// // 设置世界朝向 // VOID CSceneNode::SetWorldOrientation(FLOAT x, FLOAT y, FLOAT z, FLOAT w) { if (m_pParentNode) { // 算法: // worldOrientation = localOrientation * parentOrientation // localOrientation = worldOrientation * parentOrientationInv QUAT parentOrientationInv; QuatInverse(&parentOrientationInv, m_pParentNode->GetWorldOrientation()); QUAT localOrientation; QUAT worldOrientation; QuatSet(&worldOrientation, x, y, z, w); QuatMul(&localOrientation, &worldOrientation, &parentOrientationInv); x = localOrientation[0]; y = localOrientation[1]; z = localOrientation[2]; w = localOrientation[3]; } SetLocalOrientation(x, y, z, w); }
Vec3 TurretComponent::AbsoluteAnglesToRelativeAngles(const Vec3 absoluteAngles) const { quat_t torsoRotation; quat_t absoluteRotation; quat_t relativeRotation; vec3_t relativeAngles; AnglesToQuat(TorsoAngles().Data(), torsoRotation); AnglesToQuat(absoluteAngles.Data(), absoluteRotation); // This is the inverse of RelativeAnglesToAbsoluteAngles. See the comment there for details. quat_t inverseTorsoOrientation; QuatCopy(torsoRotation, inverseTorsoOrientation); QuatInverse(inverseTorsoOrientation); QuatMultiply(inverseTorsoOrientation, absoluteRotation, relativeRotation); QuatToAngles(relativeRotation, relativeAngles); /*turretLogger.Debug("AbsoluteAnglesToRelativeAngles: %s → %s. Torso angles: %s.", Utility::Print(absoluteAngles), Utility::Print(Vec3::Load(relativeAngles)), TorsoAngles() );*/ return Vec3::Load(relativeAngles); }
bool AnimDelta::LoadData(clientInfo_t* ci) { char newModelName[ MAX_QPATH ]; // special handling for human_(naked|light|medium) if ( !Q_stricmp( ci->modelName, "human_naked" ) || !Q_stricmp( ci->modelName, "human_light" ) || !Q_stricmp( ci->modelName, "human_medium" ) ) { Q_strncpyz( newModelName, "human_nobsuit_common", sizeof( newModelName ) ); } else { Q_strncpyz( newModelName, ci->modelName, sizeof( newModelName ) ); } refSkeleton_t base; refSkeleton_t delta; for ( int i = WP_NONE + 1; i < WP_NUM_WEAPONS; ++i ) { int handle = LoadDeltaAnimation( static_cast<weapon_t>( i ), newModelName, ci->iqm ); if ( !handle ) continue; Log::Debug("Loaded delta for %s %s", newModelName, BG_Weapon( i )->humanName); trap_R_BuildSkeleton( &delta, handle, 1, 1, 0, false ); // Derive the delta from the base stand animation. trap_R_BuildSkeleton( &base, ci->animations[ TORSO_STAND ].handle, 1, 1, 0, false ); auto ret = deltas_.insert( std::make_pair( i, std::vector<delta_t>( boneIndicies_.size() ) ) ); auto& weaponDeltas = ret.first->second; for ( size_t j = 0; j < boneIndicies_.size(); ++j ) { VectorSubtract( delta.bones[ boneIndicies_[ j ] ].t.trans, base.bones[ boneIndicies_[ j ] ].t.trans, weaponDeltas[ j ].delta ); QuatInverse( base.bones[ boneIndicies_[ j ] ].t.rot ); QuatMultiply( base.bones[ boneIndicies_[ j ] ].t.rot, delta.bones[ boneIndicies_[ j ] ].t.rot, weaponDeltas[ j ].rot ); } } return true; }