void LLTemplateMessageReader::getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum) { LLVector3 vec; getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum); if( vec.isFinite() ) { q.unpackFromVector3( vec ); } else { llwarns << "non-finite in getQuatFast " << block << " " << var << llendl; q.loadIdentity(); } }
// writes contents to datapacker BOOL LLBVHLoader::serialize(LLDataPacker& dp) { JointVector::iterator ji; KeyVector::iterator ki; F32 time; // count number of non-ignored joints S32 numJoints = 0; for (ji=mJoints.begin(); ji!=mJoints.end(); ++ji) { Joint *joint = *ji; if ( ! joint->mIgnore ) numJoints++; } // print header dp.packU16(KEYFRAME_MOTION_VERSION, "version"); dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); dp.packS32(mPriority, "base_priority"); dp.packF32(mDuration, "duration"); dp.packString(mEmoteName, "emote_name"); dp.packF32(mLoopInPoint, "loop_in_point"); dp.packF32(mLoopOutPoint, "loop_out_point"); dp.packS32(mLoop, "loop"); dp.packF32(mEaseIn, "ease_in_duration"); dp.packF32(mEaseOut, "ease_out_duration"); dp.packU32(mHand, "hand_pose"); dp.packU32(numJoints, "num_joints"); for ( ji = mJoints.begin(); ji != mJoints.end(); ++ji ) { Joint *joint = *ji; // if ignored, skip it if ( joint->mIgnore ) continue; LLQuaternion first_frame_rot; LLQuaternion fixup_rot; dp.packString(joint->mOutName, "joint_name"); dp.packS32(joint->mPriority, "joint_priority"); // compute coordinate frame rotation LLQuaternion frameRot( joint->mFrameMatrix ); LLQuaternion frameRotInv = ~frameRot; LLQuaternion offsetRot( joint->mOffsetMatrix ); // find mergechild and mergeparent joints, if specified LLQuaternion mergeParentRot; LLQuaternion mergeChildRot; Joint *mergeParent = NULL; Joint *mergeChild = NULL; JointVector::iterator mji; for (mji=mJoints.begin(); mji!=mJoints.end(); ++mji) { Joint *mjoint = *mji; if ( !joint->mMergeParentName.empty() && (mjoint->mName == joint->mMergeParentName) ) { mergeParent = *mji; } if ( !joint->mMergeChildName.empty() && (mjoint->mName == joint->mMergeChildName) ) { mergeChild = *mji; } } dp.packS32(joint->mNumRotKeys, "num_rot_keys"); LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); S32 outcount = 0; S32 frame = 1; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { if ((frame == 1) && joint->mRelativeRotationKey) { first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); fixup_rot.shortestArc(LLVector3::z_axis * first_frame_rot * frameRot, LLVector3::z_axis); } if (ki->mIgnoreRot) { frame++; continue; } time = (F32)frame * mFrameTime; if (mergeParent) { mergeParentRot = mayaQ( mergeParent->mKeys[frame-1].mRot[0], mergeParent->mKeys[frame-1].mRot[1], mergeParent->mKeys[frame-1].mRot[2], bvhStringToOrder(mergeParent->mOrder) ); LLQuaternion parentFrameRot( mergeParent->mFrameMatrix ); LLQuaternion parentOffsetRot( mergeParent->mOffsetMatrix ); mergeParentRot = ~parentFrameRot * mergeParentRot * parentFrameRot * parentOffsetRot; } else { mergeParentRot.loadIdentity(); } if (mergeChild) { mergeChildRot = mayaQ( mergeChild->mKeys[frame-1].mRot[0], mergeChild->mKeys[frame-1].mRot[1], mergeChild->mKeys[frame-1].mRot[2], bvhStringToOrder(mergeChild->mOrder) ); LLQuaternion childFrameRot( mergeChild->mFrameMatrix ); LLQuaternion childOffsetRot( mergeChild->mOffsetMatrix ); mergeChildRot = ~childFrameRot * mergeChildRot * childFrameRot * childOffsetRot; } else { mergeChildRot.loadIdentity(); } LLQuaternion inRot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); LLQuaternion outRot = frameRotInv* mergeChildRot * inRot * mergeParentRot * ~first_frame_rot * frameRot * offsetRot; U16 time_short = F32_to_U16(time, 0.f, mDuration); dp.packU16(time_short, "time"); U16 x, y, z; LLVector3 rot_vec = outRot.packToVector3(); rot_vec.quantize16(-1.f, 1.f, -1.f, 1.f); x = F32_to_U16(rot_vec.mV[VX], -1.f, 1.f); y = F32_to_U16(rot_vec.mV[VY], -1.f, 1.f); z = F32_to_U16(rot_vec.mV[VZ], -1.f, 1.f); dp.packU16(x, "rot_angle_x"); dp.packU16(y, "rot_angle_y"); dp.packU16(z, "rot_angle_z"); outcount++; frame++; } // output position keys (only for 1st joint) if ( ji == mJoints.begin() && !joint->mIgnorePositions ) { dp.packS32(joint->mNumPosKeys, "num_pos_keys"); LLVector3 relPos = joint->mRelativePosition; LLVector3 relKey; frame = 1; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { if ((frame == 1) && joint->mRelativePositionKey) { relKey.setVec(ki->mPos); } if (ki->mIgnorePos) { frame++; continue; } time = (F32)frame * mFrameTime; LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot; LLVector3 outPos = inPos * frameRot * offsetRot; outPos *= INCHES_TO_METERS; outPos -= relPos; outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); U16 time_short = F32_to_U16(time, 0.f, mDuration); dp.packU16(time_short, "time"); U16 x, y, z; outPos.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); x = F32_to_U16(outPos.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); y = F32_to_U16(outPos.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); z = F32_to_U16(outPos.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); dp.packU16(x, "pos_x"); dp.packU16(y, "pos_y"); dp.packU16(z, "pos_z"); frame++; } } else { dp.packS32(0, "num_pos_keys"); } } S32 num_constraints = (S32)mConstraints.size(); dp.packS32(num_constraints, "num_constraints"); for (ConstraintVector::iterator constraint_it = mConstraints.begin(); constraint_it != mConstraints.end(); constraint_it++) { U8 byte = constraint_it->mChainLength; dp.packU8(byte, "chain_lenght"); byte = constraint_it->mConstraintType; dp.packU8(byte, "constraint_type"); dp.packBinaryDataFixed((U8*)constraint_it->mSourceJointName, 16, "source_volume"); dp.packVector3(constraint_it->mSourceOffset, "source_offset"); dp.packBinaryDataFixed((U8*)constraint_it->mTargetJointName, 16, "target_volume"); dp.packVector3(constraint_it->mTargetOffset, "target_offset"); dp.packVector3(constraint_it->mTargetDir, "target_dir"); dp.packF32(constraint_it->mEaseInStart, "ease_in_start"); dp.packF32(constraint_it->mEaseInStop, "ease_in_stop"); dp.packF32(constraint_it->mEaseOutStart, "ease_out_start"); dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop"); } return TRUE; }