// Quatizations void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) { F32 x = mV[VX]; F32 y = mV[VY]; F32 z = mV[VZ]; x = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); y = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); z = U16_to_F32(F32_to_U16(z, lowerz, upperz), lowerz, upperz); mV[VX] = x; mV[VY] = y; mV[VZ] = z; }
void v3math_object::test<34>() { F32 x = 10.f, y = 20.f, z = -15.f; F32 x1, y1, z1; F32 lowerxy = 0.f, upperxy = 1.0f, lowerz = -1.0f, upperz = 1.f; LLVector3 vec3(x,y,z); vec3.quantize16(lowerxy,upperxy,lowerz,upperz); x1 = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); y1 = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); z1 = U16_to_F32(F32_to_U16(z, lowerz, upperz), lowerz, upperz); ensure("1:quantize16: Fail ", is_approx_equal(x1, vec3.mV[VX]) && is_approx_equal(y1, vec3.mV[VY]) && is_approx_equal(z1, vec3.mV[VZ])); LLVector3 vec3a(x,y,z); vec3a.quantize8(lowerxy,upperxy,lowerz,upperz); x1 = U8_to_F32(F32_to_U8(x, lowerxy, upperxy), lowerxy, upperxy); y1 = U8_to_F32(F32_to_U8(y, lowerxy, upperxy), lowerxy, upperxy); z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz); ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ])); }
// 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_length"); 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; }