AnimationPath* ChessUtils::createChessPieceMoveAnimationPath(Vec3f initialPosition, Vec3f finalPosition, float rotationAngle, Vec3f rotationAxis, float pieceTravelSpeed, size_t numberSamplesInPath) { AnimationPath* animationPath = new AnimationPath(); animationPath->setLoopMode(osg::AnimationPath::NO_LOOPING); Vec3 positionsOffset = finalPosition - initialPosition; float positionsDistance = positionsOffset.length(); float jumpHeight = positionsDistance / 2.0; float maxHeightPosition = initialPosition.z() + jumpHeight; float animationTimeSeconds = std::max(positionsDistance / pieceTravelSpeed, 2.0f); float numberSamplesInPathF = (float)numberSamplesInPath; float halfAnimationTime = animationTimeSeconds / 2.0; float deltaTime = animationTimeSeconds / numberSamplesInPathF; // cross product to obtain a perpendicular vector in relation to the animation direction //Vec3 rotationAxis = positionsOffset ^ osg::Z_AXIS; float fullRotation = osg::PI * 2.0; osgAnimation::Motion* rotationEaseMotion = new osgAnimation::InOutCubicMotion(0, animationTimeSeconds, rotationAngle); osgAnimation::Motion* xMovingEaseMotion = new osgAnimation::InOutCubicMotion(initialPosition.x(), animationTimeSeconds, positionsOffset.x()); osgAnimation::Motion* yMovingEaseMotion = new osgAnimation::InOutCubicMotion(initialPosition.y(), animationTimeSeconds, positionsOffset.y()); osgAnimation::Motion* zClimbingEaseMotion = new osgAnimation::InQuadMotion(initialPosition.z(), halfAnimationTime, jumpHeight); osgAnimation::Motion* zFallingEaseMotion = new osgAnimation::OutBounceMotion(maxHeightPosition, halfAnimationTime, -jumpHeight); size_t halfNumberSamplesInPath = numberSamplesInPath / 2; double currenTime = 0; for (size_t currentSamplePosition = 0; currentSamplePosition < numberSamplesInPath; ++currentSamplePosition) { float sampleXPosition = xMovingEaseMotion->getValue(); xMovingEaseMotion->update(deltaTime); float sampleYPosition = yMovingEaseMotion->getValue(); yMovingEaseMotion->update(deltaTime); float sampleZPosition; if (currentSamplePosition < halfNumberSamplesInPath) { sampleZPosition = zClimbingEaseMotion->getValue(); zClimbingEaseMotion->update(deltaTime); } else { sampleZPosition = zFallingEaseMotion->getValue(); zFallingEaseMotion->update(deltaTime); } float sampleRotationAngle = rotationEaseMotion->getValue(); rotationEaseMotion->update(deltaTime); Vec3 position(sampleXPosition, sampleYPosition, sampleZPosition); Quat rotationQuad(sampleRotationAngle, rotationAxis); animationPath->insert(currenTime, AnimationPath::ControlPoint(position, rotationQuad)); currenTime += deltaTime; } return animationPath; }
/*************************************************************** * Function: ANIMCreateSingleIconToolkitSwitchAnimation() ***************************************************************/ void ANIMCreateSingleIconToolkitSwitchAnimation(int idx, ANIMIconToolkitSwitchEntry **iconToolkitEntry) { (*iconToolkitEntry)->mSwitch = new Switch; PositionAttitudeTransform *iconToolkitPATransFwd = new PositionAttitudeTransform; PositionAttitudeTransform *iconToolkitPATransBwd = new PositionAttitudeTransform; /* 'mSwitch' has two decendents for foward and backward animations */ (*iconToolkitEntry)->mSwitch->setAllChildrenOff(); (*iconToolkitEntry)->mSwitch->addChild(iconToolkitPATransFwd); (*iconToolkitEntry)->mSwitch->addChild(iconToolkitPATransBwd); /* attach the same 'CAVEGroupIconToolkit' object to both 'PositionAttitudeTransform' */ const CAVEGeodeIconToolkit::Type type = (CAVEGeodeIconToolkit::Type) idx; CAVEGroupIconToolkit *groupIconToolkit = new CAVEGroupIconToolkit(type); iconToolkitPATransFwd->addChild(groupIconToolkit); iconToolkitPATransBwd->addChild(groupIconToolkit); /* set up the forward / backward scale animation paths for toolkit icons */ AnimationPath* animScaleFwd = new AnimationPath; AnimationPath* animScaleBwd = new AnimationPath; animScaleFwd->setLoopMode(AnimationPath::NO_LOOPING); animScaleBwd->setLoopMode(AnimationPath::NO_LOOPING); Vec3 scaleFwd, scaleBwd; float step = 1.f / ANIM_GEOMETRY_EDITOR_TOOLKIT_SHOWUP_SAMPS; for (int i = 0; i < ANIM_GEOMETRY_EDITOR_TOOLKIT_SHOWUP_SAMPS + 1; i++) { float val = i * step; scaleFwd = Vec3(val, val, val); scaleBwd = Vec3(1.f-val, 1.f-val, 1.f-val); animScaleFwd->insert(val, AnimationPath::ControlPoint(Vec3(0,0,0), Quat(), scaleFwd)); animScaleBwd->insert(val, AnimationPath::ControlPoint(Vec3(0,0,0), Quat(), scaleBwd)); } (*iconToolkitEntry)->mFwdAnimCallback = new AnimationPathCallback(animScaleFwd, 0.0, 1.f / ANIM_GEOMETRY_EDITOR_TOOLKIT_SHOWUP_TIME); (*iconToolkitEntry)->mBwdAnimCallback = new AnimationPathCallback(animScaleBwd, 0.0, 1.f / ANIM_GEOMETRY_EDITOR_TOOLKIT_SHOWUP_TIME); iconToolkitPATransFwd->setUpdateCallback((*iconToolkitEntry)->mFwdAnimCallback); iconToolkitPATransBwd->setUpdateCallback((*iconToolkitEntry)->mBwdAnimCallback); }
AnimationPath* ChessUtils::createScaleAnimationPath(Vec3f position, osgAnimation::Motion* scaleEaseMotion, float animationTimeSeconds, size_t numberSamplesInPath) { AnimationPath* animationPath = new AnimationPath(); animationPath->setLoopMode(osg::AnimationPath::NO_LOOPING); float deltaTime = animationTimeSeconds / (float)numberSamplesInPath; double currenTime = 0; while (currenTime <= animationTimeSeconds) { float scaleFactor = scaleEaseMotion->getValue(); scaleEaseMotion->update(deltaTime); Quat rotationQuad(0, osg::Z_AXIS); Vec3d scale(scaleFactor, scaleFactor, scaleFactor); animationPath->insert(currenTime, AnimationPath::ControlPoint(position, rotationQuad, scale)); currenTime += deltaTime; } return animationPath; }
/*************************************************************** * Function: ANIMLoadSketchBook() ***************************************************************/ void ANIMLoadSketchBook(PositionAttitudeTransform** xformScaleFwd, PositionAttitudeTransform** xformScaleBwd, int &numPages, ANIMPageEntry ***pageEntryArray) { *xformScaleFwd = new PositionAttitudeTransform; *xformScaleBwd = new PositionAttitudeTransform; MatrixTransform *sketchbookTrans = new MatrixTransform; Matrixf transMat, scaleMat; transMat.makeTranslate(Vec3(0, 0, ANIM_VIRTUAL_SPHERE_RADIUS)); scaleMat.makeScale(Vec3(ANIM_PARA_PAINT_FRAME_ZOOM_FACTOR, ANIM_PARA_PAINT_FRAME_ZOOM_FACTOR, ANIM_PARA_PAINT_FRAME_ZOOM_FACTOR)); sketchbookTrans->setMatrix(transMat * scaleMat); (*xformScaleFwd)->addChild(sketchbookTrans); (*xformScaleBwd)->addChild(sketchbookTrans); // load sketch book node from VRML file, create page geodes Node* sketchbookNode = osgDB::readNodeFile(ANIMDataDir() + "VRMLFiles/SketchBook.WRL"); sketchbookTrans->addChild(sketchbookNode); // Load floorplan filenames from config file bool isFile = true; int j = 0, numTex; std::string file = "", dir, path; std::vector<std::string> filenames; dir = cvr::ConfigManager::getEntry("dir", "Plugin.CaveCADBeta.Floorplans", "/home/cehughes"); dir = dir + "/"; path = "Plugin.CaveCADBeta.Floorplans.0"; file = cvr::ConfigManager::getEntry(path, "", &isFile); while (isFile) { filenames.push_back(dir + file); j++; char buf[50]; sprintf(buf, "Plugin.CaveCADBeta.Floorplans.%d", j); std::string path = std::string(buf); file = cvr::ConfigManager::getEntry(path, "", &isFile); } numPages = j; //numPages = 3; // create tree structured page entry array *pageEntryArray = new ANIMPageEntry*[numPages]; for (int i = 0; i < numPages; i++) { /* char idxStr[16]; if (i < 10) { sprintf(idxStr, "0%d", i); } else if (i < 100) { sprintf(idxStr, "%d", i); }*/ string filename = filenames[i];//ANIMDataDir() + "Textures/Floorplans/Floorplan" + string(idxStr) + string(".JPG"); (*pageEntryArray)[i] = new ANIMPageEntry; Switch *singlePageSwitch = new Switch; PositionAttitudeTransform *flipUpTrans = new PositionAttitudeTransform; PositionAttitudeTransform *flipDownTrans = new PositionAttitudeTransform; sketchbookTrans->addChild(singlePageSwitch); singlePageSwitch->addChild(flipUpTrans); singlePageSwitch->addChild(flipDownTrans); singlePageSwitch->setAllChildrenOff(); // set up flip up / flip down animation paths for each page Geode *flipUpGeode, *flipDownGeode; AnimationPathCallback *flipUpCallback, *flipDownCallback; ANIMCreateSinglePageGeodeAnimation(filename, &flipUpGeode, &flipDownGeode, &flipUpCallback, &flipDownCallback); flipUpTrans->addChild(flipUpGeode); flipUpTrans->setUpdateCallback(flipUpCallback); flipDownTrans->addChild(flipDownGeode); flipDownTrans->setUpdateCallback(flipDownCallback); // write into page entry array record (*pageEntryArray)[i]->mSwitch = singlePageSwitch; (*pageEntryArray)[i]->mFlipUpAnim = flipUpCallback; (*pageEntryArray)[i]->mFlipDownAnim = flipDownCallback; (*pageEntryArray)[i]->mPageGeode = flipDownGeode; (*pageEntryArray)[i]->mTexFilename = filename; } (*pageEntryArray)[0]->mSwitch->setSingleChildOn(1); (*pageEntryArray)[1]->mSwitch->setSingleChildOn(0); // size of floorplan // FIX THIS - put sizes in the config file or something float alt = -2.9f; (*pageEntryArray)[0]->mLength = 32; (*pageEntryArray)[0]->mWidth = 16; (*pageEntryArray)[0]->mAlti = alt; (*pageEntryArray)[1]->mLength = 128; (*pageEntryArray)[1]->mWidth = 128; (*pageEntryArray)[1]->mAlti = alt; (*pageEntryArray)[2]->mLength = 32; (*pageEntryArray)[2]->mWidth = 16; (*pageEntryArray)[2]->mAlti = alt; (*pageEntryArray)[3]->mLength = 32; (*pageEntryArray)[3]->mWidth = 32; (*pageEntryArray)[3]->mAlti = alt; // set up the forward / backward scale animation paths for sketch book root switch AnimationPath* animationPathScaleFwd = new AnimationPath; AnimationPath* animationPathScaleBwd = new AnimationPath; animationPathScaleFwd->setLoopMode(AnimationPath::NO_LOOPING); animationPathScaleBwd->setLoopMode(AnimationPath::NO_LOOPING); Vec3 scaleFwd, scaleBwd; float step = 1.f / ANIM_VIRTUAL_SPHERE_NUM_SAMPS; for (int i = 0; i < ANIM_VIRTUAL_SPHERE_NUM_SAMPS + 1; i++) { float val = i * step; scaleFwd = Vec3(val, val, val); scaleBwd = Vec3(1.f-val, 1.f-val, 1.f-val); animationPathScaleFwd->insert(val, AnimationPath::ControlPoint(Vec3(),Quat(), scaleFwd)); animationPathScaleBwd->insert(val, AnimationPath::ControlPoint(Vec3(),Quat(), scaleBwd)); } AnimationPathCallback *animCallbackFwd = new AnimationPathCallback(animationPathScaleFwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); AnimationPathCallback *animCallbackBwd = new AnimationPathCallback(animationPathScaleBwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); (*xformScaleFwd)->setUpdateCallback(animCallbackFwd); (*xformScaleBwd)->setUpdateCallback(animCallbackBwd); }
/*************************************************************** * Function: ANIMCreateSinglePageGeodeAnimation() ***************************************************************/ void ANIMCreateSinglePageGeodeAnimation(const string& texfilename, Geode **flipUpGeode, Geode **flipDownGeode, AnimationPathCallback **flipUpCallback, AnimationPathCallback **flipDownCallback) { /* coordinates of page object */ Vec3 topleft = Vec3(-0.19, 0, 0); Vec3 bottomleft = Vec3(-0.19, 0, -0.28); Vec3 bottomright = Vec3( 0.19, 0, -0.28); Vec3 topright = Vec3( 0.19, 0, 0); Vec3 start = Vec3(0, -0.004, 0); Vec3 end = Vec3(0, 0.008, 0); float pageH = 0.28, pageW = 0.38; /* create page pain geometry */ *flipUpGeode = new Geode; *flipDownGeode = new Geode; Geometry *pageGeometry = new Geometry(); Vec3Array* vertices = new Vec3Array; Vec2Array* texcoords = new Vec2Array(4); Vec3Array* normals = new Vec3Array; vertices->push_back(topleft); (*texcoords)[0].set(0, 1); vertices->push_back(bottomleft); (*texcoords)[1].set(0, 0); vertices->push_back(bottomright); (*texcoords)[2].set(1, 0); vertices->push_back(topright); (*texcoords)[3].set(1, 1); for (int i = 0; i < 4; i++) { normals->push_back(Vec3(0, -1, 0)); } DrawElementsUInt* rectangle = new DrawElementsUInt(PrimitiveSet::POLYGON, 0); rectangle->push_back(0); rectangle->push_back(1); rectangle->push_back(2); rectangle->push_back(3); pageGeometry->addPrimitiveSet(rectangle); pageGeometry->setVertexArray(vertices); pageGeometry->setTexCoordArray(0, texcoords); pageGeometry->setNormalArray(normals); pageGeometry->setNormalBinding(Geometry::BIND_PER_VERTEX); (*flipUpGeode)->addDrawable(pageGeometry); (*flipDownGeode)->addDrawable(pageGeometry); /* apply image textures to page geodes */ Image* imgFloorplan = osgDB::readImageFile(texfilename); int imgW = imgFloorplan->s(); int imgH = imgFloorplan->t(); Texture2D* texFloorplan = new Texture2D(imgFloorplan); texFloorplan->setWrap(Texture::WRAP_S, Texture::CLAMP); texFloorplan->setWrap(Texture::WRAP_T, Texture::CLAMP); float imgRatio = (float) imgW / imgH; float pageRatio = pageW / pageH; if (imgRatio <= pageRatio) { (*texcoords)[0].set((1.0 - pageRatio / imgRatio) * 0.5, 1); (*texcoords)[1].set((1.0 - pageRatio / imgRatio) * 0.5, 0); (*texcoords)[2].set((1.0 + pageRatio / imgRatio) * 0.5, 0); (*texcoords)[3].set((1.0 + pageRatio / imgRatio) * 0.5, 1); } else { (*texcoords)[0].set(0, (1.0 + imgRatio / pageRatio) * 0.5); (*texcoords)[1].set(0, (1.0 - imgRatio / pageRatio) * 0.5); (*texcoords)[2].set(1, (1.0 - imgRatio / pageRatio) * 0.5); (*texcoords)[3].set(1, (1.0 + imgRatio / pageRatio) * 0.5); } Material *transmaterial = new Material; transmaterial->setDiffuse(Material::FRONT_AND_BACK, Vec4(1, 1, 1, 1)); transmaterial->setAlpha(Material::FRONT_AND_BACK, 0.8f); Material *solidmaterial = new Material; solidmaterial->setDiffuse(Material::FRONT_AND_BACK, Vec4(1, 1, 1, 1)); solidmaterial->setAlpha(Material::FRONT_AND_BACK, 1.0f); StateSet *flipUpStateSet = (*flipUpGeode)->getOrCreateStateSet(); flipUpStateSet->setTextureAttributeAndModes(0, texFloorplan, StateAttribute::ON); flipUpStateSet->setMode(GL_BLEND, StateAttribute::OVERRIDE | StateAttribute::ON ); flipUpStateSet->setRenderingHint(StateSet::TRANSPARENT_BIN); flipUpStateSet->setAttributeAndModes(transmaterial, StateAttribute::OVERRIDE | StateAttribute::ON); StateSet *flipDownStateSet = (*flipDownGeode)->getOrCreateStateSet(); flipDownStateSet->setTextureAttributeAndModes(0, texFloorplan, StateAttribute::ON); flipDownStateSet->setMode(GL_BLEND, StateAttribute::OVERRIDE | StateAttribute::ON ); flipDownStateSet->setRenderingHint(StateSet::TRANSPARENT_BIN); flipDownStateSet->setAttributeAndModes(solidmaterial, StateAttribute::OVERRIDE | StateAttribute::ON); /* create page flipping animation call backs */ AnimationPath* animationPathFlipUp = new AnimationPath; AnimationPath* animationPathFlipDown = new AnimationPath; animationPathFlipUp->setLoopMode(AnimationPath::NO_LOOPING); animationPathFlipDown->setLoopMode(AnimationPath::NO_LOOPING); Vec3 flipUpOffset, flipDownOffset; Quat flipUpQuat, flipDownQuat; Vec3 offsetstep = (end - start) / ANIM_SKETCH_BOOK_PAGE_FLIP_SAMPS; float anglestep = M_PI * 2 / ANIM_SKETCH_BOOK_PAGE_FLIP_SAMPS; float timestep = 1.0f / ANIM_SKETCH_BOOK_PAGE_FLIP_SAMPS; for (int i = 0; i < ANIM_SKETCH_BOOK_PAGE_FLIP_SAMPS + 1; i++) { float val = i * timestep; flipUpOffset = start + offsetstep * i; flipDownOffset = end - offsetstep * i; flipUpQuat = Quat(i * anglestep, Vec3(-1, 0, 0)); flipDownQuat = Quat(i * anglestep, Vec3(1, 0, 0)); animationPathFlipUp->insert(val, AnimationPath::ControlPoint(flipUpOffset, flipUpQuat, Vec3(1, 1, 1))); animationPathFlipDown->insert(val, AnimationPath::ControlPoint(flipDownOffset, flipDownQuat, Vec3(1, 1, 1))); } *flipUpCallback = new AnimationPathCallback(animationPathFlipUp, 0.0, 1.0f / ANIM_SKETCH_BOOK_PAGE_FLIP_TIME); *flipDownCallback = new AnimationPathCallback(animationPathFlipDown, 0.0, 1.0f / ANIM_SKETCH_BOOK_PAGE_FLIP_TIME); }
/*************************************************************** * Function: ANIMLoadSketchBook() ***************************************************************/ void ANIMLoadSketchBook(PositionAttitudeTransform** xformScaleFwd, PositionAttitudeTransform** xformScaleBwd, int &numPages, ANIMPageEntry ***pageEntryArray) { *xformScaleFwd = new PositionAttitudeTransform; *xformScaleBwd = new PositionAttitudeTransform; MatrixTransform *sketchbookTrans = new MatrixTransform; Matrixf transMat, scaleMat; transMat.makeTranslate(Vec3(0, 0, ANIM_VIRTUAL_SPHERE_RADIUS)); scaleMat.makeScale(Vec3(ANIM_PARA_PAINT_FRAME_ZOOM_FACTOR, ANIM_PARA_PAINT_FRAME_ZOOM_FACTOR, ANIM_PARA_PAINT_FRAME_ZOOM_FACTOR)); sketchbookTrans->setMatrix(transMat * scaleMat); (*xformScaleFwd)->addChild(sketchbookTrans); (*xformScaleBwd)->addChild(sketchbookTrans); /* load sketch book node from VRML file, create page geodes */ Node* sketchbookNode = osgDB::readNodeFile(ANIMDataDir() + "VRMLFiles/SketchBook.WRL"); sketchbookTrans->addChild(sketchbookNode); /* create tree structured page entry array */ numPages = 3; *pageEntryArray = new ANIMPageEntry*[numPages]; for (int i = 0; i < numPages; i++) { char idxStr[16]; if (i < 10) sprintf(idxStr, "0%d", i); else if (i < 100) sprintf(idxStr, "%d", i); string filename = ANIMDataDir() + "Textures/Floorplans/Floorplan" + string(idxStr) + string(".JPG"); (*pageEntryArray)[i] = new ANIMPageEntry; Switch *singlePageSwitch = new Switch; PositionAttitudeTransform *flipUpTrans = new PositionAttitudeTransform; PositionAttitudeTransform *flipDownTrans = new PositionAttitudeTransform; sketchbookTrans->addChild(singlePageSwitch); singlePageSwitch->addChild(flipUpTrans); singlePageSwitch->addChild(flipDownTrans); singlePageSwitch->setAllChildrenOff(); /* set up flip up / flip down animation paths for each page */ Geode *flipUpGeode, *flipDownGeode; AnimationPathCallback *flipUpCallback, *flipDownCallback; ANIMCreateSinglePageGeodeAnimation(filename, &flipUpGeode, &flipDownGeode, &flipUpCallback, &flipDownCallback); flipUpTrans->addChild(flipUpGeode); flipUpTrans->setUpdateCallback(flipUpCallback); flipDownTrans->addChild(flipDownGeode); flipDownTrans->setUpdateCallback(flipDownCallback); /* write into page entry array record */ (*pageEntryArray)[i]->mSwitch = singlePageSwitch; (*pageEntryArray)[i]->mFlipUpAnim = flipUpCallback; (*pageEntryArray)[i]->mFlipDownAnim = flipDownCallback; (*pageEntryArray)[i]->mPageGeode = flipDownGeode; (*pageEntryArray)[i]->mTexFilename = filename; } (*pageEntryArray)[0]->mSwitch->setSingleChildOn(1); (*pageEntryArray)[1]->mSwitch->setSingleChildOn(0); /* size of floorplan */ (*pageEntryArray)[0]->mLength = 32; (*pageEntryArray)[0]->mWidth = 16; (*pageEntryArray)[0]->mAlti = -1.5f; (*pageEntryArray)[1]->mLength = 128; (*pageEntryArray)[1]->mWidth = 128; (*pageEntryArray)[1]->mAlti = -1.5f; (*pageEntryArray)[2]->mLength = 32; (*pageEntryArray)[2]->mWidth = 16; (*pageEntryArray)[2]->mAlti = -1.5f; /* set up the forward / backward scale animation paths for sketch book root switch */ AnimationPath* animationPathScaleFwd = new AnimationPath; AnimationPath* animationPathScaleBwd = new AnimationPath; animationPathScaleFwd->setLoopMode(AnimationPath::NO_LOOPING); animationPathScaleBwd->setLoopMode(AnimationPath::NO_LOOPING); Vec3 scaleFwd, scaleBwd; float step = 1.f / ANIM_VIRTUAL_SPHERE_NUM_SAMPS; for (int i = 0; i < ANIM_VIRTUAL_SPHERE_NUM_SAMPS + 1; i++) { float val = i * step; scaleFwd = Vec3(val, val, val); scaleBwd = Vec3(1.f-val, 1.f-val, 1.f-val); animationPathScaleFwd->insert(val, AnimationPath::ControlPoint(Vec3(),Quat(), scaleFwd)); animationPathScaleBwd->insert(val, AnimationPath::ControlPoint(Vec3(),Quat(), scaleBwd)); } AnimationPathCallback *animCallbackFwd = new AnimationPathCallback(animationPathScaleFwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); AnimationPathCallback *animCallbackBwd = new AnimationPathCallback(animationPathScaleBwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); (*xformScaleFwd)->setUpdateCallback(animCallbackFwd); (*xformScaleBwd)->setUpdateCallback(animCallbackBwd); }
/*************************************************************** * Function: ANIMLoadGeometryCreator() * * xformScaleFwd: Root transform node for inflating geometries * xformScaleBwd: Root transform node for shrinking geometries * sphereExteriorSwitch: Switch control for single exterior sphere * ***************************************************************/ void ANIMLoadGeometryCreator(PositionAttitudeTransform** xformScaleFwd, PositionAttitudeTransform** xformScaleBwd, Switch **sphereExteriorSwitch, Geode **sphereExteriorGeode, int &numTypes, ANIMShapeSwitchEntry ***shapeSwitchEntryArray) { *xformScaleFwd = new PositionAttitudeTransform; *xformScaleBwd = new PositionAttitudeTransform; MatrixTransform *geomCreatorTrans = new MatrixTransform; MatrixTransform *sphereExteriorTrans = new MatrixTransform; *sphereExteriorSwitch = new Switch; Switch *createBoxSwitch = new Switch; Switch *createCylinderSwitch = new Switch; (*xformScaleFwd)->addChild(geomCreatorTrans); (*xformScaleBwd)->addChild(geomCreatorTrans); geomCreatorTrans->addChild(*sphereExteriorSwitch); geomCreatorTrans->addChild(createBoxSwitch); geomCreatorTrans->addChild(createCylinderSwitch); osg::Vec3 pos(-1, 0, 0); // create drawables, geodes and attach them to animation switches *sphereExteriorGeode = new Geode(); Sphere *sphere = new Sphere(osg::Vec3(), ANIM_VIRTUAL_SPHERE_RADIUS); ShapeDrawable *sphereDrawable = new ShapeDrawable(sphere); (*sphereExteriorGeode)->addDrawable(sphereDrawable); Box *box = new Box(osg::Vec3(0.1, 0, 0), ANIM_VIRTUAL_SPHERE_RADIUS / 1.9); (*sphereExteriorGeode)->addDrawable(new ShapeDrawable(box)); float r = ANIM_VIRTUAL_SPHERE_RADIUS / 3.0; Cylinder *cylinder = new Cylinder(osg::Vec3(-0.05, 0, -0.05), r, r * 2); (*sphereExteriorGeode)->addDrawable(new ShapeDrawable(cylinder)); Cone *cone = new osg::Cone(osg::Vec3(0, -0.1, 0.05), r, r * 2); (*sphereExteriorGeode)->addDrawable(new ShapeDrawable(cone)); Material *transmaterial = new Material; transmaterial->setDiffuse(Material::FRONT_AND_BACK, Vec4(1, 1, 1, 1)); transmaterial->setAlpha(Material::FRONT_AND_BACK, 0.6f); Image* envMap = osgDB::readImageFile(ANIMDataDir() + "Textures/ShapeContainer.JPG"); Texture2D* envTex = new Texture2D(envMap); StateSet *sphereStateSet = (sphereDrawable)->getOrCreateStateSet(); sphereStateSet->setMode(GL_BLEND, StateAttribute::OVERRIDE | StateAttribute::ON ); sphereStateSet->setRenderingHint(StateSet::TRANSPARENT_BIN); sphereStateSet->setAttributeAndModes(transmaterial, StateAttribute::OVERRIDE | StateAttribute::ON); sphereStateSet->setTextureAttributeAndModes(0, envTex, StateAttribute::ON); sphereStateSet->setMode(GL_CULL_FACE, StateAttribute::ON); sphereExteriorTrans->addChild(*sphereExteriorGeode); (*sphereExteriorSwitch)->addChild(sphereExteriorTrans); (*sphereExteriorSwitch)->setAllChildrenOn(); // write into shape switch entry array record numTypes = 2; *shapeSwitchEntryArray = new ANIMShapeSwitchEntry*[numTypes]; (*shapeSwitchEntryArray)[0] = new ANIMShapeSwitchEntry; (*shapeSwitchEntryArray)[1] = new ANIMShapeSwitchEntry; (*shapeSwitchEntryArray)[0]->mSwitch = createBoxSwitch; (*shapeSwitchEntryArray)[1]->mSwitch = createCylinderSwitch; ANIMCreateSingleShapeSwitchAnimation(&((*shapeSwitchEntryArray)[0]), CAVEGeodeShape::BOX); ANIMCreateSingleShapeSwitchAnimation(&((*shapeSwitchEntryArray)[1]), CAVEGeodeShape::CYLINDER); /* set up the forward / backward scale animation paths for geometry creator */ AnimationPath* animationPathScaleFwd = new AnimationPath; AnimationPath* animationPathScaleBwd = new AnimationPath; animationPathScaleFwd->setLoopMode(AnimationPath::NO_LOOPING); animationPathScaleBwd->setLoopMode(AnimationPath::NO_LOOPING); Vec3 scaleFwd, scaleBwd; float step = 1.f / ANIM_VIRTUAL_SPHERE_NUM_SAMPS; for (int i = 0; i < ANIM_VIRTUAL_SPHERE_NUM_SAMPS + 1; i++) { float val = i * step; scaleFwd = Vec3(val, val, val); scaleBwd = Vec3(1.f-val, 1.f-val, 1.f-val); animationPathScaleFwd->insert(val, AnimationPath::ControlPoint(pos, Quat(), scaleFwd)); animationPathScaleBwd->insert(val, AnimationPath::ControlPoint(pos, Quat(), scaleBwd)); } AnimationPathCallback *animCallbackFwd = new AnimationPathCallback(animationPathScaleFwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); AnimationPathCallback *animCallbackBwd = new AnimationPathCallback(animationPathScaleBwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); (*xformScaleFwd)->setUpdateCallback(animCallbackFwd); (*xformScaleBwd)->setUpdateCallback(animCallbackBwd); }
/*************************************************************** * Function: ANIMCreateSingleShapeSwitchAnimation() ***************************************************************/ void ANIMCreateSingleShapeSwitchAnimation(ANIMShapeSwitchEntry **shapeEntry, const CAVEGeodeShape::Type &typ) { PositionAttitudeTransform *flipUpFwdTrans = new PositionAttitudeTransform; PositionAttitudeTransform *flipDownFwdTrans = new PositionAttitudeTransform; PositionAttitudeTransform *flipUpBwdTrans = new PositionAttitudeTransform; PositionAttitudeTransform *flipDownBwdTrans = new PositionAttitudeTransform; (*shapeEntry)->mSwitch->addChild(flipUpFwdTrans); // child #0 (*shapeEntry)->mSwitch->addChild(flipDownFwdTrans); // child #1 (*shapeEntry)->mSwitch->addChild(flipUpBwdTrans); // child #2 (*shapeEntry)->mSwitch->addChild(flipDownBwdTrans); // child #3 (*shapeEntry)->mSwitch->setAllChildrenOff(); osg::Vec3 pos(0, 0, 0); /* create shape geode based on 'ANIMShapeSwitchEntry::Type' */ Geode *shapeGeode = new Geode; if (typ == CAVEGeodeShape::BOX) { Box *box = new Box(osg::Vec3(), ANIM_VIRTUAL_SPHERE_RADIUS / 0.9); shapeGeode->addDrawable(new ShapeDrawable(box)); } else if (typ == CAVEGeodeShape::CYLINDER) { float r = ANIM_VIRTUAL_SPHERE_RADIUS / 1.5; Cylinder *cylinder = new Cylinder(osg::Vec3(), r, r * 2); shapeGeode->addDrawable(new ShapeDrawable(cylinder)); } flipUpFwdTrans->addChild(shapeGeode); flipDownFwdTrans->addChild(shapeGeode); flipUpBwdTrans->addChild(shapeGeode); flipDownBwdTrans->addChild(shapeGeode); /* set up flip up / flip down animation paths for shape switch */ AnimationPath* animationFlipUpFwd = new AnimationPath; AnimationPath* animationFlipDownFwd = new AnimationPath; AnimationPath* animationFlipUpBwd = new AnimationPath; AnimationPath* animationFlipDownBwd = new AnimationPath; animationFlipUpFwd->setLoopMode(AnimationPath::NO_LOOPING); animationFlipDownFwd->setLoopMode(AnimationPath::NO_LOOPING); animationFlipUpBwd->setLoopMode(AnimationPath::NO_LOOPING); animationFlipDownBwd->setLoopMode(AnimationPath::NO_LOOPING); Vec3 scaleUpVect, scaleDownVect; Quat flipUpFwdQuat, flipDownFwdQuat, flipUpBwdQuat, flipDownBwdQuat; float timestep = ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_TIME / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_SAMPS; float scalestep = 1.f / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_SAMPS; float anglestep = M_PI * 0.5 / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_SAMPS; if (typ == CAVEGeodeShape::BOX) pos[2] -= 0.5; else if (typ == CAVEGeodeShape::CYLINDER) pos[2] -= 1.0; osg::Vec3 diff, startPos(0,0,0), fwd, bwd; for (int i = 0; i < ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_SAMPS + 1; i++) { float t = i * timestep; float val = i * scalestep; scaleUpVect = Vec3(val, val, val); scaleDownVect = Vec3(1.f-val, 1.f-val, 1.f-val); flipUpFwdQuat = Quat(i * anglestep - M_PI / 2, Vec3(1, 0, 0)); flipDownFwdQuat = Quat(i * anglestep, Vec3(1, 0, 0)); flipUpBwdQuat = Quat(i * anglestep - M_PI / 2, Vec3(-1, 0, 0)); flipDownBwdQuat = Quat(i * anglestep, Vec3(-1, 0, 0)); diff = startPos - pos; for (int j = 0; j < 3; ++j) diff[j] *= val; fwd = startPos - diff; bwd = pos + diff; animationFlipUpFwd->insert(t, AnimationPath::ControlPoint(fwd, flipUpFwdQuat, scaleUpVect)); animationFlipDownFwd->insert(t, AnimationPath::ControlPoint(fwd, flipDownFwdQuat, scaleUpVect)); animationFlipUpBwd->insert(t, AnimationPath::ControlPoint(bwd, flipUpBwdQuat, scaleDownVect)); animationFlipDownBwd->insert(t, AnimationPath::ControlPoint(bwd, flipDownBwdQuat, scaleDownVect)); } AnimationPathCallback *animCallbackFlipUpFwd = new AnimationPathCallback(animationFlipUpFwd, 0.0, 1.f / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_TIME); AnimationPathCallback *animCallbackFlipDownFwd = new AnimationPathCallback(animationFlipDownFwd, 0.0, 1.f / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_TIME); AnimationPathCallback *animCallbackFlipUpBwd = new AnimationPathCallback(animationFlipUpBwd, 0.0, 1.f / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_TIME); AnimationPathCallback *animCallbackFlipDownBwd = new AnimationPathCallback(animationFlipDownBwd, 0.0, 1.f / ANIM_GEOMETRY_CREATOR_SHAPE_FLIP_TIME); flipUpFwdTrans->setUpdateCallback(animCallbackFlipUpFwd); flipDownFwdTrans->setUpdateCallback(animCallbackFlipDownFwd); flipUpBwdTrans->setUpdateCallback(animCallbackFlipUpBwd); flipDownBwdTrans->setUpdateCallback(animCallbackFlipDownBwd); /* write into shape switch entry array record*/ (*shapeEntry)->mFlipUpFwdAnim = animCallbackFlipUpFwd; (*shapeEntry)->mFlipDownFwdAnim = animCallbackFlipDownFwd; (*shapeEntry)->mFlipUpBwdAnim = animCallbackFlipUpBwd; (*shapeEntry)->mFlipDownBwdAnim = animCallbackFlipDownBwd; }
/*************************************************************** * Function: ANIMCreateVirtualSphere() * ***************************************************************/ void ANIMCreateVirtualSphere(osg::PositionAttitudeTransform** xformScaleFwd, osg::PositionAttitudeTransform** xformScaleBwd) { // create sphere geometry *xformScaleFwd = new PositionAttitudeTransform; *xformScaleBwd = new PositionAttitudeTransform; Geode* sphereGeode = new Geode(); Sphere* virtualSphere = new Sphere(); Drawable* sphereDrawable = new ShapeDrawable(virtualSphere); virtualSphere->setRadius(ANIM_VIRTUAL_SPHERE_RADIUS); sphereGeode->addDrawable(sphereDrawable); (*xformScaleFwd)->addChild(sphereGeode); (*xformScaleBwd)->addChild(sphereGeode); osg::StateSet* stateset; // highlights /* Sphere* highlightSphere = new Sphere(); ShapeDrawable* highlightDrawable = new ShapeDrawable(highlightSphere); Geode* highlightGeode = new Geode(); highlightSphere->setRadius(ANIM_VIRTUAL_SPHERE_RADIUS * 1.3); highlightDrawable->setColor(osg::Vec4(0,0,1,0.3)); highlightGeode->addDrawable(highlightDrawable); (*xformScaleFwd)->addChild(highlightGeode); (*xformScaleBwd)->addChild(highlightGeode); stateset = highlightDrawable->getOrCreateStateSet(); stateset->setMode(GL_BLEND, StateAttribute::ON); stateset->setMode(GL_CULL_FACE, StateAttribute::ON); stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); stateset->setRenderingHint(StateSet::TRANSPARENT_BIN); */ // set up the forward / backward scale animation path AnimationPath* animationPathScaleFwd = new AnimationPath; AnimationPath* animationPathScaleBwd = new AnimationPath; animationPathScaleFwd->setLoopMode(AnimationPath::NO_LOOPING); animationPathScaleBwd->setLoopMode(AnimationPath::NO_LOOPING); osg::Vec3 pos(-1.5, 0, 0); Vec3 scaleFwd, scaleBwd; float step = 1.f / ANIM_VIRTUAL_SPHERE_NUM_SAMPS; for (int i = 0; i < ANIM_VIRTUAL_SPHERE_NUM_SAMPS + 1; i++) { float val = i * step; scaleFwd = Vec3(val, val, val); scaleBwd = Vec3(1-val, 1-val, 1-val); animationPathScaleFwd->insert(val, AnimationPath::ControlPoint(pos, Quat(), scaleFwd)); animationPathScaleBwd->insert(val, AnimationPath::ControlPoint(pos, Quat(), scaleBwd)); } AnimationPathCallback *animCallbackFwd = new AnimationPathCallback(animationPathScaleFwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); AnimationPathCallback *animCallbackBwd = new AnimationPathCallback(animationPathScaleBwd, 0.0, 1.f / ANIM_VIRTUAL_SPHERE_LAPSE_TIME); (*xformScaleFwd)->setUpdateCallback(animCallbackFwd); (*xformScaleBwd)->setUpdateCallback(animCallbackBwd); /* apply shaders to geode stateset */ stateset = new StateSet(); stateset->setMode(GL_BLEND, StateAttribute::OVERRIDE | StateAttribute::ON ); stateset->setRenderingHint(StateSet::TRANSPARENT_BIN); //sphereGeode->setStateSet(stateset); sphereDrawable->setStateSet(stateset); Program* shaderProg = new Program; stateset->setAttribute(shaderProg); shaderProg->addShader(Shader::readShaderFile(Shader::VERTEX, ANIMDataDir() + "Shaders/VirtualSphere.vert")); shaderProg->addShader(Shader::readShaderFile(Shader::FRAGMENT, ANIMDataDir() + "Shaders/VirtualSphere.frag")); Image* envMap = osgDB::readImageFile(ANIMDataDir() + "Textures/EnvMap.JPG"); Texture2D* envTex = new Texture2D(envMap); stateset->setTextureAttributeAndModes(0, envTex, StateAttribute::ON); Uniform* envMapSampler = new Uniform("EnvMap", 0); stateset->addUniform(envMapSampler); Uniform* baseColorUniform = new Uniform("BaseColor", Vec3(0.2, 1.0, 0.2)); stateset->addUniform(baseColorUniform); Uniform* lightPosUniform = new Uniform("LightPos", Vec4(1.0, 0.0, 0.2, 0.0)); stateset->addUniform(lightPosUniform); }