/*************************************************************** * Function: updateVSParameters() ***************************************************************/ void DSVirtualEarth::updateVSParameters(const Vec3 &viewDir, const Vec3 &viewPos) { if (!mVirtualScenicHandler) return; /* compute sun direction in world space: apply transforms resulted by viewer's orientation change, guarantee that from the viewer's position, the virtual earth is always half illuminated. */ Matrixd baserotMat; baserotMat.makeRotate(Vec3(0, 1, 0), gDesignStateFrontVect); Vec3 sunDirWorld = (CAVEAnimationModeler::ANIMVirtualEarthLightDir()) * baserotMat; StateSet *stateset = mEarthGeode->getStateSet(); if (stateset) { Uniform *lightposUniform = stateset->getOrCreateUniform("LightPos", Uniform::FLOAT_VEC4); lightposUniform->set(Vec4(sunDirWorld, 0.0)); } /* compute matrix combination that transforms a vector from shader space into world space */ Matrixd latiMat; latiMat.makeRotate(mLati / 180.f * M_PI, Vec3(0, 1, 0)); Matrixd equatorMat; equatorMat.makeRotate((mTimeOffset / 12.f + mLongi / 180.f) * M_PI, Vec3(0, 0, 1)); Matrixd tiltaxisMat = mTiltAxisTrans->getMatrix(); Matrixd eclipticMat = mEclipticTrans->getMatrix(); Matrixd transMat = mUnitspaceMat * latiMat * equatorMat * tiltaxisMat * eclipticMat * baserotMat; /* updata environment rendering by passing parameters to VirtualScenicHandler */ mVirtualScenicHandler->updateVSParameters(transMat, sunDirWorld, viewDir, viewPos); }
/*************************************************************** * Function: setEquatorPos() ***************************************************************/ void DSVirtualEarth::setEquatorPos(const float &t) { /* get virtual time based on longi/lati/date */ float vtime = (mLongi + 180.f) / 15.f + 12 + (mDate - gDateOffset) * 24 + mTimeOffset; vtime = vtime - (int)(vtime / 24.f) * 24.f; mTimeOffset += (t - vtime); Matrixd rotMat; rotMat.makeRotate(mTimeOffset / 12.f * M_PI, Vec3(0, 0, 1)); mEquatorTrans->setMatrix(rotMat); }
Vec3d CameraController::calcUp(const Vec3d& oldSight, const Vec3d& newSight, const Vec3d& oldUp) { Vec3d v1 = oldSight, v2 = newSight; v1.normalize(); v2.normalize(); Matrixd mat; mat.makeRotate(v1, v2); Vec3d newUp = oldUp * mat; return newUp; }
/*************************************************************** * Function: updateUnitGridSizeInfo() ***************************************************************/ void CAVEGroupReferenceAxis::updateUnitGridSizeInfo(const string &infoStr) { if (mTextEnabledFlag) { mGridInfoText->setText("Unit size = " + infoStr); mGridInfoText->setPosition(Vec3(0, -gCharSize, -gCharSize)); /* align the text to viewer's front direction */ Matrixd rotMat; rotMat.makeRotate(Vec3(0, 1, 0), gPointerDir); mGridInfoTextTrans->setMatrix(Matrixd(rotMat)); } }
//Constructor DSVirtualEarth::DSVirtualEarth(): mState(SET_NULL), mLongi(-117.17f), mLati(32.75f), mTime(8.f), mDate(0.551f), mTimeOffset(0.0f), mTimeLapseSpeed(0.0f) { mEclipticTrans = new MatrixTransform(); mTiltAxisTrans = new MatrixTransform(); mEquatorTrans = new MatrixTransform(); mEclipticSwitch = new Switch; mEquatorSwitch = new Switch; addChild(mEclipticTrans); mEclipticTrans->addChild(mEclipticSwitch); mEclipticTrans->addChild(mTiltAxisTrans); mTiltAxisTrans->addChild(mEquatorTrans); mEquatorTrans->addChild(mEquatorSwitch); Matrixd tiltaxisMat; float angle = 23.5f / 180.0f * M_PI; tiltaxisMat.makeRotate(Vec3(0, 0, 1), Vec3(sin(angle), 0, cos(angle))); mTiltAxisTrans->setMatrix(tiltaxisMat); /* Level 1: Seasons map and Ecliptic ruler */ Switch *thisPtr = dynamic_cast <Switch*> (this); CAVEAnimationModeler::ANIMLoadVirtualEarthReferenceLevel(&thisPtr, &mSeasonsMapGeode); /* Level 2: Wired sphere, Meridian ruler, earth axis, equator ruler*/ CAVEAnimationModeler::ANIMLoadVirtualEarthEclipticLevel(&mEclipticSwitch); /* Level 3: Wired sphere, fwd & bwd animation, pin indicator, fixed pin trans */ CAVEAnimationModeler::ANIMLoadVirtualEarthEquatorLevel(&mEquatorSwitch, &mEarthGeode, &mPATransFwd, &mPATransBwd, &mFixedPinIndicatorTrans, &mFixedPinTrans); /* set initial geographical info/ time / date */ setFixedPinPos(mLongi, mLati); setEclipticPos(mDate); setEquatorPos(mTime); setPinIndicatorPos(mLongi); setAllChildrenOff(); /* transform matrix that flip shader world plain to vertical earth model */ mUnitspaceMat = Matrixd::inverse(Matrixd( 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)); /* create instance of intersector */ mDSIntersector = new DSIntersector(); mTrackballController = new TrackballController(); mVirtualScenicHandler = NULL; }
/*************************************************************** * Function: updateGridUnits() ***************************************************************/ void CAVEGroupEditGeodeWireframe::updateGridUnits(const float &gridUnitLegnth, const float &gridUnitAngle, const float &gridUnitScale) { /* update 'Move' matrix transform wireframes */ unsigned int numMoveChildren = mMoveSwitch->getNumChildren(); if (numMoveChildren > 1) { Vec3 gridOffsetVect = Vec3(0, 0, 0); if (mMoveSVect.x() > 0) gridOffsetVect = Vec3(gridUnitLegnth, 0, 0); else if (mMoveSVect.x() < 0) gridOffsetVect = Vec3(-gridUnitLegnth, 0, 0); else if (mMoveSVect.y() > 0) gridOffsetVect = Vec3(0, gridUnitLegnth, 0); else if (mMoveSVect.y() < 0) gridOffsetVect = Vec3(0, -gridUnitLegnth, 0); else if (mMoveSVect.z() > 0) gridOffsetVect = Vec3(0, 0, gridUnitLegnth); else if (mMoveSVect.z() < 0) gridOffsetVect = Vec3(0, 0, -gridUnitLegnth); for (int i = 0; i < numMoveChildren; i++) { Matrixd transMat; transMat.makeTranslate(gridOffsetVect * i); mMoveMatTransVector[i]->setMatrix(mBoundBoxScaleMat * mAccRootMat * transMat); } return; } /* update 'Rotate' matrix transform wireframes */ unsigned int numRotateChildren = mRotateSwitch->getNumChildren(); if (numRotateChildren > 1) { Vec3 gridRotationAxis = Vec3(0, 0, 1); if (mRotateSVect.x() > 0) gridRotationAxis = Vec3(1, 0, 0); else if (mRotateSVect.x() < 0) gridRotationAxis = Vec3(-1, 0, 0); else if (mRotateSVect.y() > 0) gridRotationAxis = Vec3(0, 1, 0); else if (mRotateSVect.y() < 0) gridRotationAxis = Vec3(0, -1, 0); else if (mRotateSVect.z() > 0) gridRotationAxis = Vec3(0, 0, 1); else if (mRotateSVect.z() < 0) gridRotationAxis = Vec3(0, 0, -1); for (int i = 0; i < numRotateChildren; i++) { Matrixd rotMat; rotMat.makeRotate(gridUnitAngle * i, gridRotationAxis); mRotateMatTransVector[i]->setMatrix(mBoundSphereScaleMat * rotMat); } return; } /* update 'Scale' matrix transform wireframes */ unsigned int numScaleChildren = mManipulateSwitch->getNumChildren(); if (numScaleChildren > 1) { /* rewrite scaling vector */ mScaleUnitVect.x() = mScaleUnitVect.x() > 0 ? 1:0; mScaleUnitVect.y() = mScaleUnitVect.y() > 0 ? 1:0; mScaleUnitVect.z() = mScaleUnitVect.z() > 0 ? 1:0; mScaleUnitVect *= gridUnitScale; for (int i = 0; i < numScaleChildren; i++) { /* generate scaling vector with non-negative values */ Vec3 scaleVect = Vec3(1, 1, 1); if (mScaleNumSegs > 0) scaleVect += mScaleUnitVect * i; else scaleVect -= mScaleUnitVect * i; scaleVect.x() = scaleVect.x() > 0 ? scaleVect.x() : 0; scaleVect.y() = scaleVect.y() > 0 ? scaleVect.y() : 0; scaleVect.z() = scaleVect.z() > 0 ? scaleVect.z() : 0; Matrixd scaleMat; scaleMat.makeScale(scaleVect); mManipulateMatTransVector[i]->setMatrix(mBoundBoxScaleMat * mAccRootMat * scaleMat); } return; } }
/*************************************************************** * Function: applyRotation() * * 'axisSVect': rotational snapping values around each axis, * for instance, Vec3(2, 0, 0) means rotation around X-axis by * two times of 'gridUnitAngle' * only one component of 'axisIntVect' is supposed to be non-zero * ***************************************************************/ void CAVEGroupEditGeodeWireframe::applyRotation(const osg::Vec3s &axisSVect, const float &gridUnitAngle, const string &gridUnitAngleInfo) { if (!mPrimaryFlag) return; mRotateSwitch->setAllChildrenOn(); /* rotate in other direction: clear all children of 'mRotateSwitch' except child[0], rebuild offset tree */ if ((mRotateSVect.x() * axisSVect.x() + mRotateSVect.y() * axisSVect.y() + mRotateSVect.z() * axisSVect.z()) <= 0) { unsigned int numChildren = mRotateSwitch->getNumChildren(); if (numChildren > 1) { mRotateSwitch->removeChildren(1, numChildren - 1); MatrixTransVector::iterator itrMatTrans = mRotateMatTransVector.begin(); mRotateMatTransVector.erase(itrMatTrans + 1, itrMatTrans + numChildren); } mRotateSVect = Vec3s(0, 0, 0); } /* decide unit rotation quat and start/end index of children under 'mRotateSwitch' */ Vec3 gridRotationAxis; short idxStart = 0, idxEnd = 0; if (axisSVect.x() != 0) { idxStart = mRotateSVect.x(); idxEnd = axisSVect.x(); if (axisSVect.x() > 0) gridRotationAxis = Vec3(1, 0, 0); else gridRotationAxis = Vec3(-1, 0, 0); } else if (axisSVect.y() != 0) { idxStart = mRotateSVect.y(); idxEnd = axisSVect.y(); if (axisSVect.y() > 0) gridRotationAxis = Vec3(0, 1, 0); else gridRotationAxis = Vec3(0, -1, 0); } else if (axisSVect.z() != 0) { idxStart = mRotateSVect.z(); idxEnd = axisSVect.z(); if (axisSVect.z() > 0) gridRotationAxis = Vec3(0, 0, 1); else gridRotationAxis = Vec3(0, 0, -1); } idxStart = idxStart > 0 ? idxStart: -idxStart; idxEnd = idxEnd > 0 ? idxEnd : -idxEnd; /* create or remove a sequence of extra children under 'mRotateSwitch' */ if (idxStart < idxEnd) { for (short i = idxStart + 1; i <= idxEnd; i++) { Matrixd rotMat; rotMat.makeRotate(gridUnitAngle * i, gridRotationAxis); MatrixTransform *rotateTrans = new MatrixTransform; CAVEGeodeEditWireframeRotate *rotateGeode = new CAVEGeodeEditWireframeRotate; mRotateSwitch->addChild(rotateTrans); mRotateMatTransVector.push_back(rotateTrans); rotateTrans->addChild(rotateGeode); rotateTrans->setMatrix(mBoundSphereScaleMat * rotMat); } } else if (idxStart > idxEnd) { mRotateSwitch->removeChildren(idxEnd + 1, idxStart - idxEnd); MatrixTransVector::iterator itrMatTrans = mRotateMatTransVector.begin(); itrMatTrans += idxEnd + 1; mRotateMatTransVector.erase(itrMatTrans, itrMatTrans + (idxStart - idxEnd)); } mRotateSVect = axisSVect; /* update info text if 'this' wireframe is primary */ mEditInfoTextSwitch->setAllChildrenOn(); char info[128]; const float gridUnitAngleDegree = gridUnitAngle * 180 / M_PI; sprintf(info, "Angle = %3.2f\nSnapping = ", gridUnitAngleDegree * idxEnd); mEditInfoText->setText(info + gridUnitAngleInfo); }
void Quat::get(Matrixd& matrix) const { matrix.makeRotate(*this); }
/*************************************************************** * Function: setEclipticPos() ***************************************************************/ void DSVirtualEarth::setEclipticPos(const float &date) { Matrixd rotMat; rotMat.makeRotate((date - gDateOffset) * M_PI * 2, Vec3(0, 0, 1)); mEclipticTrans->setMatrix(rotMat); }
/*************************************************************** * Function: setPinIndicatorPos() ***************************************************************/ void DSVirtualEarth::setPinIndicatorPos(const float &lati) { Matrixd rotMat; rotMat.makeRotate(lati * M_PI / 180.0f, Vec3(0, 0, 1)); mFixedPinIndicatorTrans->setMatrix(rotMat); }
/*************************************************************** * Function: updateDiagonal() * * 'wireFrameVect': Lengths vector of the wire frame, used to * decide the size of axis system. 'solidShapeVect': Diagonal * vector of the actual solid shape, used to print out numbers * of dimentions that showed on each axis. * ***************************************************************/ void CAVEGroupReferenceAxis::updateDiagonal(const osg::Vec3 &wireFrameVect, const osg::Vec3 &solidShapeVect) { /* update axis */ if (wireFrameVect.x() >= 0) mXAxisGeode->setType(CAVEGeodeReferenceAxis::POS_X, &mXDirTrans); else mXAxisGeode->setType(CAVEGeodeReferenceAxis::NEG_X, &mXDirTrans); if (wireFrameVect.y() >= 0) mYAxisGeode->setType(CAVEGeodeReferenceAxis::POS_Y, &mYDirTrans); else mYAxisGeode->setType(CAVEGeodeReferenceAxis::NEG_Y, &mYDirTrans); if (wireFrameVect.z() >= 0) mZAxisGeode->setType(CAVEGeodeReferenceAxis::POS_Z, &mZDirTrans); else mZAxisGeode->setType(CAVEGeodeReferenceAxis::NEG_Z, &mZDirTrans); mXAxisGeode->resize(wireFrameVect.x()); mYAxisGeode->resize(wireFrameVect.y()); mZAxisGeode->resize(wireFrameVect.z()); /* update text */ if (mTextEnabledFlag) { char lenstr[64]; const float threshold = CAVEGeodeSnapWireframe::gSnappingUnitDist; const float lx = solidShapeVect.x() > 0 ? solidShapeVect.x(): -solidShapeVect.x(); const float ly = solidShapeVect.y() > 0 ? solidShapeVect.y(): -solidShapeVect.y(); const float lz = solidShapeVect.z() > 0 ? solidShapeVect.z(): -solidShapeVect.z(); Matrixd rotMat; rotMat.makeRotate(Vec3(0, 1, 0), gPointerDir); if (lx >= threshold) { sprintf(lenstr, "%3.2f m", lx); mXAxisText->setText(string(lenstr)); /* apply pointer oriented rotation and offset along the axis */ Matrixd transMat; transMat.makeTranslate(Vec3(wireFrameVect.x(), 0, gCharSize)); mXAxisTextTrans->setMatrix(rotMat * transMat); } else mXAxisText->setText(""); if (ly >= threshold) { sprintf(lenstr, "%3.2f m", ly); mYAxisText->setText(string(lenstr)); /* apply pointer oriented rotation and offset along the axis */ Matrixd transMat; transMat.makeTranslate(Vec3(0, wireFrameVect.y(), gCharSize)); mYAxisTextTrans->setMatrix(rotMat * transMat); } else mYAxisText->setText(""); if (lz >= threshold) { sprintf(lenstr, "%3.2f m", lz); mZAxisText->setText(string(lenstr)); /* apply pointer oriented rotation and offset along the axis */ Matrixd transMat; transMat.makeTranslate(Vec3(0, -gCharSize, wireFrameVect.z())); mZAxisTextTrans->setMatrix(rotMat * transMat); } else mZAxisText->setText(""); } }