void tilt_compensate(float in[4], float tilt[4], float out[4]){ float tiltConjugate[4]; float tempQ[4]; quaternionConjugate(tilt, tiltConjugate); quaternionMultiply(in, tiltConjugate, tempQ); quaternionMultiply(tilt, tempQ, out); }
void tilt_compensate(quaternion_t magQ, quaternion_t unfusedQ) { quaternion_t unfusedConjugateQ; quaternion_t tempQ; quaternionConjugate(unfusedQ, unfusedConjugateQ); quaternionMultiply(magQ, unfusedConjugateQ, tempQ); quaternionMultiply(unfusedQ, tempQ, magQ); }
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); }
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] ); }*/ }
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; }