hkResult HavokDisplayManager::updateGeometry(const hkMatrix4& transform, hkUlong id, int tag) { auto trans = hkTransform(); hkFloat32* matrix = nullptr; transform.get4x4ColumnMajor(matrix); trans.set4x4ColumnMajor(matrix); return updateGeometry(trans, id, tag); }
hkDemo::Result MirroredMotionDemo::stepDemo() { // Check user input { if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_1 )) { for ( int i = 0; i < 2; i++ ) { if (( m_control[i]->getEaseStatus() == hkaDefaultAnimationControl::EASING_IN ) || ( m_control[i]->getEaseStatus() == hkaDefaultAnimationControl::EASED_IN )) { m_control[i]->easeOut( .5f ); } else { m_control[i]->easeIn( .5f ); } } } if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_2 )) { m_wireframe = !m_wireframe; setGraphicsState( HKG_ENABLED_WIREFRAME, m_wireframe ); } if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_3 )) { m_drawSkin = !m_drawSkin; } if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_0 ) ) { m_useExtractedMotion = !m_useExtractedMotion; } if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_L1 ) ) { m_accumulatedMotion[0].setIdentity(); m_accumulatedMotion[1].setIdentity(); } if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_R1 ) ) { m_paused = !m_paused; if ( m_paused ) { m_timestep = 0; } else { m_timestep = 1.0f / 60.0f; } } } const int boneCount = m_skeleton->m_numBones; for ( int j = 0; j < 2; j++ ) { // Grab accumulated motion { hkQsTransform deltaMotion; deltaMotion.setIdentity(); m_skeletonInstance[j]->getDeltaReferenceFrame( m_timestep, deltaMotion ); m_accumulatedMotion[j].setMulEq( deltaMotion ); } // Advance the active animations m_skeletonInstance[j]->stepDeltaTime( m_timestep ); // Sample the active animations and combine into a single pose hkaPose pose (m_skeleton); m_skeletonInstance[j]->sampleAndCombineAnimations( pose.accessUnsyncedPoseLocalSpace().begin(), pose.getFloatSlotValues().begin() ); hkReal separation = m_separation * hkReal( 2*j-1 ); hkQsTransform Q( hkQsTransform::IDENTITY ); Q.m_translation.set( separation, 0, 0 ); if ( m_useExtractedMotion ) { Q.setMulEq( m_accumulatedMotion[j] ); } pose.syncModelSpace(); AnimationUtils::drawPose( pose, Q ); // Test if the skin is to be drawn if ( !m_drawSkin ) { Q.m_translation( 2 ) -= 2.0f * m_separation; } // Construct the composite world transform hkLocalArray<hkTransform> compositeWorldInverse( boneCount ); compositeWorldInverse.setSize( boneCount ); const hkArray<hkQsTransform>& poseModelSpace = pose.getSyncedPoseModelSpace(); // Skin the meshes for (int i=0; i < m_numSkinBindings[j]; i++) { // assumes either a straight map (null map) or a single one (1 palette) hkInt16* usedBones = m_skinBindings[j][i]->m_mappings? m_skinBindings[j][i]->m_mappings[0].m_mapping : HK_NULL; int numUsedBones = usedBones? m_skinBindings[j][i]->m_mappings[0].m_numMapping : boneCount; // Multiply through by the bind pose inverse world inverse matrices for (int p=0; p < numUsedBones; p++) { int boneIndex = usedBones? usedBones[p] : p; hkTransform tWorld; poseModelSpace[ boneIndex ].copyToTransform(tWorld); compositeWorldInverse[p].setMul( tWorld, m_skinBindings[j][i]->m_boneFromSkinMeshTransforms[ boneIndex ] ); } AnimationUtils::skinMesh( *m_skinBindings[j][i]->m_mesh, hkTransform( Q.m_rotation, hkVector4( Q.m_translation(0), Q.m_translation(1), Q.m_translation(2), 1 ) ), compositeWorldInverse.begin(), *m_env->m_sceneConverter ); } // Move the attachments { HK_ALIGN(float f[16], 16); for (int a=0; a < m_numAttachments[j]; a++) { if (m_attachmentObjects[j][a]) { hkaBoneAttachment* ba = m_attachments[j][a]; hkQsTransform modelFromBone = pose.getBoneModelSpace( ba->m_boneIndex ); hkQsTransform worldFromBoneQs; worldFromBoneQs.setMul( Q, modelFromBone ); worldFromBoneQs.get4x4ColumnMajor(f); hkMatrix4 worldFromBone; worldFromBone.set4x4ColumnMajor(f); hkMatrix4 worldFromAttachment; worldFromAttachment.setMul(worldFromBone, ba->m_boneFromAttachment); m_env->m_sceneConverter->updateAttachment(m_attachmentObjects[j][a], worldFromAttachment); } } } } return hkDemo::DEMO_OK; }