LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) { LLCamera ret = camera; LLXformMatrix* mat = mDrawable->getXform(); LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); LLVector3 delta = ret.getOrigin() - center; LLQuaternion rot = ~mat->getRotation(); delta *= rot; LLVector3 lookAt = ret.getAtAxis(); LLVector3 up_axis = ret.getUpAxis(); LLVector3 left_axis = ret.getLeftAxis(); lookAt *= rot; up_axis *= rot; left_axis *= rot; if (!delta.isFinite()) { delta.clearVec(); } ret.setOrigin(delta); ret.setAxes(lookAt, left_axis, up_axis); return ret; }
LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 box_side, bool hud) : mHud(hud) { mVOPartGroupp = NULL; mUniformParticles = TRUE; mRegionp = LLWorld::getInstance()->getRegionFromPosAgent(center_agent); llassert_always(center_agent.isFinite()); if (!mRegionp) { //llwarns << "No region at position, using agent region!" << llendl; mRegionp = gAgent.getRegion(); } mCenterAgent = center_agent; mBoxRadius = F_SQRT3*box_side*0.5f; if (mHud) { mVOPartGroupp = (LLVOPartGroup *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_HUD_PART_GROUP, getRegion()); } else { mVOPartGroupp = (LLVOPartGroup *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_PART_GROUP, getRegion()); } mVOPartGroupp->setViewerPartGroup(this); mVOPartGroupp->setPositionAgent(getCenterAgent()); mBoxSide = box_side; F32 scale = box_side * 0.5f; mVOPartGroupp->setScale(LLVector3(scale,scale,scale)); //gPipeline.addObject(mVOPartGroupp); gPipeline.createObject(mVOPartGroupp); LLSpatialGroup* group = mVOPartGroupp->mDrawable->getSpatialGroup(); if (group != NULL) { LLVector3 center(group->mOctreeNode->getCenter().getF32ptr()); LLVector3 size(group->mOctreeNode->getSize().getF32ptr()); size += LLVector3(0.01f, 0.01f, 0.01f); mMinObjPos = center - size; mMaxObjPos = center + size; } else { // Not sure what else to set the obj bounds to when the drawable has no spatial group. LLVector3 extents(mBoxRadius, mBoxRadius, mBoxRadius); mMinObjPos = center_agent - extents; mMaxObjPos = center_agent + extents; } mSkippedTime = 0.f; static U32 id_seed = 0; mID = ++id_seed; }
// at and up_direction are presumed to be normalized void LLCoordFrame::lookDir(const LLVector3 &at, const LLVector3 &up_direction) { // Make sure 'at' and 'up_direction' are not parallel // and that neither are zero-length vectors LLVector3 left(up_direction % at); if (left.isNull()) { //tweak lookat pos so we don't get a degenerate matrix LLVector3 tempat(at[VX] + 0.01f, at[VY], at[VZ]); tempat.normVec(); left = (up_direction % tempat); } left.normVec(); LLVector3 up = at % left; if (at.isFinite() && left.isFinite() && up.isFinite()) { setAxes(at, left, up); } }
void LLTemplateMessageReader::getVector3(const char *block, const char *var, LLVector3 &v, S32 blocknum ) { getData(block, var, &v.mV[0], sizeof(v.mV), blocknum); if( !v.isFinite() ) { llwarns << "non-finite in getVector3Fast " << block << " " << var << llendl; v.zeroVec(); } }
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(); } }
//----------------------------------------------------------------------------- // LLEditingMotion::onUpdate() //----------------------------------------------------------------------------- BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) { LLVector3 focus_pt; LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint"); BOOL result = TRUE; if (!pointAtPt) { focus_pt = mLastSelectPt; result = FALSE; } else { focus_pt = *pointAtPt; mLastSelectPt = focus_pt; } focus_pt += mCharacter->getCharacterPosition(); // propagate joint positions to kinematic chain mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); // propagate current joint rotations to kinematic chain mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); // update target position from character LLVector3 target = focus_pt - mParentJoint.getPosition(); F32 target_dist = target.normVec(); LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f); edit_plane_normal.normVec(); edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation()); F32 dot = edit_plane_normal * target; if (dot < 0.f) { target = target + (edit_plane_normal * (dot * 2.f)); target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f); target.normVec(); } target = target * target_dist; if (!target.isFinite()) { LL_WARNS() << "Non finite target in editing motion with target distance of " << target_dist << " and focus point " << focus_pt << " and pointAtPt: "; if (pointAtPt) { LL_CONT << *pointAtPt; } else { LL_CONT << "NULL"; } LL_CONT << LL_ENDL; target.setVec(1.f, 1.f, 1.f); } mTarget.setPosition( target + mParentJoint.getPosition()); // LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; // update the ikSolver if (!mTarget.getPosition().isExactlyZero()) { LLQuaternion shoulderRot = mShoulderJoint.getRotation(); LLQuaternion elbowRot = mElbowJoint.getRotation(); mIKSolver.solve(); // use blending... F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE); shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot); elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); // now put blended values back into joints llassert(shoulderRot.isFinite()); llassert(elbowRot.isFinite()); mShoulderState->setRotation(shoulderRot); mElbowState->setRotation(elbowRot); mWristState->setRotation(LLQuaternion::DEFAULT); } mCharacter->setAnimationData("Hand Pose", &sHandPose); mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority); return result; }