From: hgn Date: Wed, 5 Apr 2023 01:29:59 +0000 (+0100) Subject: wowwww X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=72c40f1bc7a732f6a628dbf8a4135ac0bf3efa4e;p=carveJwlIkooP6JGAAIwe30JlM.git wowwww --- diff --git a/blender_export.py b/blender_export.py index dcab66f..cbd2a19 100644 --- a/blender_export.py +++ b/blender_export.py @@ -23,7 +23,8 @@ sr_entity_alias = { 'ent_route': 4, 'ent_water': 5, 'ent_volume': 6, - 'ent_audio': 7 + 'ent_audio': 7, + 'ent_marker': 8 } class mdl_vert(Structure): # 48 bytes. Quite large. Could compress @@ -282,6 +283,12 @@ class ent_audio(Structure): ("max_channels",c_uint32)] #} +class ent_marker(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("name",c_uint32)] +#} + def obj_ent_type( obj ): #{ if obj.type == 'ARMATURE': return 'mdl_armature' @@ -1097,8 +1104,6 @@ def sr_compile( collection ): #} #} - checkpoint_count = 0 - pathindice_count = 0 audio_clip_count = 0 for ent_type, arr in sr_compile.entities.items():#{ @@ -1167,76 +1172,9 @@ def sr_compile( collection ): spawn = ent_spawn() compile_obj_transform( obj, spawn.transform ) obj_data = obj.SR_data.ent_spawn[0] - spawn.pstr_name = sr_compile_string( obj_data.name ) + spawn.pstr_name = sr_compile_string( obj_data.alias ) sr_ent_push( spawn ) #} - elif ent_type == 'ent_route': #{ - obj_data = obj.SR_data.ent_route[0] - route = ent_route() - route.pstr_name = sr_compile_string( obj_data.alias ) - route.checkpoints_start = checkpoint_count - route.checkpoints_count = 0 - - for ci in range(3): - route.colour[ci] = obj_data.colour[ci] - route.colour[3] = 1.0 - - compile_obj_transform( obj, route.transform ) - - checkpoints = obj_data.gates - route_nodes = [] - - for uc in obj.users_collection[0].objects:#{ - uc_type = obj_ent_type( uc ) - if uc_type == 'ent_gate' or uc_type == 'ent_route_node': - route_nodes += [uc] - #} - graph = node_graph( route_nodes ) - - for i in range(len(checkpoints)):#{ - gi = checkpoints[i].target - gj = checkpoints[(i+1)%len(checkpoints)].target - gate = gi - - if gi:#{ - dest = gi.SR_data.ent_gate[0].target - gi = dest - #} - - if gi==gj: continue # error? - if not gi or not gj: continue - - checkpoint = ent_checkpoint() - checkpoint.gate_index = sr_compile.entity_ids[gate.name] - checkpoint.path_start = pathindice_count - checkpoint.path_count = 0 - - path = dijkstra( graph, gj.name, gi.name ) - if path:#{ - for pi in range(1,len(path)-1):#{ - pathindice = ent_path_index() - pathindice.index = sr_compile.entity_ids[path[pi]] - sr_ent_push( pathindice ) - - checkpoint.path_count += 1 - pathindice_count += 1 - #} - #} - - sr_ent_push( checkpoint ) - route.checkpoints_count += 1 - checkpoint_count += 1 - #} - - sr_ent_push( route ) - #} - elif ent_type == 'ent_route_node':#{ - rn = ent_route_node() - rn.co[0] = obj.location[0] - rn.co[1] = obj.location[2] - rn.co[2] = -obj.location[1] - sr_ent_push( rn ) - #} elif ent_type == 'ent_water':#{ water = ent_water() compile_obj_transform( obj, water.transform ) @@ -1305,9 +1243,116 @@ def sr_compile( collection ): sr_ent_push(volume) #} + elif ent_type == 'ent_marker':#{ + marker = ent_marker() + marker.name = sr_compile_string( obj.SR_data.ent_marker[0].alias ) + compile_obj_transform( obj, marker.transform ) + sr_ent_push(marker) + #} #} #} - + + def _children( col ):#{ + yield col + for c in col.children:#{ + yield from _children(c) + #} + #} + + checkpoint_count = 0 + pathindice_count = 0 + routenode_count = 0 + + for col in _children(collection):#{ + print( F"Adding routes for subcollection: {col.name}" ) + route_gates = [] + route_curves = [] + routes = [] + + for obj in col.objects:#{ + if obj.type == 'ARMATURE': pass + else:#{ + ent_type = obj_ent_type( obj ) + + if ent_type == 'ent_gate': + route_gates += [obj] + elif ent_type == 'ent_route_node':#{ + if obj.type == 'CURVE':#{ + route_curves += [obj] + #} + #} + elif ent_type == 'ent_route': + routes += [obj] + #} + #} + + dij = create_node_graph( route_curves, route_gates ) + + for obj in routes:#{ + obj_data = obj.SR_data.ent_route[0] + route = ent_route() + route.pstr_name = sr_compile_string( obj_data.alias ) + route.checkpoints_start = checkpoint_count + route.checkpoints_count = 0 + + for ci in range(3): + route.colour[ci] = obj_data.colour[ci] + route.colour[3] = 1.0 + + compile_obj_transform( obj, route.transform ) + checkpoints = obj_data.gates + + for i in range(len(checkpoints)):#{ + gi = checkpoints[i].target + gj = checkpoints[(i+1)%len(checkpoints)].target + gate = gi + + if gi:#{ + dest = gi.SR_data.ent_gate[0].target + gi = dest + #} + + if gi==gj: continue # error? + if not gi or not gj: continue + + checkpoint = ent_checkpoint() + checkpoint.gate_index = sr_compile.entity_ids[gate.name] + checkpoint.path_start = pathindice_count + checkpoint.path_count = 0 + + path = solve_graph( dij, gi.name, gj.name ) + + if path:#{ + for pi in range(len(path)):#{ + pathindice = ent_path_index() + pathindice.index = routenode_count + path[pi] + sr_ent_push( pathindice ) + + checkpoint.path_count += 1 + pathindice_count += 1 + #} + #} + + sr_ent_push( checkpoint ) + route.checkpoints_count += 1 + checkpoint_count += 1 + #} + + sr_ent_push( route ) + #} + + for point in dij.points:#{ + rn = ent_route_node() + rn.co[0] = point[0] + rn.co[1] = point[2] + rn.co[2] = -point[1] + sr_ent_push( rn ) + #} + + routenode_count += len(dij.points) + #} + + print( F"[SR] Writing file" ) file_array_instructions = {} @@ -1609,7 +1654,7 @@ class SR_INTERFACE(bpy.types.Panel): elif active_object.type == 'LIGHT': #{ _draw_prop_collection( [active_object.data.SR_data] ) #} - elif active_object.type == 'EMPTY' or active_object.type == 'MESH': #{ + elif active_object.type in ['EMPTY','CURVE','MESH']:#{ box.prop( active_object.SR_data, "ent_type" ) ent_type = active_object.SR_data.ent_type @@ -1970,6 +2015,11 @@ class SR_OBJECT_ENT_AUDIO(bpy.types.PropertyGroup): #} #} +class SR_OBJECT_ENT_MARKER(bpy.types.PropertyGroup): +#{ + alias: bpy.props.StringProperty() +#} + class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): #{ ent_gate: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GATE) @@ -1977,6 +2027,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_route: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_ROUTE) ent_volume: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_VOLUME) ent_audio: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_AUDIO) + ent_marker: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MARKER) ent_type: bpy.props.EnumProperty( name="Type", @@ -1987,7 +2038,8 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ('ent_route', 'Route', '', 4), ('ent_water', 'Water Surface', '', 5), ('ent_volume', 'Volume', '', 6 ), - ('ent_audio', 'Audio Files', '', 7)], + ('ent_audio', 'Audio Files', '', 7), + ('ent_marker', 'Marker', '', 8)], update=sr_on_type_change ) #} @@ -2143,8 +2195,7 @@ def cv_draw_sphere( pos, radius, colour ): pi = 3.14159265358979323846264 - for i in range(16): - #{ + for i in range(16):#{ t = ((i+1.0) * 1.0/16.0) * pi * 2.0 s = math.sin(t) c = math.cos(t) @@ -2178,8 +2229,7 @@ def cv_draw_halfsphere( pos, tx, ty, tz, radius, colour ): pi = 3.14159265358979323846264 - for i in range(16): - #{ + for i in range(16):#{ t = ((i+1.0) * 1.0/16.0) * pi s = math.sin(t) c = math.cos(t) @@ -2226,8 +2276,7 @@ def cv_draw_ucube( transform, colour, s=Vector((1,1,1)), o=Vector((0,0,0)) ): indices = [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),\ (0,4),(1,5),(2,6),(3,7)] - for l in indices: - #{ + for l in indices:#{ v0 = vs[l[0]] v1 = vs[l[1]] cv_view_verts += [(v0[0],v0[1],v0[2])] @@ -2263,14 +2312,12 @@ def cv_draw_line2( p0, p1, c0, c1 ): # def cv_tangent_basis( n, tx, ty ): #{ - if abs( n[0] ) >= 0.57735027: - #{ + if abs( n[0] ) >= 0.57735027:#{ tx[0] = n[1] tx[1] = -n[0] tx[2] = 0.0 #} - else: - #{ + else:#{ tx[0] = 0.0 tx[1] = n[2] tx[2] = -n[1] @@ -2300,7 +2347,7 @@ def cv_draw_arrow( p0, p1, c0, size=0.15 ): cv_view_verts += [p0,p1, midpt+(tx-n)*size,midpt, midpt+(-tx-n)*size,midpt ] cv_view_colours += [c0,c0,c0,c0,c0,c0] - cv_draw_lines() + #cv_draw_lines() #} def cv_draw_line_dotted( p0, p1, c0, dots=10 ): @@ -2317,7 +2364,7 @@ def cv_draw_line_dotted( p0, p1, c0, dots=10 ): cv_view_verts += [p2,p3] cv_view_colours += [c0,c0] #} - cv_draw_lines() + #cv_draw_lines() #} # Drawhandles of a bezier control point @@ -2342,8 +2389,7 @@ def cv_draw_bezier( p0,h0,p1,h1,c0,c1 ): global cv_view_verts, cv_view_colours last = p0 - for i in range(10): - #{ + for i in range(10):#{ t = (i+1)/10 a0 = 1-t @@ -2454,7 +2500,7 @@ def draw_cone_twist( center, vx, vy, va ): size = 0.12 cv_view_verts += [center, center+va*size] - cv_view_colours += [ (1,1,1,1), (1,1,1,1) ] + cv_view_colours += [ (1,1,1), (1,1,1) ] for x in range(32):#{ t0 = (x/32) * math.tau @@ -2472,7 +2518,7 @@ def draw_cone_twist( center, vx, vy, va ): col1 = ( abs(c1), abs(s1), 0.0, 1.0 ) cv_view_verts += [center, p0, p0, p1] - cv_view_colours += [ (0,0,0,0), col0, col0, col1 ] + cv_view_colours += [ (0,0,0), col0, col0, col1 ] #} cv_draw_lines() @@ -2517,7 +2563,7 @@ def draw_skeleton_helpers( obj ): cv_view_verts += [(v0[0],v0[1],v0[2])] cv_view_verts += [(v1[0],v1[1],v1[2])] - cv_view_colours += [(0.5,0.5,0.5,0.5),(0.5,0.5,0.5,0.5)] + cv_view_colours += [(0.5,0.5,0.5),(0.5,0.5,0.5)] #} #} elif bone.SR_data.collider == '2':#{ @@ -2545,7 +2591,7 @@ def draw_skeleton_helpers( obj ): p0 = obj.matrix_world@Vector( c + (a+b)*0.5 + v1*l*-0.5 ) p1 = obj.matrix_world@Vector( c + (a+b)*0.5 + v1*l* 0.5 ) - colour = [0.2,0.2,0.2,1.0] + colour = [0.2,0.2,0.2] colour[major_axis] = 0.5 cv_draw_halfsphere( p0, -v1, ty, tx, r, colour ) @@ -2594,15 +2640,24 @@ def cv_ent_gate( obj ): indices = [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(7,8)] + r3d = bpy.context.area.spaces.active.region_3d + + p0 = r3d.view_matrix.inverted().translation + v0 = (obj.matrix_world@Vector((0,0,0))) - p0 + v1 = obj.matrix_world.to_3x3() @ Vector((0,1,0)) + + if v0.dot(v1) > 0.0: cc = (0,1,0) + else: cc = (1,0,0) + for l in indices:#{ v0 = vs[l[0]] v1 = vs[l[1]] cv_view_verts += [(v0[0],v0[1],v0[2])] cv_view_verts += [(v1[0],v1[1],v1[2])] - cv_view_colours += [(1,1,0,1),(1,1,0,1)] + cv_view_colours += [cc,cc] #} - sw = (0.4,0.4,0.4,0.2) + sw = (0.4,0.4,0.4) if data.target != None: cv_draw_arrow( obj.location, data.target.location, sw ) #} @@ -2674,53 +2729,148 @@ def dijkstra( graph, start_node, target_node ): return path #} -def node_graph( route_nodes ): +class dij_graph(): +#{ + def __init__(_,points,graph,subsections):#{ + _.points = points + _.graph = graph + _.subsections = subsections + #} +#} + +def create_node_graph( curves, gates ): #{ + # add endpoints of curves graph = {} - for n in route_nodes: - graph[n.name] = {} + route_points = [] + subsections = [] + point_count = 0 + spline_count = 0 - for i in range(len(route_nodes)-1):#{ - for j in range(i+1, len(route_nodes)):#{ - ni = route_nodes[i] - nj = route_nodes[j] + for c in range(len(curves)):#{ + for s in range(len(curves[c].data.splines)):#{ + spline = curves[c].data.splines[s] + l = len(spline.points) + if l < 2: continue - v0 = ni.location - nj.location + dist = round(spline.calc_length(),2) - gate = None + ia = point_count + ib = point_count+l-1 - if ni.SR_data.ent_type == 'ent_gate': - gate = ni + graph[ia] = { ib: dist } + graph[ib] = { ia: dist } + + for i in range(len(spline.points)):#{ + wco = curves[c].matrix_world @ spline.points[i].co + route_points.append(Vector((wco[0],wco[1],wco[2]+0.5))) + + previous = ia+i-1 + proxima = ia+i+1 - if nj.SR_data.ent_type == 'ent_gate':#{ - if gate: continue - gate = nj + if i == 0: previous = -1 + if i == len(spline.points)-1: proxima = -1 + + subsections.append((spline_count,previous,proxima)) + point_count += 1 #} - if gate:#{ - v1 = gate.matrix_world.to_3x3() @ Vector((0,-1,0)) - if gate.SR_data.ent_gate[0].target: - if v1.dot(v0) > 0.0: continue - else: - if v1.dot(v0) < 0.0: continue + spline_count += 1 + #} + #} + + # link endpoints + graph_keys = list(graph) + for i in range(len(graph_keys)-1):#{ + for j in range(i+1, len(graph_keys)):#{ + if i%2==0 and i+1==j: continue + + ni = graph_keys[i] + nj = graph_keys[j] + pi = route_points[ni] + pj = route_points[nj] + + dist = round((pj-pi).magnitude,2) + + if dist < 10.0:#{ + graph[ni][nj] = dist + graph[nj][ni] = dist #} + #} + #} + + # add and link gates( by name ) + for gate in gates:#{ + v1 = gate.matrix_world.to_3x3() @ Vector((0,1,0)) + if gate.SR_data.ent_gate[0].target: + v1 = v1 * -1.0 + + graph[ gate.name ] = {} + + for i in range(len(graph_keys)):#{ + ni = graph_keys[i] + pi = route_points[ni] - dist = v0.magnitude + v0 = pi-gate.location + if v0.dot(v1) < 0.0: continue - if dist > 25.0: continue - graph[route_nodes[i].name][route_nodes[j].name] = dist - graph[route_nodes[j].name][route_nodes[i].name] = dist + dist = round(v0.magnitude,2) + + if dist < 10.0:#{ + graph[ gate.name ][ ni ] = dist + graph[ ni ][ gate.name ] = dist + #} #} #} - return graph + return dij_graph(route_points,graph,subsections) #} -def cv_draw_route( route, route_nodes ): +def solve_graph( dij, start, end ): +#{ + path = dijkstra( dij.graph, end, start ) + full = [] + + if path:#{ + for sj in range(1,len(path)-2):#{ + i0 = path[sj] + i1 = path[sj+1] + map0 = dij.subsections[i0] + map1 = dij.subsections[i1] + + if map0[0] == map1[0]:#{ + if map0[1] == -1: direction = 2 + else: direction = 1 + sent = 0 + + while True:#{ + map0 = dij.subsections[i0] + i1 = map0[direction] + if i1 == -1: break + + full.append( i0 ) + sent += 1 + i0 = i1 + if sent > 50: break + #} + #} + else:#{ + full.append( i0 ) + #} + #} + + full.append( path[-2] ) + #} + return full +#} + +def cv_draw_route( route, dij ): #{ pole = Vector((0.2,0.2,10)) hat = Vector((1,8,0.2)) - cc = route.SR_data.ent_route[0].colour + cc = (route.SR_data.ent_route[0].colour[0], + route.SR_data.ent_route[0].colour[1], + route.SR_data.ent_route[0].colour[2]) cv_draw_ucube(route.matrix_world,cc,Vector((0.5,-7.5,6)),\ Vector((0,-6.5,5.5))) @@ -2730,7 +2880,6 @@ def cv_draw_route( route, route_nodes ): cv_draw_ucube(route.matrix_world,cc,hat, Vector((-0.5,-6.5,-1)) ) checkpoints = route.SR_data.ent_route[0].gates - graph = node_graph( route_nodes ) for i in range(len(checkpoints)):#{ gi = checkpoints[i].target @@ -2746,13 +2895,17 @@ def cv_draw_route( route, route_nodes ): if gi==gj: continue # error? if not gi or not gj: continue - path = dijkstra( graph, gj.name, gi.name ) + path = solve_graph( dij, gi.name, gj.name ) if path:#{ - for sj in range(len(path)-1):#{ - o0 = bpy.data.objects[ path[sj] ] - o1 = bpy.data.objects[ path[sj+1] ] - cv_draw_arrow(o0.location,o1.location,cc,1.5) + cv_draw_arrow(gi.location,dij.points[path[0]],cc,1.5) + cv_draw_arrow(dij.points[path[len(path)-1]],gj.location,cc,1.5) + for j in range(len(path)-1):#{ + i0 = path[j] + i1 = path[j+1] + o0 = dij.points[ i0 ] + o1 = dij.points[ i1 ] + cv_draw_arrow(o0,o1,cc,1.5) #} #} else:#{ @@ -2779,7 +2932,8 @@ def cv_draw(): gpu.state.depth_test_set('LESS') gpu.state.blend_set('NONE') - route_nodes = [] + route_gates = [] + route_curves = [] routes = [] for obj in bpy.context.collection.objects:#{ @@ -2792,10 +2946,13 @@ def cv_draw(): if ent_type == 'ent_gate':#{ cv_ent_gate( obj ) - route_nodes += [obj] + route_gates += [obj] + #} + elif ent_type == 'ent_route_node':#{ + if obj.type == 'CURVE':#{ + route_curves += [obj] + #} #} - elif ent_type == 'ent_route_node': - route_nodes += [obj] elif ent_type == 'ent_route': routes += [obj] elif ent_type == 'ent_volume':#{ @@ -2807,10 +2964,12 @@ def cv_draw(): #} #} #} + + dij = create_node_graph( route_curves, route_gates ) #cv_draw_route_map( route_nodes ) for route in routes:#{ - cv_draw_route( route, route_nodes ) + cv_draw_route( route, dij ) #} cv_draw_lines() @@ -2828,7 +2987,7 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ SR_OBJECT_ENT_VOLUME, SR_UL_AUDIO_LIST, SR_OBJECT_ENT_AUDIO_FILE_ENTRY,\ SR_OT_ROUTE_LIST_DEL_ITEM,\ - SR_OBJECT_ENT_AUDIO,\ + SR_OBJECT_ENT_AUDIO,SR_OBJECT_ENT_MARKER,\ \ SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \ diff --git a/build.c b/build.c index 1201177..f791927 100644 --- a/build.c +++ b/build.c @@ -139,9 +139,4 @@ void build_shaders(void) _S( "blitblur", "blit.vs", "blitblur.fs" ); _S( "blitcolour","blit.vs", "colour.fs" ); _S( "routeui", "routeui.vs", "routeui.fs" ); - -#if 0 - // 3D Standard - _S( "scoretext", "shaders/scoretext.vs", "shaders/vblend.fs" ); -#endif } diff --git a/conf.h b/conf.h index ade9247..33cc44e 100644 --- a/conf.h +++ b/conf.h @@ -7,7 +7,8 @@ VG_STATIC float cl_fov = 0.86f, cl_blur_strength = 0.3f; VG_STATIC int cl_blur = 1, - cl_playermdl_id = 0; + cl_playermdl_id = 0, + cl_invert_y = 0; VG_STATIC void g_conf_init(void) { @@ -19,6 +20,14 @@ VG_STATIC void g_conf_init(void) .persistent = 1 }); + vg_var_push( (struct vg_var){ + .name = "cl_invert_y", + .data = &cl_invert_y, + .data_type = k_var_dtype_i32, + .opt_i32 = { .min=0, .max=1, .clamp=1 }, + .persistent = 1 + }); + vg_var_push( (struct vg_var){ .name = "cl_blur_strength", .data = &cl_blur_strength, diff --git a/entity.h b/entity.h index 5b0d4a7..e437d3d 100644 --- a/entity.h +++ b/entity.h @@ -17,6 +17,7 @@ typedef struct volume_trigger volume_trigger; typedef struct ent_volume ent_volume; typedef struct ent_audio ent_audio; typedef struct ent_index ent_index; +typedef struct ent_marker ent_marker; enum entity_alias{ k_ent_gate = 1, @@ -25,7 +26,8 @@ enum entity_alias{ k_ent_route = 4, k_ent_water = 5, k_ent_volume = 6, - k_ent_audio = 7 + k_ent_audio = 7, + k_ent_marker = 8 }; struct ent_index{ @@ -182,6 +184,11 @@ struct ent_audio{ max_channels; }; +struct ent_marker{ + mdl_transform transform; + u32 pstr_alias; +}; + enum channel_behaviour{ k_channel_behaviour_unlimited = 0, k_channel_behaviour_discard_if_full = 1, @@ -194,4 +201,18 @@ enum probability_curve{ k_probability_curve_wildlife_night = 2 }; +VG_STATIC ent_marker *ent_find_marker( mdl_context *mdl, + mdl_array_ptr *arr, const char *alias ) +{ + for( u32 i=0; ipstr_alias ), alias ) ){ + return marker; + } + } + + return NULL; +} + #endif /* ENTITY_H */ diff --git a/maps_src/mp_mtzero.mdl b/maps_src/mp_mtzero.mdl index e691978..1b58c56 100644 Binary files a/maps_src/mp_mtzero.mdl and b/maps_src/mp_mtzero.mdl differ diff --git a/menu.h b/menu.h index 4f65644..bcd6141 100644 --- a/menu.h +++ b/menu.h @@ -5,18 +5,23 @@ #include "model.h" #include "world_render.h" #include "player.h" +#include "conf.h" -#include "shaders/menu.h" +#include "shaders/model_menu.h" #include "vg_steam_friends.h" #include "submodules/tinydir/tinydir.h" VG_STATIC mdl_context menu_model; +VG_STATIC mdl_array_ptr menu_markers; VG_STATIC glmesh menu_glmesh; VG_STATIC m4x3f menu_mdl_mtx; VG_STATIC float menu_opacity = 0.0f; VG_STATIC float menu_input_cooldown = 0.0f; -VG_STATIC float menu_fov_target = 97.0f; +VG_STATIC float menu_fov_target = 97.0f, + menu_smooth_fov = 97.0f; VG_STATIC v2f menu_extra_angles; +VG_STATIC v3f menu_camera_pos; +VG_STATIC v2f menu_camera_angles; VG_STATIC int cl_menu = 0, cl_menu_go_away = 0; @@ -41,23 +46,24 @@ VG_STATIC void menu_btn_fuckoff( int event ); VG_STATIC void menu_btn_reset( int event ); VG_STATIC void menu_btn_map( int event ); VG_STATIC void menu_btn_settings( int event ); +VG_STATIC void menu_btn_invert_y( int event ); -VG_STATIC mdl_node *menu_pnode_fov_slider, - *menu_pnode_fov_min, - *menu_pnode_fov_max, - *menu_pnode_vol_slider, - *menu_pnode_vol_min, - *menu_pnode_vol_max; +VG_STATIC mdl_mesh *menu_mesh_fov_slider, + *menu_mesh_vol_slider; -struct -{ +VG_STATIC ent_marker + *menu_mark_fov_min, + *menu_mark_fov_max, + *menu_mark_vol_min, + *menu_mark_vol_max; + +struct{ /* state */ int loc; u32 page; /* map browser */ - struct menu_map_file - { + struct menu_map_file{ char name[ 64 ]; } maps_list[ 16 ]; @@ -67,8 +73,7 @@ struct } VG_STATIC game_menu; -enum menu_page -{ +enum menu_page{ k_menu_page_main = 0x1, k_menu_page_skater = 0x2, k_menu_page_quit = 0x4, @@ -76,16 +81,14 @@ enum menu_page k_menu_page_map = 0x10 }; -struct menu_btn_userdata -{ +struct menu_btn_userdata{ int i; void *ptr_generic; }; VG_STATIC int menu_settings_if( struct menu_btn_userdata ud ) { - if( game_menu.page & k_menu_page_settings ) - { + if( game_menu.page & k_menu_page_settings ){ int *ptr = ud.ptr_generic; return *ptr; } @@ -131,7 +134,7 @@ struct menu_button *lr, *ld; - mdl_node *pnode; + mdl_mesh *mesh; float falpha, fsize; } VG_STATIC menu_buttons[] = @@ -139,7 +142,7 @@ VG_STATIC menu_buttons[] = { "text_quit", menu_vis, {.i=k_menu_page_main|k_menu_page_quit}, .fn_press = menu_btn_quit, - .ld="text_reset", .lr="text_settings", .ll="text_map" + .ld="text_reset", .lr="text_settings", /*.ll="text_map"*/ }, { "text_quitty", menu_vis, {.i=k_menu_page_quit} @@ -151,18 +154,20 @@ VG_STATIC menu_buttons[] = { "text_reset", menu_vis, {.i=k_menu_page_main}, .fn_press = menu_btn_reset, - .lu="text_quit", .ld="text_skater", .ll="text_map", .lr="text_settings" + .lu="text_quit", .ld="text_skater", /*.ll="text_map",*/ .lr="text_settings" }, { "text_skater", menu_vis, {.i=k_menu_page_main|k_menu_page_skater}, .fn_press = menu_btn_skater, - .lu="text_reset", .ll="text_map", .lr="text_settings" + .lu="text_reset", /*.ll="text_map",*/ .lr="text_settings" }, +/* { "text_map", menu_vis, {.i=k_menu_page_main}, .fn_press = menu_btn_map, .lr="text_reset" }, +*/ { "text_settings", menu_vis, {.i=k_menu_page_main|k_menu_page_settings}, .fn_press = menu_btn_settings, @@ -177,7 +182,7 @@ VG_STATIC menu_buttons[] = { "fov_slider", menu_vis, {k_menu_page_settings}, - .ld="text_blur" + .ld="text_invert_y" }, { "fov_info", menu_vis, {k_menu_page_settings} }, @@ -187,10 +192,18 @@ VG_STATIC menu_buttons[] = }, { "vol_info", menu_vis, {k_menu_page_settings} }, +{ + "text_invert_y", menu_vis, {k_menu_page_settings}, + .fn_press = menu_btn_invert_y, + .lu = "fov_slider", .ld="text_blur" +}, +{ + "text_invert_y_check", menu_settings_if, {.ptr_generic=&cl_invert_y} +}, { "text_blur", menu_vis, {k_menu_page_settings}, .fn_press = menu_btn_blur, - .lu="fov_slider", .ld="vol_slider" + .lu="text_invert_y", .ld="vol_slider" }, { "text_blur_check", menu_settings_if, {.ptr_generic=&cl_blur} @@ -221,11 +234,10 @@ VG_STATIC int menu_get_loc( const char *loc ) return 0; } +VG_STATIC int __respawn( int argc, const char *argv[] ); VG_STATIC void menu_btn_reset( int event ) { - reset_player(0,NULL); - world_routes_clear(); - + __respawn(0,NULL); cl_menu_go_away = 1; game_menu.page = 0; } @@ -257,6 +269,11 @@ VG_STATIC void menu_btn_blur( int event ) cl_blur ^= 0x1; } +VG_STATIC void menu_btn_invert_y( int event ) +{ + cl_invert_y ^= 0x1; +} + VG_STATIC void menu_btn_map( int event ) { game_menu.page = k_menu_page_map; @@ -266,13 +283,11 @@ VG_STATIC void menu_btn_map( int event ) tinydir_dir dir; tinydir_open( &dir, "maps" ); - while( dir.has_next ) - { + while( dir.has_next ){ tinydir_file file; tinydir_readfile( &dir, &file ); - if( file.is_reg ) - { + if( file.is_reg ){ struct menu_map_file *mf = &game_menu.maps_list[ game_menu.map_count ]; vg_strncpy( file.name, mf->name, @@ -291,8 +306,7 @@ VG_STATIC void menu_btn_map( int event ) VG_STATIC void menu_crap_ui(void) { - if( cl_menu && (game_menu.page == k_menu_page_map) ) - { + if( cl_menu && (game_menu.page == k_menu_page_map) ){ ui_rect box; box[0] = vg.window_x/2 - 150; box[1] = vg.window_y/2 - 300; @@ -301,18 +315,15 @@ VG_STATIC void menu_crap_ui(void) ui_fill_rect( box, 0xa0000000 ); - if( game_menu.map_count == 0 ) - { + if( game_menu.map_count == 0 ){ ui_text( (ui_rect){ vg.window_x/2, box[1]+8, 0,0 }, "No maps found", 1, k_text_align_center ); } - else - { + else{ ui_rect_pad( box, 4 ); box[3] = 16; - for( int i=0; im_pubParam; vg_info( "Steam game overlay activated; pausing\n" ); - if( inf->m_bActive ) - { + if( inf->m_bActive ){ cl_menu = 1; game_menu.page = k_menu_page_main; game_menu.loc = menu_get_loc( "text_skater" ); @@ -362,10 +372,11 @@ VG_STATIC void menu_init(void) vg_linear_clear( vg_mem.scratch ); - mdl_open( &menu_model, "models/rs_menu.mdl" ); - mdl_load_metadata( &menu_model, vg_mem.rtmemory ); - mdl_load_mesh_data( &menu_model, vg_mem.scratch ); - mdl_invert_uv_coordinates( &menu_model ); + mdl_open( &menu_model, "models/rs_menu.mdl", vg_mem.rtmemory ); + mdl_load_metadata_block( &menu_model, vg_mem.rtmemory ); + mdl_load_mesh_block( &menu_model, vg_mem.scratch ); + mdl_load_array( &menu_model, &menu_markers, "ent_marker", vg_mem.rtmemory ); + //mdl_invert_uv_coordinates( &menu_model ); mdl_close( &menu_model ); vg_acquire_thread_sync(); @@ -375,26 +386,29 @@ VG_STATIC void menu_init(void) } vg_release_thread_sync(); - for( int i=0; ipnode = mdl_node_from_name( &menu_model, btn->name ); + btn->mesh = mdl_find_mesh( &menu_model, btn->name ); - if( !btn->pnode ) - { + if( !btn->mesh ){ vg_info( "info: %s\n", btn->name ); vg_fatal_exit_loop( "Menu programming error" ); } } - menu_pnode_fov_max = mdl_node_from_name( &menu_model, "fov_slider_max" ); - menu_pnode_fov_min = mdl_node_from_name( &menu_model, "fov_slider_min" ); - menu_pnode_fov_slider = mdl_node_from_name( &menu_model, "fov_slider" ); - menu_pnode_vol_max = mdl_node_from_name( &menu_model, "vol_slider_max" ); - menu_pnode_vol_min = mdl_node_from_name( &menu_model, "vol_slider_min" ); - menu_pnode_vol_slider = mdl_node_from_name( &menu_model, "vol_slider" ); + menu_mark_fov_max = + ent_find_marker( &menu_model, &menu_markers, "fov_slider_max" ); + menu_mark_fov_min = + ent_find_marker( &menu_model, &menu_markers, "fov_slider_min" ); + menu_mark_vol_max = + ent_find_marker( &menu_model, &menu_markers, "vol_slider_max" ); + menu_mark_vol_min = + ent_find_marker( &menu_model, &menu_markers, "vol_slider_min" ); + + menu_mesh_fov_slider = mdl_find_mesh( &menu_model, "fov_slider" ); + menu_mesh_vol_slider = mdl_find_mesh( &menu_model, "vol_slider" ); - shader_menu_register(); + shader_model_menu_register(); #ifdef SR_NETWORKED steam_register_callback( k_iGameOverlayActivated, steam_on_game_overlay ); @@ -405,12 +419,10 @@ VG_STATIC void menu_run_directional(void) { struct menu_button *btn = &menu_buttons[ game_menu.loc ]; - if( vg_input_button_down( &input_menu_press ) ) - { - if( btn->fn_press ) - { + if( vg_input_button_down( &input_menu_press ) ){ + if( btn->fn_press ){ audio_lock(); - audio_play_oneshot( &audio_ui[0], 1.0f ); + audio_oneshot( &audio_ui[0], 1.0f, 0.0f ); audio_unlock(); btn->fn_press( 1 ); @@ -418,28 +430,23 @@ VG_STATIC void menu_run_directional(void) } } - if( menu_input_cooldown <= 0.0f ) - { + if( menu_input_cooldown <= 0.0f ){ v2f dir = { input_menu_h.axis.value, -input_menu_v.axis.value }; - if( v2_length2( dir ) > 0.8f*0.8f ) - { + if( v2_length2( dir ) > 0.8f*0.8f ){ const char *link = NULL; - if( fabsf(dir[0]) > fabsf(dir[1]) ) - { + if( fabsf(dir[0]) > fabsf(dir[1]) ){ if( dir[0] > 0.0f ) link = btn->lr; else link = btn->ll; } - else - { + else{ if( dir[1] > 0.0f ) link = btn->ld; else link = btn->lu; } - if( link ) - { + if( link ){ game_menu.loc = menu_get_loc( link ); menu_input_cooldown = 0.25f; } @@ -473,23 +480,19 @@ VG_STATIC void menu_page_main(void) VG_STATIC void menu_page_map(void) { - if( menu_page_should_backout() ) - { + if( menu_page_should_backout() ){ game_menu.page = k_menu_page_main; game_menu.loc = menu_get_loc( "text_map" ); } - if( game_menu.map_count > 0 ) - { + if( game_menu.map_count > 0 ){ float v = input_menu_v.axis.value; - if( (fabsf(v) > 0.7f) && (menu_input_cooldown <= 0.0f) ) - { + if( (fabsf(v) > 0.7f) && (menu_input_cooldown <= 0.0f) ){ audio_lock(); - audio_play_oneshot( &audio_rewind[4], 1.0f ); + audio_oneshot( &audio_rewind[4], 1.0f, 0.0f ); audio_unlock(); - if( v > 0.0f ) - { + if( v > 0.0f ){ game_menu.selected_map --; if( game_menu.selected_map < 0 ) @@ -497,8 +500,7 @@ VG_STATIC void menu_page_map(void) menu_input_cooldown = 0.25f; } - else - { + else{ game_menu.selected_map ++; if( game_menu.selected_map >= game_menu.map_count ) @@ -508,8 +510,8 @@ VG_STATIC void menu_page_map(void) } } - if( vg_input_button_down( &input_menu_press ) ) - { + if( vg_input_button_down( &input_menu_press ) ){ +#if 0 /* load map */ char temp[256]; strcpy( temp, "maps/" ); @@ -517,6 +519,7 @@ VG_STATIC void menu_page_map(void) world_change_world( 1, (const char *[]){ temp } ); menu_close(); +#endif } } @@ -525,8 +528,7 @@ VG_STATIC void menu_page_map(void) VG_STATIC void menu_page_quit(void) { - if( menu_page_should_backout() ) - { + if( menu_page_should_backout() ){ game_menu.page = k_menu_page_main; game_menu.loc = menu_get_loc( "text_quit" ); } @@ -535,26 +537,26 @@ VG_STATIC void menu_page_quit(void) menu_run_directional(); } +void temp_update_playermodel(void); VG_STATIC void menu_page_skater(void) { float h = input_menu_h.axis.value; menu_fov_target = 97.0f; - if( menu_page_should_backout() ) - { + if( menu_page_should_backout() ){ game_menu.page = k_menu_page_main; game_menu.loc = menu_get_loc( "text_skater" ); return; } - if( (fabsf(h) > 0.7f) && (menu_input_cooldown <= 0.0f) ) - { + if( (fabsf(h) > 0.7f) && (menu_input_cooldown <= 0.0f) ){ audio_lock(); - audio_play_oneshot( &audio_rewind[4], 1.0f ); + audio_oneshot( &audio_rewind[4], 1.0f, 0.0f ); audio_unlock(); - if( h < 0.0f ) - { + vg_info( "%f\n", h ); + + if( h < 0.0f ){ cl_playermdl_id --; if( cl_playermdl_id < 0 ) cl_playermdl_id = 2; @@ -566,34 +568,34 @@ VG_STATIC void menu_page_skater(void) menu_input_cooldown = 0.25f; } - else - { + else{ cl_playermdl_id ++; if( cl_playermdl_id > 2 ) cl_playermdl_id = 0; - int ri = menu_get_loc( "skater_left" ); + int ri = menu_get_loc( "skater_right" ); menu_buttons[ri].fsize = 0.4f; menu_buttons[ri].falpha = 1.0f; menu_input_cooldown = 0.25f; } + + temp_update_playermodel(); } } VG_STATIC void menu_slider( float *value, int set_value, - mdl_node *slider, mdl_node *pmin, mdl_node *pmax ) + mdl_mesh *slider, v3f co_min, v3f co_max ) { - if( set_value ) - { + if( set_value ){ float h = input_menu_h.axis.value; if( fabsf(h) > 0.04f ) *value += h * vg.frame_delta; *value = vg_clampf( *value, 0.0f, 1.0f ); } - v3_lerp( pmin->co, pmax->co, *value, slider->co ); + v3_lerp( co_min, co_max, *value, slider->transform.co ); } VG_STATIC void menu_page_settings(void) @@ -602,25 +604,26 @@ VG_STATIC void menu_page_settings(void) int fov_select = game_menu.loc == menu_get_loc( "fov_slider" ); menu_slider( &cl_fov, fov_select, - menu_pnode_fov_slider, menu_pnode_fov_min, - menu_pnode_fov_max ); + menu_mesh_fov_slider, menu_mark_fov_min->transform.co, + menu_mark_fov_max->transform.co ); if( fov_select ) menu_fov_target = vg_lerpf( 97.0f, 135.0f, cl_fov ) * 0.8f; - menu_slider( &vg_audio.volume_console, + menu_slider( &vg_audio.external_global_volume, (game_menu.loc == menu_get_loc( "vol_slider" )), - menu_pnode_vol_slider, menu_pnode_vol_min, - menu_pnode_vol_max ); + menu_mesh_vol_slider, menu_mark_vol_min->transform.co, + menu_mark_vol_max->transform.co ); - if( menu_page_should_backout() ) - { + if( menu_page_should_backout() ){ game_menu.page = k_menu_page_main; game_menu.loc = menu_get_loc( "text_settings" ); return; } } +player_instance *tmp_localplayer(void); + VG_STATIC void menu_update(void) { vg_input_update( 1, &input_menu_h ); @@ -634,17 +637,13 @@ VG_STATIC void menu_update(void) toggle_kb = vg_input_button_down( &input_menu_toggle_kbm ), wait_for_a_sec = 0; - if( toggle_gp || toggle_kb ) - { - if( cl_menu ) - { - if( toggle_gp ) - { + if( toggle_gp || toggle_kb ){ + if( cl_menu ){ + if( toggle_gp ){ menu_close(); } } - else - { + else{ if( toggle_kb ) wait_for_a_sec = 1; @@ -653,8 +652,7 @@ VG_STATIC void menu_update(void) } } - if( !wait_for_a_sec && cl_menu ) - { + if( !wait_for_a_sec && cl_menu ){ if( game_menu.page == k_menu_page_main ) menu_page_main(); else if( game_menu.page == k_menu_page_skater ) @@ -669,48 +667,59 @@ VG_STATIC void menu_update(void) struct menu_button *btn = &menu_buttons[ game_menu.loc ]; - v3f pos; - v2f angles; - /* Base */ { - v3f lookdir; - v3f *mtx = player.mdl.sk.final_mtx[player.mdl.id_head]; - m3x3_mulv( mtx, (v3f){-1.0f,0.0f,0.0f}, lookdir ); - - lookdir[1] = 0.0f; - v3_normalize( lookdir ); - + player_instance *player = tmp_localplayer(); + struct player_avatar *av = player->playeravatar; + v3f center_rough; + if( player->subsystem == k_player_subsystem_dead ){ + m4x3_mulv( av->sk.final_mtx[av->id_hip], (v3f){0.0f,0.9f,0.0f}, + center_rough ); + } + else{ + m4x3_mulv( av->sk.final_mtx[av->id_head], (v3f){0.0f,1.5f,0.0f}, + center_rough ); + } - if( player.is_dead ) - { - v3_copy(player.mdl.ragdoll[ player.mdl.id_hip-1 ].rb.co, center_rough); + v3f cam_offset; + float cam_rot; + if( player->subsystem == k_player_subsystem_walk ){ + v3_muls( player->rb.to_world[2], 1.0f, cam_offset ); + cam_rot = 0.0f; } - else - { - v3_add( player.camera_pos, player.visual_transform[3], center_rough ); - v3_muls( center_rough, 0.5f, center_rough ); + else{ + v3_muls( player->rb.to_world[0], -1.0f, cam_offset ); + cam_rot = -VG_PIf*0.5f; } - v3_muladds( center_rough, lookdir, 1.5f, pos ); - v3_add( (v3f){ 0.0f,0.8f,0.0f}, pos, pos ); - angles[1] = 0.0f; - angles[0] = -atan2f( lookdir[0], lookdir[2] ); + v3f lookdir; + m3x3_mulv( player->invbasis, cam_offset, lookdir ); + lookdir[1] = 0.0f; + v3_normalize( lookdir ); + + m3x3_mulv( player->basis, lookdir, cam_offset ); + v3_muladds( center_rough, cam_offset, 2.0f, menu_camera_pos ); + + menu_camera_angles[1] = 0.0f; + menu_camera_angles[0] = -atan2f( lookdir[0], lookdir[2] ); /* setup model matrix */ v4f qmenu_mdl; - q_axis_angle( qmenu_mdl, (v3f){0.0f,1.0f,0.0f}, -angles[0] ); - + q_axis_angle( qmenu_mdl, (v3f){0.0f,1.0f,0.0f}, -menu_camera_angles[0] ); q_m3x3( qmenu_mdl, menu_mdl_mtx ); - v3_copy( center_rough, menu_mdl_mtx[3] ); + v3_add( center_rough, (v3f){0.0f,-0.5f,0.0f}, menu_mdl_mtx[3] ); + m3x3_mul( player->basis, menu_mdl_mtx, menu_mdl_mtx ); + + menu_smooth_fov = vg_lerpf( menu_smooth_fov, menu_fov_target, + vg.frame_delta * 8.2f ); } /* Extra */ { v3f delta; - v3_sub( btn->pnode->co, (v3f){ 0.0f,1.5f,-1.5f }, delta ); + v3_sub( btn->mesh->transform.co, (v3f){ 0.0f,1.5f,-1.5f }, delta ); v3_normalize( delta ); float y = atan2f( delta[0], delta[2] ), @@ -720,36 +729,22 @@ VG_STATIC void menu_update(void) menu_extra_angles[0] = vg_lerpf( menu_extra_angles[0], y, dt ); menu_extra_angles[1] = vg_lerpf( menu_extra_angles[1], p, dt ); - v2_muladds( angles, menu_extra_angles, 0.8f, angles ); - angles[0] = fmodf( angles[0], VG_TAUf ); - } - - /* Update camera */ -#if 0 - { - main_camera.angles[0] = - vg_alerpf( main_camera.angles[0], angles[0], menu_opacity ); - main_camera.angles[1] = - vg_lerpf ( main_camera.angles[1], angles[1], menu_opacity ); - v3_lerp( main_camera.pos, pos, menu_opacity, main_camera.pos ); - - camera_update_transform( &main_camera ); + v2_muladds( menu_camera_angles, menu_extra_angles, 0.8f, + menu_camera_angles ); + menu_camera_angles[0] = fmodf( menu_camera_angles[0], VG_TAUf ); } -#endif float dt = vg.frame_delta * 6.0f; menu_opacity = vg_lerpf( menu_opacity, cl_menu&&!cl_menu_go_away, dt ); - if( menu_opacity <= 0.01f ) - { + if( menu_opacity <= 0.01f ){ cl_menu = 0; cl_menu_go_away = 0; } vg.time_rate = 1.0-(double)menu_opacity; - if( cl_menu ) - { + if( cl_menu ){ menu_input_cooldown -= vg.frame_delta; } } @@ -761,7 +756,7 @@ float expSustainedImpulse( float x, float f, float k ) return fminf( x*x/(f*f), 1.0f+(2.0f/f)*s*expf(-k*s)); } -VG_STATIC void menu_render( camera *cam ) +VG_STATIC void menu_render_bg(void) { glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); @@ -771,23 +766,25 @@ VG_STATIC void menu_render( camera *cam ) shader_blitcolour_use(); shader_blitcolour_uColour( (v4f){ 0.1f, 0.1f, 0.3f, menu_opacity*0.5f } ); render_fsquad(); +} +VG_STATIC void menu_render_fg( camera *cam ) +{ glEnable( GL_DEPTH_TEST ); glDisable( GL_BLEND ); m4x3f mtx; - shader_menu_use(); - shader_menu_uColour( (v4f){ 1.0f,1.0f,1.0f,1.0f} ); - shader_menu_uTexMain( 1 ); + shader_model_menu_use(); + shader_model_menu_uColour( (v4f){ 1.0f,1.0f,1.0f,1.0f} ); + shader_model_menu_uTexMain( 1 ); vg_tex2d_bind( &tex_menu, 1 ); - shader_menu_uPv( cam->mtx.pv ); - shader_menu_uPvmPrev( cam->mtx_prev.pv ); + shader_model_menu_uPv( cam->mtx.pv ); + shader_model_menu_uPvmPrev( cam->mtx_prev.pv ); mesh_bind( &menu_glmesh ); - for( int i=0; ifn_visibility( btn->user )? 1.0f: 0.0f, @@ -795,7 +792,7 @@ VG_STATIC void menu_render( camera *cam ) tsize = tsize0+tsize1; btn->falpha = vg_lerpf( btn->falpha, talpha, vg.frame_delta * 14.0f ); - btn->fsize = vg_lerpf( btn->fsize, tsize, vg.frame_delta * 3.0f ); + btn->fsize = vg_lerpf( btn->fsize, tsize, vg.frame_delta * 7.0f ); /* Colour */ v4f vselected = {0.95f*1.3f,0.45f*1.3f,0.095f*1.3f, 1.0f}, @@ -803,21 +800,20 @@ VG_STATIC void menu_render( camera *cam ) vcurrent; v4_lerp( vnormal, vselected, btn->falpha, vcurrent ); - shader_menu_uColour( vcurrent ); + shader_model_menu_uColour( vcurrent ); /* Create matrix */ m4x3f mtx_size; - mdl_node_transform( btn->pnode, mtx ); + mdl_transform_m4x3( &btn->mesh->transform, mtx ); m4x3_mul( menu_mdl_mtx, mtx, mtx ); m4x3_identity( mtx_size ); m4x3_scale( mtx_size, expSustainedImpulse( btn->fsize, 0.5f, 8.7f) ); m4x3_mul( mtx, mtx_size, mtx ); - shader_menu_uMdl( mtx ); + shader_model_menu_uMdl( mtx ); - for( int j=0; jpnode->submesh_count; j++ ) - { + for( int j=0; jmesh->submesh_count; j++ ){ mdl_submesh *sm = - &menu_model.submesh_buffer[ btn->pnode->submesh_start+j ]; + mdl_arritm( &menu_model.submeshs, btn->mesh->submesh_start+j ); mdl_draw_submesh( sm ); } } diff --git a/models_src/ch_jordan.mdl b/models_src/ch_jordan.mdl index 7fe4aa1..c1ac5b3 100644 Binary files a/models_src/ch_jordan.mdl and b/models_src/ch_jordan.mdl differ diff --git a/models_src/ch_outlaw.mdl b/models_src/ch_outlaw.mdl index 7035591..80e52ab 100644 Binary files a/models_src/ch_outlaw.mdl and b/models_src/ch_outlaw.mdl differ diff --git a/models_src/rs_menu.mdl b/models_src/rs_menu.mdl new file mode 100644 index 0000000..2bcc670 Binary files /dev/null and b/models_src/rs_menu.mdl differ diff --git a/player.c b/player.c index 483df66..8d6429f 100644 --- a/player.c +++ b/player.c @@ -88,7 +88,8 @@ void player__create( player_instance *inst ) "bind use gp-y", "bind use e", - "bind camera c" + "bind camera c", + "bind camera gp-rb" }; for( int i=0; isubsystem == k_player_subsystem_dead ){ - player->subsystem = k_player_subsystem_walk; - //reset_player( 0, NULL ); + __respawn( 0, NULL ); } else{ /* cant do that */ @@ -321,6 +321,8 @@ void player__pass_gate( player_instance *player, ent_gate *gate ) if( gate->type == k_gate_type_nonlocal ) world_global.active_world = gate->target; + world_global.in_volume = 0; + audio_lock(); audio_oneshot( &audio_gate_pass, 1.0f, 0.0f ); audio_unlock(); @@ -375,6 +377,7 @@ VG_STATIC void player__pre_render( player_instance *player ) player->rewind_total_length = 0.0f; player->rewind_accum = 0.0f; world_global.sky_target_rate = 1.0; + world_global.last_use = world_global.time; } else{ world_global.sky_target_rate = -100.0; @@ -526,6 +529,7 @@ PLAYER_API void player__spawn( player_instance *player, player->subsystem = k_player_subsystem_walk; player->viewable_world = get_active_world(); + player->gate_waiting = NULL; if( _player_reset[ player->subsystem ] ) _player_reset[ player->subsystem ]( player, rp ); diff --git a/player.h b/player.h index cd7fd57..53016cd 100644 --- a/player.h +++ b/player.h @@ -28,8 +28,8 @@ struct player_instance enum camera_mode { - k_cam_firstperson = 0, - k_cam_thirdperson = 1 + k_cam_firstperson = 1, + k_cam_thirdperson = 0 } camera_mode; float camera_type_blend; diff --git a/player_common.c b/player_common.c index 259a798..432fbae 100644 --- a/player_common.c +++ b/player_common.c @@ -2,6 +2,7 @@ #define PLAYER_COMMON_C #include "player.h" +#include "conf.h" VG_STATIC void player_vector_angles( v3f angles, v3f v, float C, float k ) { @@ -115,8 +116,10 @@ VG_STATIC void player__cam_iterate( player_instance *player ) vg.frame_delta * 8.0f, player->tpv_offset_smooth ); /* fov -- simple blend */ - /* FIXME: cl_fov */ - player->cam.fov = vg_lerpf( 97.0f, 128.0f, player->camera_type_blend ); + float fov_skate = vg_lerpf( 97.0f, 135.0f, cl_fov ), + fov_walk = vg_lerpf( 90.0f, 110.0f, cl_fov ); + + player->cam.fov = vg_lerpf( fov_walk, fov_skate, player->camera_type_blend ); /* * first person camera @@ -226,7 +229,12 @@ VG_STATIC void player__cam_iterate( player_instance *player ) VG_STATIC void player_look( player_instance *player, v3f angles ) { angles[2] = 0.0f; - v2_muladds( angles, vg.mouse_delta, 0.0025f, angles ); + + v2f mouse_input; + v2_copy( vg.mouse_delta, mouse_input ); + if( cl_invert_y ) + mouse_input[1] *= -1.0f; + v2_muladds( angles, mouse_input, 0.0025f, angles ); if( vg_input.controller_should_use_trackpad_look ){ static v2f last_input; @@ -236,6 +244,9 @@ VG_STATIC void player_look( player_instance *player, v3f angles ) v2f input = { player->input_js2h->axis.value, player->input_js2v->axis.value }; + if( cl_invert_y ) + input[1] *= -1.0f; + if( (v2_length2(last_input) > 0.001f) && (v2_length2(input) > 0.001f) ){ v2_sub( input, last_input, vel ); v2_muls( vel, 1.0f/vg.time_delta, vel ); @@ -251,7 +262,12 @@ VG_STATIC void player_look( player_instance *player, v3f angles ) } else{ angles[0] += player->input_js2h->axis.value * vg.time_delta * 4.0f; - angles[1] += player->input_js2v->axis.value * vg.time_delta * 4.0f; + + float input_y = player->input_js2v->axis.value * vg.time_delta * 4.0f; + if( cl_invert_y ) + input_y *= -1.0f; + + angles[1] += input_y; } angles[1] = vg_clampf( angles[1], -VG_PIf*0.5f, VG_PIf*0.5f ); diff --git a/player_skate.c b/player_skate.c index bec5453..bd83545 100644 --- a/player_skate.c +++ b/player_skate.c @@ -4,6 +4,7 @@ #include "player.h" #include "audio.h" #include "vg/vg_perlin.h" +#include "menu.h" VG_STATIC void player__skate_bind( player_instance *player ) { @@ -127,10 +128,8 @@ VG_STATIC int skate_grind_scansq( player_instance *player, v3f tri[3]; struct world_surface *surf = world_tri_index_surface(world,ptri[0]); -#if 0 if( !(surf->info.flags & k_material_flag_skate_surface) ) continue; -#endif for( int j=0; j<3; j++ ) v3_copy( world->scene_geo->arrvertices[ptri[j]].co, tri[j] ); @@ -579,8 +578,6 @@ void player__approximate_best_trajectory( player_instance *player ) v3_add( launch_co, co0, co0 ); /* rough scan to make sure we dont collide with anything */ - /* NOTE this was rarely needed and ends up with false negatives. */ -#if 0 for( int j=1; j<=16; j++ ){ t = (float)j*(1.0f/16.0f); t *= 0.9f; @@ -595,14 +592,13 @@ void player__approximate_best_trajectory( player_instance *player ) v3f n; int idx = spherecast_world( world, co0,co1, - k_board_radius*0.5f, &t1, n); + k_board_radius*0.1f, &t1, n); if( idx != -1 ){ goto invalidated_grind; } v3_copy( co1, co0 ); } -#endif v3_copy( grind.n, jump->n ); @@ -614,10 +610,8 @@ void player__approximate_best_trajectory( player_instance *player ) s->possible_jumps[ s->possible_jump_count ++ ] = *jump; -#if 0 continue; invalidated_grind:; -#endif } } @@ -1010,7 +1004,8 @@ VG_STATIC void skate_apply_pump_model( player_instance *player ) v3_muladds( s->state.throw_v, player->rb.to_world[1], -doty, Fl); if( s->state.activity == k_skate_activity_ground ){ - v3_muladds( player->rb.v, Fl, k_mmcollect_lat, player->rb.v ); + if( v3_length2(player->rb.v)<(20.0f*20.0f) ) + v3_muladds( player->rb.v, Fl, k_mmcollect_lat, player->rb.v ); v3_muladds( s->state.throw_v, Fl, -k_mmcollect_lat, s->state.throw_v ); } @@ -1191,10 +1186,13 @@ VG_STATIC void player__skate_post_update( player_instance *player ) slide = 0.0f; } + static float menu_gate = 1.0f; + menu_gate = vg_lerpf( menu_gate, 1-cl_menu, vg.frame_delta*4.0f ); + float - vol_main = sqrtf( (1.0f-air)*attn*(1.0f-slide) * 0.4f ), - vol_air = sqrtf( air *attn * 0.5f ), - vol_slide = sqrtf( (1.0f-air)*attn*slide * 0.25f ); + vol_main = sqrtf( (1.0f-air)*attn*(1.0f-slide) * 0.4f ) * menu_gate, + vol_air = sqrtf( air *attn * 0.5f ) * menu_gate, + vol_slide = sqrtf( (1.0f-air)*attn*slide * 0.25f ) * menu_gate; const u32 flags = AUDIO_FLAG_SPACIAL_3D|AUDIO_FLAG_LOOP; diff --git a/player_walk.c b/player_walk.c index 692a296..1e92bb1 100644 --- a/player_walk.c +++ b/player_walk.c @@ -587,6 +587,7 @@ VG_STATIC void player__walk_update( player_instance *player ) w->state_gate_storage = w->state; player__pass_gate( player, gate ); } + rb_update_transform( &player->rb ); } VG_STATIC void player__walk_restore( player_instance *player ) diff --git a/scene.h b/scene.h index 74c4ea6..aeecd4e 100644 --- a/scene.h +++ b/scene.h @@ -115,8 +115,8 @@ VG_STATIC void scene_add_mdl_submesh( scene *pscene, mdl_context *mdl, v3_normalize( normal_matrix[2] ); for( u32 i=0; ivertex_count; i++ ){ - mdl_vert *src = &src_verts[ i ]; - scene_vert *pvert = &dst_verts[ i ]; + mdl_vert *src = &src_verts[i]; + scene_vert *pvert = &dst_verts[i]; m4x3_mulv( transform, src->co, pvert->co ); diff --git a/skaterift.c b/skaterift.c index 795ca58..1db6db5 100644 --- a/skaterift.c +++ b/skaterift.c @@ -27,16 +27,13 @@ VG_STATIC struct player_avatar localplayer_avatar; VG_STATIC glmesh localplayer_meshes[3]; vg_tex2d localplayer_texture = { .path = "textures/ch_gradient.qoi" }; - - - - +player_instance *tmp_localplayer(void) +{ + return &localplayer; +} #include "network.h" - -#if 0 #include "menu.h" -#endif #include "vehicle.h" static int cl_ui = 1, @@ -220,10 +217,14 @@ VG_STATIC void load_playermodels(void) vg_release_thread_sync(); } +void temp_update_playermodel(void){ + player__use_mesh( &localplayer, &localplayer_meshes[cl_playermdl_id] ); +} + VG_STATIC void vg_load(void) { vg_loader_step( render_init, NULL ); - //vg_loader_step( menu_init, NULL ); + vg_loader_step( menu_init, NULL ); vg_loader_step( world_init, NULL ); //vg_loader_step( player_init, NULL ); //vg_loader_step( vehicle_init, NULL ); @@ -237,7 +238,7 @@ VG_STATIC void vg_load(void) player__create( &localplayer ); player_avatar_load( &localplayer_avatar, "models/ch_new.mdl" ); player__use_avatar( &localplayer, &localplayer_avatar ); - player__use_mesh( &localplayer, &localplayer_meshes[0] ); + player__use_mesh( &localplayer, &localplayer_meshes[cl_playermdl_id] ); player__use_texture( &localplayer, &localplayer_texture ); player__bind( &localplayer ); @@ -249,7 +250,7 @@ VG_STATIC void vg_load(void) /* 'systems' are completely loaded now */ /* load home world */ - world_load( &world_global.worlds[0], "maps/mp_gridmap.mdl" ); + world_load( &world_global.worlds[0], "maps/mp_mtzero.mdl" ); #if 0 world_load( &world_global.worlds[1], "maps/mp_gridmap.mdl" ); @@ -360,15 +361,12 @@ VG_STATIC void vg_update_post(void) float dist = 200.0f; - for( int i=0; i<10; i++ ) - { - if( ray_world( get_active_world(), rc, rd, &ray ) ) - { + for( int i=0; i<10; i++ ){ + if( ray_world( get_active_world(), rc, rd, &ray ) ){ dist = (float)i*5.0f + ray.dist; break; } - else - { + else{ v3_muladds( rc, rd, ray.dist, rc ); } } @@ -376,10 +374,8 @@ VG_STATIC void vg_update_post(void) distances[si] = dist; - for( int i=0; i<14; i++ ) - { - if( distances[i] != 200.0f ) - { + for( int i=0; i<14; i++ ){ + if( distances[i] != 200.0f ){ u32 colours[] = { VG__RED, VG__BLUE, VG__GREEN, VG__CYAN, VG__YELOW, VG__PINK, VG__WHITE }; @@ -404,13 +400,21 @@ VG_STATIC void vg_update_post(void) v3f ears = { 1.0f,0.0f,0.0f }; m3x3_mulv( main_camera.transform, ears, ears ); - v3_copy( ears, vg_audio.listener_ears ); - v3_copy( main_camera.transform[3], vg_audio.listener_pos ); - v3_copy( localplayer.rb.v, vg_audio.listener_velocity ); + v3_copy( ears, vg_audio.external_listener_ears ); + v3_copy( main_camera.transform[3], vg_audio.external_listener_pos ); + + /* TODO: this is transformed back and fourth twice. */ + if( localplayer.gate_waiting ){ + m4x3_mulv( localplayer.gate_waiting->transport, + vg_audio.external_listener_pos, + vg_audio.external_listener_pos ); + } + + v3_copy( localplayer.rb.v, vg_audio.external_lister_velocity ); audio_unlock(); -#if 0 menu_update(); +#if 0 vehicle_update_post(); #endif } @@ -430,16 +434,14 @@ VG_STATIC void present_view_with_post_processing(void) glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA); glBlendEquation(GL_FUNC_ADD); - if( cl_blur ) - { + if( cl_blur ){ shader_blitblur_use(); shader_blitblur_uTexMain( 0 ); shader_blitblur_uTexMotion( 1 ); shader_blitblur_uBlurStrength(cl_blur_strength / (vg.frame_delta*60.0f)); v2f menu_blurring; - //v2_muls( (v2f){ 0.04f, 0.001f }, menu_opacity, menu_blurring ); - v2_muls( (v2f){ 0.04f, 0.001f }, 0.0f, menu_blurring ); + v2_muls( (v2f){ 0.04f, 0.001f }, menu_opacity, menu_blurring ); shader_blitblur_uOverrideDir( menu_blurring ); if( cl_view_id == 0 ) @@ -451,8 +453,7 @@ VG_STATIC void present_view_with_post_processing(void) render_fb_bind_texture( gpipeline.fb_main, 1, 1 ); } - else - { + else{ shader_blit_use(); shader_blit_uTexMain( 0 ); render_fb_bind_texture( gpipeline.fb_main, 0, 0 ); @@ -500,17 +501,6 @@ VG_STATIC void render_scene(void) render_world( view_world, &main_camera, 0 ); - int player_transparent = 1, - player_draw = 1; - -#if 0 - if( (localplayer.subsystem == k_player_subsystem_dead) || - (localplayer.camera_mode == k_cam_thirdperson) ) - player_transparent = 0; -#endif - - if( !player_transparent && player_draw ) - player__render( &main_camera, &localplayer ); render_water_texture( view_world, &main_camera, 0 ); render_fb_bind( gpipeline.fb_main ); @@ -520,18 +510,10 @@ VG_STATIC void render_scene(void) if( localplayer.gate_waiting ) depth = 0; render_world_gates( view_world, &main_camera, depth ); - if( player_transparent && player_draw ) + if( !cl_menu ) render_player_transparent(); } -VG_STATIC void render_menu(void) -{ - glClear( GL_DEPTH_BUFFER_BIT ); -#if 0 - menu_render( &main_camera ); -#endif -} - VG_STATIC void render_main_game(void) { #if 0 @@ -549,31 +531,33 @@ VG_STATIC void render_main_game(void) main_camera.fov = fov; #endif - /* copy camera from player. - * TODO: blend with camera from menu */ - - /* FIXME: TEMP!! */ player__pre_render( &localplayer ); - v3_copy( localplayer.cam.pos, main_camera.pos ); - v3_copy( localplayer.cam.angles, main_camera.angles ); - main_camera.fov = localplayer.cam.fov; + v3_lerp( localplayer.cam.pos, menu_camera_pos, menu_opacity, + main_camera.pos ); + main_camera.angles[0] = + vg_alerpf( localplayer.cam.angles[0], menu_camera_angles[0], + menu_opacity ); + main_camera.angles[1] = + vg_lerpf ( localplayer.cam.angles[1], menu_camera_angles[1], + menu_opacity ); + + main_camera.fov = vg_lerpf( localplayer.cam.fov, menu_smooth_fov, + menu_opacity ); main_camera.nearz = 0.1f; main_camera.farz = 2100.0f; camera_update_transform( &main_camera ); - if( localplayer.gate_waiting ) - { + if( localplayer.gate_waiting ){ m3x3_mul( localplayer.basis_gate, main_camera.transform, main_camera.transform ); } - else - { + else{ m3x3_mul( localplayer.basis, main_camera.transform, main_camera.transform ); } - + camera_update_view( &main_camera ); camera_update_projection( &main_camera ); camera_finalize( &main_camera ); @@ -581,15 +565,18 @@ VG_STATIC void render_main_game(void) /* ========== Begin Frame ========== */ render_scene(); - present_view_with_post_processing(); -#if 0 - if( cl_menu ) - { - render_menu(); + if( cl_menu ) { + glClear( GL_DEPTH_BUFFER_BIT ); + menu_render_bg(); + glEnable( GL_DEPTH_TEST ); render_player_transparent(); } -#endif + + present_view_with_post_processing(); + + if( cl_menu ) + menu_render_fg( &main_camera ); /* =========== End Frame =========== */ } @@ -618,12 +605,11 @@ VG_STATIC void vg_render(void) VG_STATIC void run_light_widget( struct light_widget *lw ); VG_STATIC void vg_ui(void) { +#if 0 player__im_gui( &localplayer ); +#endif world_instance *world = get_active_world(); - -#if 0 menu_crap_ui(); -#endif #if 0 if( cl_light_edit ) diff --git a/textures_src/menu.qoi b/textures_src/menu.qoi index 26e22f0..e626f9f 100644 Binary files a/textures_src/menu.qoi and b/textures_src/menu.qoi differ diff --git a/world.h b/world.h index e23ae21..b9814f8 100644 --- a/world.h +++ b/world.h @@ -570,7 +570,8 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) return; } - existing = audio_channel_fadeout( existing, audio->crossfade); + existing->group = 0; + existing = audio_channel_fadeout(existing, audio->crossfade); } ch = audio_get_first_idle_channel(); diff --git a/world_gen.h b/world_gen.h index 500592d..64395bc 100644 --- a/world_gen.h +++ b/world_gen.h @@ -334,16 +334,23 @@ VG_STATIC void world_compute_light_indices( world_instance *world ) icubes_max[i] = cubes_max[i]; } + v3f cube_size; + v3i icubes_count; v3i_sub( icubes_max, icubes_min, icubes_count ); for( int i=0; i<3; i++ ){ - icubes_count[i] = VG_MIN( 128, icubes_count[i]+1 ); - cubes_max[i] = icubes_min[i] + icubes_count[i]; + int clamped_count = VG_MIN( 128, icubes_count[i]+1 ); + float clamped_max = icubes_min[i] + clamped_count, + max = icubes_min[i] + icubes_count[i]+1; + + icubes_count[i] = clamped_count; + cube_size[i] = (max / clamped_max) * k_light_cube_size; + cubes_max[i] = clamped_max; } - v3_muls( cubes_min, k_light_cube_size, cubes_min ); - v3_muls( cubes_max, k_light_cube_size, cubes_max ); + v3_mul( cubes_min, cube_size, cubes_min ); + v3_mul( cubes_max, cube_size, cubes_max ); for( int i=0; i<3; i++ ){ float range = cubes_max[i]-cubes_min[i]; @@ -361,12 +368,8 @@ VG_STATIC void world_compute_light_indices( world_instance *world ) vg_info( "Computing light cubes (%d) [%f %f %f] -> [%f %f %f]\n", total_cubes, cubes_min[0], -cubes_min[2], cubes_min[1], cubes_max[0], -cubes_max[2], cubes_max[1] ); - v3_copy( cubes_min, world->ub_lighting.g_cube_min ); - v3f cube_size; - v3_div( (v3f){1.0f,1.0f,1.0f}, world->ub_lighting.g_cube_inv_range, - cube_size ); float bound_radius = v3_length( cube_size ); for( int iz = 0; izcolour, light->colour[3] * 2.0f, light_dst[i*3+0] ); - light_dst[i*3+0][3] = -1.0f; + light_dst[i*3+0][3] = 2.0f; if( !light->daytime ){ - u32 hash = (i * 29986577) & 0xff; + u32 hash = (i * 29986577u) & 0xffu; float switch_on = hash; switch_on *= (1.0f/255.0f); diff --git a/world_routes.h b/world_routes.h index f8a566c..d866cb7 100644 --- a/world_routes.h +++ b/world_routes.h @@ -35,14 +35,18 @@ void world_routes_local_set_record( world_instance *world, ent_route *route, temp.points = 0; temp.time = time_centiseconds; +#if 0 highscores_push_record( &temp ); +#endif struct track_info *ti = &track_infos[ route->official_track_id ]; ti->push = 1; if( ti->achievement_id ){ +#if 0 steam_set_achievement( ti->achievement_id ); steam_store_achievements(); +#endif } } else{ @@ -128,7 +132,8 @@ VG_STATIC void world_routes_activate_entry_gate( world_instance *world, route->checkpoints_start+k ); ent_gate *gk = mdl_arritm( &world->ent_gate, cp->gate_index ); - if( gk == rg ){ + gk = mdl_arritm( &world->ent_gate, gk->target ); + if( gk == dest ){ route->active_checkpoint = k; world_routes_time_lap( world, route ); break; @@ -253,35 +258,48 @@ VG_STATIC void world_routes_place_curve( world_instance *world, ray_hit ha, hb; ha.dist = 8.0f; hb.dist = 8.0f; - if( ray_world( world, sa, down, &ha ) && - ray_world( world, sb, down, &hb )) - { - scene_vert va, vb; - - v3_muladds( ha.pos, up, 0.06f, va.co ); - v3_muladds( hb.pos, up, 0.06f, vb.co ); - - scene_vert_pack_norm( &va, up ); - scene_vert_pack_norm( &vb, up ); - - float t1 = (travel_length / total_length) * patch_count; - va.uv[0] = t1; - va.uv[1] = 0.0f; - vb.uv[0] = t1; - vb.uv[1] = 1.0f; - - scene_push_vert( world->scene_lines, &va ); - scene_push_vert( world->scene_lines, &vb ); - - if( last_valid ){ - /* Connect them with triangles */ - scene_push_tri( world->scene_lines, (u32[3]){ - last_valid+0-2, last_valid+1-2, last_valid+2-2} ); - scene_push_tri( world->scene_lines, (u32[3]){ - last_valid+1-2, last_valid+3-2, last_valid+2-2} ); + + int resa = ray_world( world, sa, down, &ha ), + resb = ray_world( world, sb, down, &hb ); + + if( resa && resb ){ + struct world_surface *surfa = ray_hit_surface( world, &ha ), + *surfb = ray_hit_surface( world, &hb ); + + if( (surfa->info.flags & k_material_flag_skate_surface) && + (surfb->info.flags & k_material_flag_skate_surface) ) + { + scene_vert va, vb; + + float gap = vg_fractf(cur_x*0.5f)*0.02f; + + v3_muladds( ha.pos, up, 0.06f+gap, va.co ); + v3_muladds( hb.pos, up, 0.06f+gap, vb.co ); + + scene_vert_pack_norm( &va, up ); + scene_vert_pack_norm( &vb, up ); + + float t1 = (travel_length / total_length) * patch_count; + va.uv[0] = t1; + va.uv[1] = 0.0f; + vb.uv[0] = t1; + vb.uv[1] = 1.0f; + + scene_push_vert( world->scene_lines, &va ); + scene_push_vert( world->scene_lines, &vb ); + + if( last_valid ){ + /* Connect them with triangles */ + scene_push_tri( world->scene_lines, (u32[3]){ + last_valid+0-2, last_valid+1-2, last_valid+2-2} ); + scene_push_tri( world->scene_lines, (u32[3]){ + last_valid+1-2, last_valid+3-2, last_valid+2-2} ); + } + + last_valid = world->scene_lines->vertex_count; } - - last_valid = world->scene_lines->vertex_count; + else + last_valid = 0; } else last_valid = 0; @@ -312,7 +330,8 @@ VG_STATIC void world_routes_create_mesh( world_instance *world, u32 route_id ) ent_gate *start_gate = mdl_arritm( &world->ent_gate, c0->gate_index ); start_gate = mdl_arritm( &world->ent_gate, start_gate->target ); - ent_gate *end_gate = mdl_arritm( &world->ent_gate, c1->gate_index ); + ent_gate *end_gate = mdl_arritm( &world->ent_gate, c1->gate_index ), + *collector = mdl_arritm( &world->ent_gate, end_gate->target ); v4f p[3]; @@ -377,9 +396,13 @@ VG_STATIC void world_routes_create_mesh( world_instance *world, u32 route_id ) else{ v3_copy( end_gate->co[0], p[2] ); v3_add( (v3f){0.0f,0.1f,0.0f}, p[2], p[2] ); - p[2][3] = end_gate->ref_count; - p[2][3] -= (float)end_gate->ref_total * 0.5f; - end_gate->ref_count ++; + p[2][3] = collector->ref_count; + + if( i == route->checkpoints_count-1) + p[2][3] -= 1.0f; + + p[2][3] -= (float)collector->ref_total * 0.5f; + //collector->ref_count ++; } /* p0,p1,p2 bezier patch is complete @@ -439,8 +462,6 @@ VG_STATIC void world_routes_generate( world_instance *world ) ent_gate *start_gate = mdl_arritm( &world->ent_gate, c0->gate_index ); start_gate = mdl_arritm( &world->ent_gate, start_gate->target ); - - ent_gate *end_gate = mdl_arritm( &world->ent_gate, c1->gate_index ); start_gate->ref_total ++; if( !c0->path_count ) @@ -452,12 +473,6 @@ VG_STATIC void world_routes_generate( world_instance *world ) ent_route_node *rn = mdl_arritm( &world->ent_route_node, index->index ); rn->ref_total ++; - - if( j+1 < c0->path_count ){ - } - else{ - end_gate->ref_total ++; - } } } } @@ -516,6 +531,10 @@ VG_STATIC void world_routes_ent_init( world_instance *world ) gate = mdl_arritm(&world->ent_gate, gate->target ); for( u32 k=0; k<4; k++ ){ + if( gate->routes[k] == i ){ + vg_error( "already assigned route to gate\n" ); + break; + } if( gate->routes[k] == 0xffff ){ gate->routes[k] = i; break; @@ -525,6 +544,15 @@ VG_STATIC void world_routes_ent_init( world_instance *world ) } } + for( u32 i=0; ient_gate); i++ ){ + ent_gate *gate = mdl_arritm( &world->ent_gate, i ); + + vg_info( "ROUTES :: %hu %hu %hu %hu\n", gate->routes[0], + gate->routes[1], + gate->routes[2], + gate->routes[3] ); + } + world_routes_clear( world ); }