virtual void operator()( osg::Node *node, osg::NodeVisitor* nv ) { Transform trans; mPositionalLight->GetTransform( trans, Transformable::ABS_CS ); osg::Matrix absMatrix; Transformable::GetAbsoluteMatrix( mPositionalLight->GetMatrixNode(), absMatrix ); osg::Light* osgLight = mPositionalLight->GetLightSource()->getLight(); float x, y, z, h, p, r; trans.Get( x, y, z, h, p, r); osg::Vec4 position( x, y, z, 1.0f ); //force positional lighting with w of 1.0f osgLight->setPosition( position * osg::Matrix::inverse( absMatrix ) ); //note: the actual direction is handled by the Transformable's MatrixNode. //this just tells the Light that it has a direction. osgLight->setDirection( osg::Vec3( 0.0f, 1.0f, 0.0f ) ); traverse( node, nv ); }
/** * Message handler callback. * * @param data the message data */ void CadworkFlyMotionModel::OnMessage(MessageData* data) { Transformable *target = GetTarget(); if (target != NULL && IsEnabled() && (data->message == dtCore::System::MESSAGE_POST_EVENT_TRAVERSAL/*MESSAGE_PRE_FRAME*/) && // don't move if paused & using simtime for speed (since simtime will be 0 if paused) (!HasOption(OPTION_USE_SIMTIME_FOR_SPEED) || !System::GetInstance().GetPause())) { if(IsMouseGrabbed()) { // Get the time change (sim time or real time) double delta = GetTimeDelta(data); Transform transform; GetTarget()->GetTransform(transform); osg::Vec3 xyz, hpr; transform.Get(xyz, hpr); // rotation bool rotationChanged = false; if(!HasOption(OPTION_REQUIRE_MOUSE_DOWN)) { hpr = Rotate(hpr, delta, rotationChanged); if (rotationChanged) { transform.SetRotation(hpr); } } // translation bool translationChanged = false; xyz = Translate(xyz, delta, translationChanged); if (translationChanged) { transform.SetTranslation(xyz); } // homing if(mHomingButton->GetState()) { GoToHomePosition(); } // finalize changes if (rotationChanged || translationChanged) { GetTarget()->SetTransform(transform); } } // release cursor //if(mCursorReleaseButton->GetState()) //{ // ReleaseMouse(); //} ////grab cursor //if(mCursorGrabButton->GetState()) //{ // GrabMouse(); //} /** * Now some serious work. Below begins the 'animation' of the smooth camera * movement while zooming (by mouse wheel). First part is rotation when refocusing * and the second part is changing distance. Default animation duration is 0.4s. */ if(mAnimData.isAnimating()) { double f = (System::GetInstance().GetSimulationTime() - mAnimData._startTime) / mAnimData._motion->getDuration(); f = f<0 ? 0 : f > 1 ? 1 : f; //clamp f into a <0,1> range float t; mAnimData._motion->getValueInNormalizedRange(f,t); //gets normalized <0,1> linear value f and turns it into non-lineary interpolated value t also normalized (the function is defined in MathMotionTemplate constructor in AnimationData definition) /** handle amooth zooming */ if(mAnimData._isZooming) { float newdist; newdist = t * (mAnimData._toDist - mAnimData._fromDist) + mAnimData._fromDist; Transform trans; target->GetTransform(trans); if(mAnimData._isRotating) //rotating while zooming { osg::Vec3 xyz,hpr,oldhpr; trans.Get(xyz,oldhpr); trans.Set(xyz,mAnimData._toRotation); trans.Get(xyz,hpr); float deltaDist = mTmpPrevDistance - newdist; /*if (newdist < MIN_DISTANCE && (mAnimData._toDist < mAnimData._fromDist)) { deltaDist = MIN_DISTANCE - GetDistance(); }*/ osg::Vec3 translation (0.0f, deltaDist, 0.0f); osg::Matrix mat; dtUtil::MatrixUtil::HprToMatrix(mat, hpr); translation = osg::Matrix::transform3x3(translation, mat); xyz += translation; if(mDistanceShouldChange) mTmpPrevDistance = newdist;//(mNewCenter-xyz).length(); trans.Set(xyz,oldhpr); } else{ //zooming only osg::Vec3 xyz,hpr; trans.Get(xyz,hpr); float deltaDist = mTmpPrevDistance - newdist; osg::Vec3 translation (0.0f, deltaDist, 0.0f); osg::Matrix mat; dtUtil::MatrixUtil::HprToMatrix(mat, hpr); translation = osg::Matrix::transform3x3(translation, mat); xyz += translation; if(mDistanceShouldChange) mTmpPrevDistance = newdist; trans.Set(xyz,hpr); } target->SetTransform(trans); } if(mAnimData._isRotating) { osg::Quat newRotation; newRotation.slerp(f, mAnimData._fromRotation, mAnimData._toRotation); if(f>=1.) { newRotation = mAnimData._toRotation; } Transform trans; target->GetTransform(trans); osg::Vec3 xyz; trans.GetTranslation(xyz); trans.Set(xyz,newRotation); target->SetTransform(trans); /** cursor interpolation */ if(mAnimData._interpolateCursor){ float newx, newy; float x,y; mMouse->GetPosition(x,y); //get current position in case the user is moving the mouse float oldx, oldy; oldx = mAnimData._previousPhase * (mAnimData._toCursor.x() - mAnimData._fromCursor.x()); oldy = mAnimData._previousPhase * (mAnimData._toCursor.y() - mAnimData._fromCursor.y()); newx = f * (mAnimData._toCursor.x() - mAnimData._fromCursor.x());// + x/*mAnimData._fromCursor.x()*/; newy = f * (mAnimData._toCursor.y() - mAnimData._fromCursor.y());// + y/*mAnimData._fromCursor.y()*/; float truex, truey; truex = newx - oldx + x; truey = newy - oldy + y; mMouse->SetPosition(truex,truey); } } mAnimData._previousPhase = f; if(f>=1.) { /*Transform trans; target->GetTransform(trans); trans.Set(trans.GetTranslation(), mAnimData._toRotation); target->SetTransform(trans);*/ mAnimData.reset(); //clear all data, set all flags on false => not animating anymore } } } }
/** * Called when an axis' state has changed. * * @param axis the changed axis * @param oldState the old state of the axis * @param newState the new state of the axis * @param delta a delta value indicating stateless motion */ bool OrbitMotionModel::AxisStateChanged(const Axis* axis, double oldState, double newState, double delta) { delta = delta * (double)mMouseSensitivity; if (GetTarget() != 0 && IsEnabled()) { Transform transform; GetTarget()->GetTransform(transform); osg::Vec3 xyz, hpr; transform.Get(xyz, hpr); if (axis == mAzimuthAxis.get()) { osg::Vec3 focus(0.0f, mDistance, 0.0f); osg::Matrix mat; transform.Get(mat); dtUtil::MatrixUtil::TransformVec3(focus, mat); hpr[0] -= float(delta * mAngularRate); osg::Vec3 offset(0.0f, -mDistance, 0.0f); dtUtil::MatrixUtil::PositionAndHprToMatrix(mat, focus, hpr); dtUtil::MatrixUtil::TransformVec3(xyz, offset, mat); } else if (axis == mElevationAxis.get()) { osg::Vec3 focus( 0.0f, mDistance, 0.0f ); osg::Matrix mat; transform.Get(mat); dtUtil::MatrixUtil::TransformVec3(focus, mat); hpr[1] += float(delta * mAngularRate); if (hpr[1] < mMinElevationLimit) { hpr[1] = mMinElevationLimit; } else if (hpr[1] > mMaxElevationLimit) { hpr[1] = mMaxElevationLimit; } osg::Vec3 offset ( 0.0f, -mDistance, 0.0f ); dtUtil::MatrixUtil::PositionAndHprToMatrix(mat, focus, hpr); dtUtil::MatrixUtil::TransformVec3(xyz, offset, mat); } else if (axis == mDistanceAxis.get()) { float distDelta = -float(delta * mDistance * mLinearRate); if (mDistance + distDelta < 1.0f) { distDelta = 1.0f - mDistance; } osg::Vec3 translation (0.0f, -distDelta, 0.0f); osg::Matrix mat; dtUtil::MatrixUtil::HprToMatrix(mat, hpr); translation = osg::Matrix::transform3x3(translation, mat); xyz += translation; mDistance += distDelta; } else if (axis == mLeftRightTranslationAxis.get()) { osg::Vec3 translation ( -float(delta * mDistance * mLinearRate), 0.0f, 0.0f ); osg::Matrix mat; dtUtil::MatrixUtil::HprToMatrix(mat, hpr); translation = osg::Matrix::transform3x3(translation, mat); xyz += translation; } else if (axis == mUpDownTranslationAxis.get()) { osg::Vec3 translation ( 0.0f, 0.0f, -float(delta * mDistance * mLinearRate) ); osg::Matrix mat; dtUtil::MatrixUtil::HprToMatrix(mat, hpr); translation = osg::Matrix::transform3x3(translation, mat); xyz += translation; } transform.Set(xyz, hpr); GetTarget()->SetTransform(transform); return true; } return false; }