Beispiel #1
0
void Game::_control_camera(float mouse_x, float mouse_y)
{
    float camera_speed = 5.0f * _delta_time;
    if(app_is_key_down(KEY_SHIFT))
        camera_speed *= 3.0f;

    float3 look = quaternionGetZAxis(&_camera.orientation);
    float3 right = quaternionGetXAxis(&_camera.orientation);
    float3 up = quaternionGetYAxis(&_camera.orientation);
    look = float3multiplyScalar(&look, camera_speed);
    up = float3multiplyScalar(&up, camera_speed);
    right = float3multiplyScalar(&right, camera_speed);

    if(app_is_key_down(KEY_W))
        _camera.position = float3add(&_camera.position, &look);
    if(app_is_key_down(KEY_S))
        _camera.position = float3subtract(&_camera.position, &look);

    if(app_is_key_down(KEY_D))
        _camera.position = float3add(&_camera.position, &right);
    if(app_is_key_down(KEY_A))
        _camera.position = float3subtract(&_camera.position, &right);

    if(app_is_key_down(KEY_E))
        _camera.position = float3add(&_camera.position, &up);
    if(app_is_key_down(KEY_Q))
        _camera.position = float3subtract(&_camera.position, &up);

    if(app_is_key_down(KEY_UP))
        mouse_y = -1.0f;
    else if(app_is_key_down(KEY_DOWN))
        mouse_y = 1.0f;

    if(app_is_key_down(KEY_RIGHT))
        mouse_x = 1.0f;
    else if(app_is_key_down(KEY_LEFT))
        mouse_x = -1.0f;

    if(app_is_mouse_button_down(MOUSE_LEFT) == 0)
        mouse_x = mouse_y = 0.0f;

    // L/R Rotation
    float3 yaxis = {0.0f, 1.0f, 0.0f};
    quaternion q = quaternionFromAxisAngle(&yaxis, _delta_time*mouse_x);
    _camera.orientation = quaternionMultiply(&_camera.orientation, &q);

    // U/D rotation
    float3 xaxis = {1.0f, 0.0f, 0.0f};
    q = quaternionFromAxisAngle(&xaxis, _delta_time*mouse_y);
    _camera.orientation = quaternionMultiply(&q, &_camera.orientation);
}
Beispiel #2
0
/*
 * External
 */
Game::Game()
{
    _fps.frame = 0;
    _camera = TransformZero();
    //_camera.position.z = -60.0f;
    _camera.position.y = 5.0f;
    float3 axis = {1.0f, 0.0f, 0.0f};
    _camera.orientation = quaternionFromAxisAngle(&axis, 0.4f);
}
Beispiel #3
0
void animSequenceLoad( tAnimSequence* pAnimSequence,
                       const char* szFileName,
                       tAnimHierarchy const* pAnimHierarchy,
                       CFactory<tVector4>* pVectorFactory,
                       CFactory<tQuaternion>* pQuaternionFactory )
{
    const float fDegreeToRadian = 3.14159f / 180.0f;
    
    char szFullPath[256];
    getFullPath( szFullPath, szFileName );
    
    TiXmlDocument doc( szFullPath );
    bool bLoaded = doc.LoadFile();
    if( bLoaded )
    {
        pAnimSequence->miNumFrames = 0;
        
        TiXmlNode* pNode = doc.FirstChild( "jointKeyframe" )->FirstChild( "keyframe" );
        while( pNode )
        {
            ++pAnimSequence->miNumFrames;
            pNode = pNode->NextSibling( "keyframe" );
        }
        
        pAnimSequence->mafTime = (float *)MALLOC( sizeof( float ) * pAnimSequence->miNumFrames );
        pAnimSequence->maPositions = pVectorFactory->alloc( pAnimSequence->miNumFrames );
        pAnimSequence->maRotation = pQuaternionFactory->alloc( pAnimSequence->miNumFrames );
        pAnimSequence->maScalings = pVectorFactory->alloc( pAnimSequence->miNumFrames );
        pAnimSequence->mapJoints = (tJoint **)MALLOC( sizeof( tJoint* ) * pAnimSequence->miNumFrames );
        
        pAnimSequence->maRotationVec = pVectorFactory->alloc( pAnimSequence->miNumFrames );
        
        pAnimSequence->miNumJoints = 0;
        pAnimSequence->mapUniqueJoints = (tJoint **)MALLOC( sizeof( tJoint* ) * pAnimSequence->miNumFrames );
        memset( pAnimSequence->mapUniqueJoints, 0, sizeof( tJoint* ) * pAnimSequence->miNumFrames );
        
        pAnimSequence->mfLastTime = 0.0f;
        
        int iFrame = 0;
        pNode = doc.FirstChild( "jointKeyframe" )->FirstChild( "keyframe" );
        while( pNode )
        {
            TiXmlElement* pElement = pNode->ToElement();
            
            const char* szName = pElement->Attribute( "joint" );
            const char* szTime = pElement->Attribute( "time" );
            
            const char* szRotX = pElement->Attribute( "rotatex" );
            const char* szRotY = pElement->Attribute( "rotatey" );
            const char* szRotZ = pElement->Attribute( "rotatez" );
            
            const char* szTranslateX = pElement->Attribute( "translatex" );
            const char* szTranslateY = pElement->Attribute( "translatey" );
            const char* szTranslateZ = pElement->Attribute( "translatez" );
            
            // 24 frames / sec
            pAnimSequence->mafTime[iFrame] = ( (float)atof( szTime ) - 1.0f ) / 23.0f;
            if( pAnimSequence->mfLastTime < pAnimSequence->mafTime[iFrame] )
            {
                pAnimSequence->mfLastTime = pAnimSequence->mafTime[iFrame];
            }
            
            tVector4* pPos = &pAnimSequence->maPositions[iFrame];
            tVector4* pScaling = &pAnimSequence->maScalings[iFrame];
            tQuaternion* pRotation = &pAnimSequence->maRotation[iFrame];
            
            tVector4* pRotVec = &pAnimSequence->maRotationVec[iFrame];
            
            tVector4 xAxis = { 1.0f, 0.0f, 0.0f, 1.0f };
            tVector4 yAxis = { 0.0f, 1.0f, 0.0f, 1.0f };
            tVector4 zAxis = { 0.0f, 0.0f, 1.0f, 1.0f };
            
            // total rotation
            tQuaternion xRot, yRot, zRot;
            quaternionInit( &xRot );
            quaternionInit( &yRot );
            quaternionInit( &zRot );
            
            float fRotX = (float)atof( szRotX );
            float fRotY = (float)atof( szRotY );
            float fRotZ = (float)atof( szRotZ );
            
            fRotX *= fDegreeToRadian;
            fRotY *= fDegreeToRadian;
            fRotZ *= fDegreeToRadian;
            
            quaternionFromAxisAngle( &xRot, &xAxis, fRotX );
            quaternionFromAxisAngle( &yRot, &yAxis, fRotY );
            quaternionFromAxisAngle( &zRot, &zAxis, fRotZ );
            
            tQuaternion zyRot;
            quaternionMultiply( &zyRot, &zRot, &yRot );
            quaternionMultiply( pRotation, &zyRot, &xRot );
            
            // scale
            pScaling->fX = pScaling->fY = pScaling->fZ = pScaling->fW = 1.0f;
            
            // position
            pPos->fX = (float)atof( szTranslateX );
            pPos->fY = (float)atof( szTranslateY );
            pPos->fZ = (float)atof( szTranslateZ );
            pPos->fW = 1.0f;
            
            // rotation vector
            pRotVec->fX = fRotX;
            pRotVec->fY = fRotY;
            pRotVec->fZ = fRotZ;
            pRotVec->fW = 1.0f;
            
            // look for the joint in the hierarchy
            int iNumJoints = pAnimHierarchy->miNumJoints;
            for( int i = 0; i < iNumJoints; i++ )
            {
                if( !strcmp( szName, pAnimHierarchy->maJoints[i].mszName ) )
                {
                    pAnimSequence->mapJoints[iFrame] = &pAnimHierarchy->maJoints[i];
                    break;
                }
            }
            
            //OUTPUT( "%s time = %.1f rot ( %f, %f, %f )\n", szName, pAnimSequence->mafTime[iFrame], fRotX, fRotY, fRotZ );
            
            pNode = pNode->NextSibling( "keyframe" );
            
            ++iFrame;
        }
    }
    
    // unique joints in the hierarchy
    pAnimSequence->mapUniqueJoints = (tJoint **)MALLOC( sizeof( tJoint* ) * pAnimHierarchy->miNumJoints );
    pAnimSequence->miNumJoints = pAnimHierarchy->miNumJoints;
    for( int i = 0; i < pAnimHierarchy->miNumJoints; i++ )
    {
        pAnimSequence->mapUniqueJoints[i] = &pAnimHierarchy->maJoints[i];
    }
    
    // sort using joint as the index key
    sortOnJoints( pAnimSequence );
    pAnimSequence->maiStartFrames = (unsigned int *)MALLOC( sizeof( int ) * pAnimSequence->miNumJoints );
    pAnimSequence->maiEndFrames = (unsigned int *)MALLOC( sizeof( int ) * pAnimSequence->miNumJoints );

    int iNumFrames = pAnimSequence->miNumFrames;
    int iNumJoints = pAnimSequence->miNumJoints;
    
    for( int i = 0; i < iNumJoints; i++ )
    {
        pAnimSequence->maiStartFrames[i] = -1;
        pAnimSequence->maiEndFrames[i] = -1;
    }

    // get start and end indices of the joint's keyframes
    for( int i = 0; i < iNumJoints; i++ )
    {
        tJoint* pJoint = pAnimSequence->mapUniqueJoints[i];
        for( int j = 0; j < iNumFrames; j++ )
        {
            // find start
            if( pAnimSequence->mapJoints[j] == pJoint )
            {
                // find end
                pAnimSequence->maiStartFrames[i] = j;
                for( int k = j + 1; k < iNumFrames; k++ )
                {
                    if( pAnimSequence->mapJoints[k] != pJoint )
                    {
                        pAnimSequence->maiEndFrames[i] = k - 1;
                        break;
                    }
                }
                
                if( pAnimSequence->maiEndFrames[i] == -1 )
                {
                    pAnimSequence->maiEndFrames[i] = iNumFrames - 1;
                }
                
                break;
            }
            
        }   // for j = 0 to num frames
        
    }   // for i = 0 to num joints
    
    /*for( int i = 0; i < pAnimSequence->miNumFrames; i++ )
    {
        OUTPUT( "%s time = %.1f rot ( %f, %f, %f )\n",
               pAnimSequence->mapJoints[i]->mszName,
               pAnimSequence->mafTime[i],
               pAnimSequence->maRotationVec[i].fX,
               pAnimSequence->maRotationVec[i].fY,
               pAnimSequence->maRotationVec[i].fZ );
    }*/
    
    sortOnTime( pAnimSequence );
    
    /*for( int i = 0; i < pAnimSequence->miNumFrames; i++ )
    {
        OUTPUT( "%s time = %.1f rot ( %f, %f, %f )\n",
                pAnimSequence->mapJoints[i]->mszName,
                pAnimSequence->mafTime[i],
                pAnimSequence->maRotationVec[i].fX,
                pAnimSequence->maRotationVec[i].fY,
               pAnimSequence->maRotationVec[i].fZ );
    }
    
    for( int i = 0; i < pAnimSequence->miNumJoints; i++ )
    {
        OUTPUT( "%s\t( %d, %d )\n",
                pAnimSequence->mapUniqueJoints[i]->mszName,
                pAnimSequence->maiStartFrames[i],
                pAnimSequence->maiEndFrames[i] );
    }*/
}
Beispiel #4
0
int Game::on_frame(void) {
    // Handle OS events
    float delta_x = 0.0f;
    float delta_y = 0.0f;
    const SystemEvent* event = app_pop_event();
    while (event) {
        switch(event->type) {
            case kEventResize:
                _render->resize(event->data.resize.width, event->data.resize.height);
                printf("W: %d  H: %d\n", event->data.resize.width, event->data.resize.height);
                break;
            case kEventKeyDown:
                if(event->data.key == KEY_ESCAPE)
                    return 1;
                if(event->data.key == KEY_F1)
                    _render->toggle_debug_graphics();
                if(event->data.key == KEY_F2)
                    _render->toggle_deferred();
                break;
            case kEventMouseDown:
                if(event->data.mouse.button == MOUSE_LEFT)
                    app_lock_and_hide_cursor();
                debug_output("Mouse: %.0f %.0f\n", event->data.mouse.x, event->data.mouse.y);
                break;
            case kEventMouseUp:
                if(event->data.mouse.button == MOUSE_LEFT)
                    app_unlock_and_show_cursor();
                break;
            case kEventMouseMove:
                delta_x += event->data.mouse.x;
                delta_y += event->data.mouse.y;
                break;
            default:
                break;
        }
        event = app_pop_event();
    }

    // Beginning of frame stuff
    _delta_time = (float)timer_delta_time(&_timer);
    update_fps(&_fps, _delta_time);

    float3 xaxis = {1.0f, 0.0f, 0.0f};
    quaternion q = quaternionFromAxisAngle(&xaxis, _delta_time*0.15f);
    Transform t = _world.entity(_sun_id)->transform();
    t.orientation = quaternionMultiply(&q, &t.orientation);
    //_world.entity(_sun_id)->set_transform(t);
    if(quaternionGetZAxis(&t.orientation).y > 0.0f) {
        //_world.entity(_sun_id)->deactivate_component(kLightComponent);
    } else {
        //_world.entity(_sun_id)->activate_component(kLightComponent);
    }

    // Frame
    _control_camera(delta_x, delta_y);
    float4x4 view = TransformGetMatrix(&_camera);
    _render->set_3d_view_matrix(view);

    _world.update(_delta_time);

    _render->render();

    // End of frame stuff
    if(++_frame_count % 16 == 0) {
        debug_output("%.2fms (%.0f FPS)\n", get_frametime(&_fps), get_fps(&_fps));
    }
    return 0;
}
Beispiel #5
0
void Game::initialize(void) {

    timer_init(&_timer);
    _frame_count = 0;
    _render = Render::create();
    _render->initialize(app_get_window());

    _world.add_system(new RenderSystem, kRenderComponent);
    _world.add_system(new LightSystem, kLightComponent);
    RenderData::_render = _render;
    LightData::_render = _render;


    //srand((uint32_t)_timer.start_time);
    srand(42);

    // Texture loaders
    _resource_manager.add_handlers("jpg", Render::load_texture, Render::unload_texture, _render);
    _resource_manager.add_handlers("dds", Render::load_texture, Render::unload_texture, _render);
    _resource_manager.add_handlers("png", Render::load_texture, Render::unload_texture, _render);
    _resource_manager.add_handlers("tga", Render::load_texture, Render::unload_texture, _render);

    // File loaders
    _resource_manager.add_handlers("mesh", Render::load_mesh, Render::unload_mesh, _render);
    _resource_manager.add_handlers("obj", Render::load_mesh, Render::unload_mesh, _render);

    // Create some materials
    Material grass_material =
    {
        _resource_manager.get_resource("assets/grass.dds"),
        _resource_manager.get_resource("assets/grass_nrm.png"),
        {0},
        {0.0f, 0.0f, 0.0f},
        0.0f,
        0.0f
    };

    Material materials[3] =
    {
        {
            _resource_manager.get_resource("assets/metal.dds"),
            _resource_manager.get_resource("assets/metal_nrm.png"),
            _resource_manager.get_resource("assets/metal.dds"),
            {0.0f, 0.0f, 0.0f},
            200.0f,
            0.8f
        },
        {
            _resource_manager.get_resource("assets/brick.dds"),
            _resource_manager.get_resource("assets/brick_nrm.png"),
            0,
            {1.0f, 1.0f, 1.0f},
            4.0f,
            0.1f
        },
        {
            _resource_manager.get_resource("assets/wood.dds"),
            _resource_manager.get_resource("assets/wood_nrm.png"),
            0,
            {1.0f, 1.0f, 1.0f},
            8.0f,
            0.3f
        }
    };

    // Ground
    const VtxPosNormTex ground_vertices[] =
    {
        /* Top */
        { {-0.5f,  0.0f, -0.5f}, { 0.0f,  1.0f,  0.0f}, {0.0f, 10.0f} },
        { { 0.5f,  0.0f, -0.5f}, { 0.0f,  1.0f,  0.0f}, {10.0f, 10.0f} },
        { { 0.5f,  0.0f,  0.5f}, { 0.0f,  1.0f,  0.0f}, {10.0f, 0.0f} },
        { {-0.5f,  0.0f,  0.5f}, { 0.0f,  1.0f,  0.0f}, {0.0f, 0.0f} },
        /* Bottom */
        { {-0.5f,  0.0f, -0.5f}, { 0.0f,  -1.0f,  0.0f}, {0.0f, 10.0f} },
        { { 0.5f,  0.0f, -0.5f}, { 0.0f,  -1.0f,  0.0f}, {10.0f, 10.0f} },
        { { 0.5f,  0.0f,  0.5f}, { 0.0f,  -1.0f,  0.0f}, {10.0f, 0.0f} },
        { {-0.5f,  0.0f,  0.5f}, { 0.0f,  -1.0f,  0.0f}, {0.0f, 0.0f} },
    };
    const unsigned short ground_indices[] =
    {
        3,1,0,
        2,1,3,
        3,0,1,
        2,3,1,
    };
    assert(ground_indices && ground_vertices);

    Transform transform = TransformZero();
    transform.scale = 1.0f;
    transform.position.y = -100000.0f;
    transform.position.y = 0.0f;
    RenderData render_data = {0};
    //render_data.mesh = _render->create_mesh(ARRAYSIZE(ground_vertices), kVtxPosNormTex, ARRAYSIZE(ground_indices), sizeof(ground_indices[0]), ground_vertices, ground_indices);
    //render_data.mesh = _render->sphere_mesh();
    std::map<float3, VtxPosNormTex> m;
    std::vector<float3> verts;
    std::vector<VtxPosNormTex>  terrain_verts;
    std::vector<uint32_t>       terrain_indices;
    verts.reserve(1000000);
    terrain_verts.reserve(1000000);
    terrain_indices.reserve(1000000);
    const float size = 50.0f;
    float3 min = { -size, -size, -size };
    float3 max = {  size,  size,  size };
    //min = float3addScalar(&min,)
    timer_reset(&_timer);
    generate_terrain_points(terrain_func, min, max, 1.0f, verts);
    debug_output("Time: %f\tNum raw Vertices: %d\n", timer_delta_time(&_timer), verts.size());
    timer_reset(&_timer);
    smooth_terrain(verts, terrain_verts, terrain_indices);
    //generate_terrain(terrain_func, terrain_verts, terrain_indices);
    debug_output("time: %f, Num Terrain Vertices: %d\n", timer_delta_time(&_timer), terrain_verts.size());
    debug_output("Num Terrain indices: %d\n", terrain_indices.size());
    timer_reset(&_timer);
    render_data.mesh = _render->create_mesh((uint32_t)terrain_verts.size(), kVtxPosNormTex, (uint32_t)terrain_indices.size(), sizeof(uint32_t), terrain_verts.data(), terrain_indices.data());
    render_data.material = grass_material;

    EntityID id = _world.create_entity();
    _world.entity(id)->set_transform(transform)
                     ->add_component(RenderComponent(render_data));

    id = _world.create_entity();
    
    Material sky_material =
    {
        _resource_manager.get_resource("assets/sky.png"),
        _resource_manager.get_resource("assets/default_norm.png"),
        {0},
        {0.0f, 0.0f, 0.0f},
        0.0f,
        0.0f
    };
    render_data.material = sky_material;
    render_data.mesh = _render->sphere_mesh();
    transform = TransformZero();
    transform.scale = -100.0f;
    transform.scale = 1000.0f;
    _world.entity(id)->set_transform(transform)
                     ->add_component(RenderComponent(render_data));

    for(int ii=0; ii<32;++ii) {
        transform = TransformZero();
        transform.scale = _rand_float(0.5f, 5.0f);
        transform.position.x = _rand_float(-50.0f, 50.0f);
        transform.position.y = _rand_float(3.0f, 7.5f);
        transform.position.z = _rand_float(-50.0f, 50.0f);
        float3 axis = { _rand_float(-3.0f, 3.0f), _rand_float(-3.0f, 3.0f), _rand_float(-3.0f, 3.0f) };
        transform.orientation = quaternionFromAxisAngle(&axis, _rand_float(0.0f, kPi));
        switch(rand()%2) {
            case 0:
                render_data.mesh = _render->sphere_mesh();
                break;
            case 1:
                render_data.mesh = _render->cube_mesh();
                break;
        }
        int material = rand()%3;
        render_data.material = materials[material];
        id = _world.create_entity();
        _world.entity(id)->set_transform(transform)
                         ->add_component(RenderComponent(render_data));
    }

    Material house_material =
    {
        _resource_manager.get_resource("assets/house_diffuse.tga"),
        _resource_manager.get_resource("assets/house_normal.tga"),
        _resource_manager.get_resource("assets/house_spec.tga"),
        {0.0f, 0.0f, 0.0f},
        1.5f,
        0.06f
    };
    transform = TransformZero();
    transform.scale = 0.015f;
    transform.orientation = quaternionFromEuler(0.0f, DegToRad(-90.0f), 0.0f);

    render_data.mesh = _resource_manager.get_resource("assets/house_obj.obj");
    render_data.material = house_material;
    id = _world.create_entity();
    _world.entity(id)->set_transform(transform)
                     ->add_component(RenderComponent(render_data));

    // Add a "sun"
    Light light;
    light.pos.x = 0.0f;
    light.pos.y = 10.0f;
    light.pos.z = 0.0f;
    light.size = 250.0f;
    light.dir.x = 0.0f;
    light.dir.y = -1.0f;
    light.dir.z = 0.0f;
    light.color.x = 1.0f;
    light.color.y = 1.0f;
    light.color.z = 1.0f;
    light.inner_cos = 0.1f;
    light.type = kDirectionalLight;

    transform = TransformZero();
    transform.orientation = quaternionFromEuler(DegToRad(90.0f), DegToRad(45.0f), 0.0f);
    transform.position = light.pos;

    _sun_id = _world.create_entity();
    _world.entity(_sun_id)->set_transform(transform)
                          ->add_component(LightComponent(light));

    transform = TransformZero();
    for(int ii=1;ii<MAX_LIGHTS;++ii) {
        light.pos.x = _rand_float(-50.0f, 50.0f);
        light.pos.y = _rand_float(1.0f, 4.0f);
        light.pos.z = _rand_float(-50.0f, 50.0f);
        light.size = 3.0f;
        light.color.x = _rand_float(0.0f, 1.0f);
        light.color.y = _rand_float(0.0f, 1.0f);
        light.color.z = _rand_float(0.0f, 1.0f);
        light.type = kPointLight;

        transform.position = light.pos;
        id = _world.create_entity();
        _world.entity(id)->set_transform(transform)
                         ->add_component(LightComponent(light));
    }
}