/***************************************************************
* 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);
}
Example #3
0
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);
}
Example #8
0
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("");
    }
}