vec3 Actor::getForward() { return getRotatedVec3(forward); }
extern void game_update_and_render(Memory* memory, RenderState *renderer, float last_frame_time_seconds, const u8 *keys, SDL_Event e) { UNUSED(keys); UNUSED(e); ASSERT(sizeof(PermanentState) <= memory->permanent_size); PermanentState *permanent = (PermanentState *)memory->permanent; ASSERT(sizeof(ScratchState) <= memory->scratch_size); ScratchState *scratch = (ScratchState *)memory->scratch; ASSERT(sizeof(DebugState) <= memory->debug_size); DebugState *debug = (DebugState *)memory->debug; ASSERT(sizeof(Node16Arena) <= memory->node16_size); Node16Arena *node16 = (Node16Arena *)memory->node16; ASSERT(sizeof(Node16) == sizeof(Node16*)*2 + 16); ASSERT(sizeof(FoundPathNode) == sizeof(BarNode)); if (memory->is_initialized == false) { initialize_memory(permanent, node16, renderer, memory); } // dynamic blocks for (u32 i = 0; i < permanent->dynamic_block_count; i++) { if ( permanent->dynamic_blocks[i].total_frames > 1) { permanent->dynamic_blocks[i].frame_duration_left += last_frame_time_seconds; if (permanent->dynamic_blocks[i].frame_duration_left >= permanent->dynamic_blocks[i].duration_per_frame) { int frame_index = permanent->dynamic_blocks[i].current_frame; if (permanent->dynamic_blocks[i].plays_forward == 1) { frame_index +=1; if (frame_index > permanent->dynamic_blocks[i].last_frame) frame_index = permanent->dynamic_blocks[i].first_frame; } else { frame_index -= 1; if (frame_index < permanent->dynamic_blocks[i].first_frame) frame_index = permanent->dynamic_blocks[i].last_frame; } permanent->dynamic_blocks[i].current_frame = frame_index; permanent->dynamic_blocks[i].frame_duration_left = 0; SimpleFrame f = generated_frames[frame_index]; permanent->dynamic_blocks[i].frame.x_pos = f.frameX; permanent->dynamic_blocks[i].frame.y_pos = f.frameY; permanent->dynamic_blocks[i].frame.width = f.frameW; permanent->dynamic_blocks[i].frame.height = f.frameH; permanent->dynamic_blocks[i].frame.y_internal_off = f.ssH - (f.sssY + f.frameH); permanent->dynamic_blocks[i].frame.x_internal_off = f.ssW - (f.sssX + f.frameW); } } } permanent->colored_line_count = 0; #if 1 { permanent->colored_line_count = 0; for (u32 i = 0; i < permanent->actor_count; i++) { if (permanent->paths[i].Sentinel->Next != permanent->paths[i].Sentinel) { float distance = Vector3Distance(permanent->steer_data[i].location, permanent->paths[i].Sentinel->Next->path.node); if (distance < 5.f){ Node16 *First = permanent->paths[i].Sentinel->Next; permanent->paths[i].Sentinel->Next = First->Next; First->Next = node16->Free->Next; node16->Free->Next = First; First->Prev = node16->Free; } } BEGIN_PERFORMANCE_COUNTER(actors_steering); { Vector3 seek_force = seek_return(&permanent->steer_data[i], permanent->paths[i].Sentinel->Next->path.node); seek_force = Vector3MultiplyScalar(seek_force, 1); actor_apply_force(&permanent->steer_data[i], seek_force); permanent->steer_data[i].velocity = Vector3Add(permanent->steer_data[i].velocity, permanent->steer_data[i].acceleration); permanent->steer_data[i].velocity = Vector3Limit(permanent->steer_data[i].velocity, permanent->steer_data[i].max_speed); permanent->steer_data[i].location = Vector3Add(permanent->steer_data[i].location, Vector3MultiplyScalar(permanent->steer_data[i].velocity, last_frame_time_seconds)); permanent->steer_data[i].acceleration = Vector3MultiplyScalar(permanent->steer_data[i].acceleration, 0); // left = frame 0, down = frame 1 right = frame 2,up = frame 3 double angle = (180.0 / PI) * atan2(permanent->steer_data[i].velocity.x, permanent->steer_data[i].velocity.y); angle = angle + 180; if (angle > 315 || angle < 45) { permanent->anim_data[i].frame = 10; //11 } else if (angle >= 45 && angle <= 135) { permanent->anim_data[i].frame = 4;// 5 } else if (angle >=135 && angle <= 225) { permanent->anim_data[i].frame = 6; //7 } else if (angle > 225 && angle <= 315) { permanent->anim_data[i].frame = 8; //9 } permanent->anim_data[i].frame_duration_left += last_frame_time_seconds; if (permanent->anim_data[i].frame_duration_left > 0.1f) { permanent->anim_data[i].frame += 1; } if (permanent->anim_data[i].frame_duration_left > 0.2f) { permanent->anim_data[i].frame_duration_left = 0; } END_PERFORMANCE_COUNTER(actors_steering); } #if 1 if (permanent->paths[i].Sentinel->Next != permanent->paths[i].Sentinel) { Node16 * d= permanent->paths[i].Sentinel->Next; u32 c = permanent->colored_line_count; while (d->Next != permanent->paths[i].Sentinel){ //if (d->path.node.z != d->Next->path.node.z) { // printf("going from %f,%f,[%f] to %f,%f,[%f]\n", d->path.node.x, d->path.node.y, d->path.node.z, d->Next->path.node.x, d->Next->path.node.y, d->Next->path.node.z); //} permanent->colored_lines[c].x1 = getRotatedXFloat(d->path.node.x, d->path.node.y, facing_side, permanent->dims); permanent->colored_lines[c].y1 = getRotatedYFloat(d->path.node.x, d->path.node.y, facing_side, permanent->dims); permanent->colored_lines[c].z1 = d->path.node.z; permanent->colored_lines[c].x2 = getRotatedXFloat(d->Next->path.node.x, d->Next->path.node.y, facing_side, permanent->dims); permanent->colored_lines[c].y2 = getRotatedYFloat(d->Next->path.node.x, d->Next->path.node.y, facing_side, permanent->dims); permanent->colored_lines[c].z2 = d->Next->path.node.z; permanent->colored_lines[c].r = 0.0f; permanent->colored_lines[c].g = 0.0f; permanent->colored_lines[c].b = 0.0f; d = d->Next; c++; } permanent->colored_line_count = c; } #endif ASSERT( permanent->colored_line_count < LINE_BATCH_COUNT * MAX_IN_BUFFER) if (permanent->paths[i].Sentinel->Next != permanent->paths[i].Sentinel) { continue; } BEGIN_PERFORMANCE_COUNTER(mass_pathfinding); TempMemory temp_mem = begin_temporary_memory(&scratch->arena); grid_node * Start = get_node_at(permanent->grid, permanent->steer_data[i].location.x/permanent->block_size.x, permanent->steer_data[i].location.y/permanent->block_size.y, (permanent->steer_data[i].location.z + 10)/permanent->block_size.z_level); if (Start->walkable) { } else { Start = get_neighboring_walkable_node(permanent->grid, Start->X, Start->Y, Start->Z); if (!Start->walkable) { Start = get_random_walkable_node(permanent->grid); } } grid_node * End = get_random_walkable_node(permanent->grid); ASSERT(Start->walkable); ASSERT(End->walkable); path_list * PathRaw = find_path(Start, End, permanent->grid, &scratch->arena); path_list *Path = NULL; if (PathRaw) { //Path = smooth_path(PathRaw, &scratch->arena, permanent->grid); Path = PathRaw; if (Path) { path_node * done= Path->Sentinel->Prev; while (done != Path->Sentinel) { Node16 *N = NULL; if ( node16->Free->Next != node16->Free) { N = node16->Free->Next; node16->Free->Next = N->Next; node16->Free->Next->Prev = node16->Free; } else { N = PUSH_STRUCT(&node16->arena, Node16); } ActorPath * p = &(permanent->paths[i]); // TODO iam not sure about this, is this the right way to center all positions in the path nodes? // should it be done somewhere else instead? // TODO and why o why does it need something extra when facing Front and not under other circumstances. //float xMult = 0;//facing_side == Front ? 1 : facing_side == Left ? -0.5 : 0.5; //float yMult = 0;//facing_side == Front ? 0.5 : 1; N->path.node.x = (permanent->block_size.x/2) + done->X * permanent->block_size.x; N->path.node.y = (permanent->block_size.y/2) + done->Y * permanent->block_size.y; N->path.node.z = done->Z * permanent->block_size.z_level; /* if (done->Prev != Path->Sentinel) { */ /* // going up */ /* if (done->Z > done->Prev->Z) { */ /* printf("going up\n"); */ /* printf("%d,%d,%d %d,%d,%d\n", done->X,done->Y,done->Z, done->Prev->X, done->Prev->Y, done->Prev->Z); */ /* } */ /* if (done->Z < done->Prev->Z) { */ /* printf("going down 222\n"); */ /* printf("%d,%d,%d %d,%d,%d\n", done->X,done->Y,done->Z, done->Prev->X, done->Prev->Y, done->Prev->Z); */ /* } */ /* } */ /* if (done->Next != Path->Sentinel) { */ /* // going down */ /* if (done->Z < done->Next->Z) { */ /* printf("going down\n"); */ /* printf("%d,%d,%d %d,%d,%d\n", done->X,done->Y,done->Z, done->Next->X, done->Next->Y, done->Next->Z); */ /* } */ /* } */ // if this is part of a stair move going up east/west // TODO: this routine patches some issues which, IMO would better be solved at the root, dunno how wnad where though./ #if 0 // pathing movemenst going up on east/west stairs if (facing_side == Front) { if (done->Prev != Path->Sentinel) { // going up if (done->Z > done->Prev->Z) { if (done->X < done->Prev->X){ N->path.node.x += permanent->block_size.x; } else if (done->X > done->Prev->X){ N->path.node.x -= permanent->block_size.x; } } } if (done->Next != Path->Sentinel) { // going down if (done->Z < done->Next->Z) { if (done->X < done->Next->X){ N->path.node.x -= permanent->block_size.x; } else if (done->X > done->Next->X){ N->path.node.x += permanent->block_size.x; } } } } if (facing_side == Left) { if (done->Prev != Path->Sentinel) { // going up if (done->Z > done->Prev->Z) { if (done->Y < done->Prev->Y){ N->path.node.y += permanent->block_size.y; } else if (done->Y > done->Prev->Y){ N->path.node.y -= permanent->block_size.y; } } } if (done->Next != Path->Sentinel) { // going down if (done->Z < done->Next->Z) { if (done->Y < done->Next->Y){ N->path.node.y -= permanent->block_size.y; } else if (done->Y > done->Next->Y){ N->path.node.y += permanent->block_size.y; } } } } if (facing_side == Right) { if (done->Prev != Path->Sentinel) { // going up if (done->Z > done->Prev->Z) { if (done->Y < done->Prev->Y){ N->path.node.y += permanent->block_size.y; } else if (done->Y > done->Prev->Y){ N->path.node.y -= permanent->block_size.y; } } } if (done->Next != Path->Sentinel) { // going down if (done->Z < done->Next->Z) { if (done->Y < done->Next->Y){ N->path.node.y -= permanent->block_size.y; } else if (done->Y > done->Next->Y){ N->path.node.y += permanent->block_size.y; } } } } #endif DLIST_ADDFIRST(p, N); done = done->Prev; } } } END_PERFORMANCE_COUNTER(mass_pathfinding); //path_list * Path = ExpandPath(PathSmooth, &scratch->arena); BEGIN_PERFORMANCE_COUNTER(grid_cleaning); for (int i = 0; i < permanent->grid->width * permanent->grid->height * permanent->grid->depth;i++) { permanent->grid->nodes[i].f = 0; permanent->grid->nodes[i].g = 0; permanent->grid->nodes[i].opened = 0; permanent->grid->nodes[i].closed = 0; permanent->grid->nodes[i].Next = NULL; permanent->grid->nodes[i].parent = NULL; } END_PERFORMANCE_COUNTER(grid_cleaning); end_temporary_memory(temp_mem); } set_colored_line_batch_sizes(permanent, renderer); } #endif BEGIN_PERFORMANCE_COUNTER(actors_data_gathering); for (u32 i = 0; i < permanent->actor_count; i++) { permanent->actors[i]._location = getRotatedVec3( permanent->steer_data[i].location, facing_side, permanent->dims, permanent->block_size); permanent->actors[i]._palette_index = permanent->anim_data[i].palette_index; permanent->actors[i]._frame = permanent->anim_data[i].frame; permanent->actors[i].x_off = 0; permanent->actors[i].y_off = 0; if ( permanent->anim_data[i].frame == 4) { permanent->actors[i].complex = &generated_body_frames[BP_walking_west_body_000]; } else if (permanent->anim_data[i].frame == 5) { permanent->actors[i].complex = &generated_body_frames[BP_walking_west_body_001]; } else if (permanent->anim_data[i].frame == 6) { permanent->actors[i].complex = &generated_body_frames[BP_walking_south_body_000]; } else if (permanent->anim_data[i].frame == 7) { permanent->actors[i].complex = &generated_body_frames[BP_walking_south_body_001]; } else if (permanent->anim_data[i].frame == 8) { permanent->actors[i].complex = &generated_body_frames[BP_walking_east_body_000]; } else if (permanent->anim_data[i].frame == 9) { permanent->actors[i].complex = &generated_body_frames[BP_walking_east_body_001]; } else if (permanent->anim_data[i].frame == 10) { permanent->actors[i].complex = &generated_body_frames[BP_walking_north_body_000]; } else if (permanent->anim_data[i].frame == 11) { permanent->actors[i].complex = &generated_body_frames[BP_walking_north_body_001]; } /* if ( permanent->anim_data[i].frame % 2 == 0) { */ /* permanent->actors[i].complex = &generated_body_frames[BP_total_east_body_000]; */ /* } else { */ /* permanent->actors[i].complex = &generated_body_frames[BP_total_east_body_001]; */ /* } */ } for (u32 i = permanent->actor_count; i < permanent->actor_count*2; i++) { u32 j = i - permanent->actor_count; permanent->actors[i]._location = getRotatedVec3( permanent->steer_data[j].location, facing_side, permanent->dims, permanent->block_size); permanent->actors[i]._palette_index = (1.0f / 16.0f) * (j % 16);//permanent->anim_data[j].palette_index; permanent->actors[i]._frame = permanent->anim_data[j].frame; int deltaX = permanent->actors[j].complex->anchorX - permanent->actors[j].complex->pivotX; int deltaY = permanent->actors[j].complex->anchorY - permanent->actors[j].complex->pivotY; permanent->actors[i].x_off = deltaX; permanent->actors[i].y_off = -1 * deltaY; if ( permanent->anim_data[j].frame == 4) { permanent->actors[i].complex = &generated_body_frames[BP_facing_west_head_000]; } else if (permanent->anim_data[j].frame == 5) { permanent->actors[i].complex = &generated_body_frames[BP_facing_west_head_000]; } else if (permanent->anim_data[j].frame == 6) { permanent->actors[i].complex = &generated_body_frames[BP_facing_south_head_000]; } else if (permanent->anim_data[j].frame == 7) { permanent->actors[i].complex = &generated_body_frames[BP_facing_south_head_000]; } else if (permanent->anim_data[j].frame == 8) { permanent->actors[i].complex = &generated_body_frames[BP_facing_east_head_000]; } else if (permanent->anim_data[j].frame == 9) { permanent->actors[i].complex = &generated_body_frames[BP_facing_east_head_000]; } else if (permanent->anim_data[j].frame == 10) { permanent->actors[i].complex = &generated_body_frames[BP_facing_north_head_000]; } else if (permanent->anim_data[j].frame == 11) { permanent->actors[i].complex = &generated_body_frames[BP_facing_north_head_000]; } } END_PERFORMANCE_COUNTER(actors_data_gathering); BEGIN_PERFORMANCE_COUNTER(actors_sort); Actor_quick_sort(permanent->actors, permanent->actor_count*2); END_PERFORMANCE_COUNTER(actors_sort); }
vec3 Actor::getUp() { return getRotatedVec3(up); }