vec3 Actor::getForward()
{
	return getRotatedVec3(forward);
}
Exemple #2
0
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);
}