AxisObject类源码极其调用(生成一个Axis)

来源:互联网 发布:部落冲突天鹰火炮数据 编辑:程序博客网 时间:2024/04/27 11:34
#ifndef _AXIS_OBJECT_H_
#define _AXIS_OBJECT_H_


class AxisObject
{
enum BoxParts
{
BOX_NONE = 0x00,
BOX_TOP = 0x01,
BOX_BOT = 0x02,
BOX_FRONT = 0x04,
BOX_BACK = 0x08,
BOX_LEFT = 0x10,
BOX_RIGHT = 0x20,
BOX_ALL = 0xFF
};
private:
void addMaterial(const Ogre::String& mat, Ogre::ColourValue &clr, Ogre::SceneBlendType sbt);
void addBox(Ogre::ManualObject* obj, Ogre::Vector3 dim, Ogre::Vector3 pos, Ogre::ColourValue color, short boxMask);
public:
Ogre::ManualObject* createAxis(Ogre::SceneManager* scene, const Ogre::String &name, Ogre::Real scale);
};


#endif



#include "Ogre.h"
#include "OgreMaterial.h"
#include "AxisObject.h"


using namespace Ogre;


void AxisObject::addBox(Ogre::ManualObject* obj, Ogre::Vector3 dim, Ogre::Vector3 pos, Ogre::ColourValue color, short boxMask)
{
if(!obj)
return;
obj->begin("Axis", Ogre::RenderOperation::OT_TRIANGLE_LIST);


dim/= 2;


Ogre::Real l = dim.x;
Ogre::Real h = dim.y;
Ogre::Real w = dim.z;


obj->position(Ogre::Vector3(-1, h, w) + pos);
obj->colour(color);
obj->position(Ogre::Vector3(-l, -h, w) + pos); 
obj->colour(color); 
obj->position(Ogre::Vector3(1, -h, w) + pos);
obj->colour(color);
obj->position(Ogre::Vector3(1, h, w) + pos);


obj->position(Ogre::Vector3(-1, h, -w) + pos);
obj->colour(color);
obj->position(Ogre::Vector3(-1, -h, -w) + pos);
obj->colour(color);
obj->position(Ogre::Vector3(1, -h, -w) + pos);
obj->colour(color);
obj->position(Ogre::Vector3(1, h, -w) + pos);


//front back
if(boxMask & BOX_FRONT)
obj->quad(0, 1, 2, 3);
if(boxMask & BOX_BACK)
obj->quad(7, 6, 5, 4);


//top bottom
if(boxMask & BOX_TOP)
obj->quad(0, 3, 7, 4);
if(boxMask & BOX_BOT)
obj->quad(2, 1, 5, 6);


//end caps
if(boxMask & BOX_RIGHT)
obj->quad(1, 0, 4, 5);
if(boxMask & BOX_LEFT)
obj->quad(3, 2, 6, 7);


obj->end();


}


void AxisObject::addMaterial(const Ogre::String& mat, Ogre::ColourValue &clr, Ogre::SceneBlendType sbt)
{
static int init = false;
if(init)
return;
else
init = true;
Ogre::MaterialPtr matptr = Ogre::MaterialManager::getSingleton().create(mat, "General");
matptr->setReceiveShadows(false);
matptr->getTechnique(0)->setLightingEnabled(true);
matptr->getTechnique(0)->getPass(0)->setDiffuse(clr);
matptr->getTechnique(0)->getPass(0)->setAmbient(clr);
matptr->getTechnique(0)->getPass(0)->setSelfIllumination(clr);
matptr->getTechnique(0)->getPass(0)->setSceneBlending(sbt);
matptr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
matptr->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_DIFFUSE);


}


Ogre::ManualObject* AxisObject::createAxis(Ogre::SceneManager* scene, const Ogre::String &name, Ogre::Real scale)
{
addMaterial("Axis", Ogre::ColourValue(1, 1, 1, .75), Ogre::SBT_TRANSPARENT_ALPHA);


Ogre::ManualObject* axis = scene->createManualObject(name);


Ogre::Real len = scale;
Ogre::Real scl = len * .1;
Ogre::Real loc = len / 2 + scl / 2;
Ogre::Real fade = .5;
Ogre::Real solid = .8;


addBox(axis, Vector3(len, scl, scl), Vector3(loc,0,0), ColourValue(0, 0, solid, solid), (BOX_ALL & ~BOX_RIGHT));
addBox(axis, Vector3(len, scl, scl), Vector3(-loc,0,0), ColourValue(0, 0, fade, fade), (BOX_ALL & ~BOX_LEFT)); 


addBox(axis, Vector3(scl, len, scl), Vector3(0,loc,0), ColourValue(0, solid, 0, solid), (BOX_ALL & ~BOX_BOT));
addBox(axis, Vector3(scl, len, scl), Vector3(0,-loc,0), ColourValue(0, fade, 0, fade), (BOX_ALL & ~BOX_TOP));


addBox(axis, Vector3(scl, scl, len), Vector3(0,0,loc), ColourValue(solid, 0, 0, solid), (BOX_ALL & ~BOX_BACK)); 
addBox(axis, Vector3(scl, scl, len), Vector3(0,0,-loc), ColourValue(fade, 0, 0, fade), (BOX_ALL & ~BOX_FRONT));


axis->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - 1);




return axis;
}



调用


#include "ExampleApplication.h"
#include "AxisObject.h"

#define NUM_JAIQUAS 6
AnimationState* mAnimState[NUM_JAIQUAS];
Real mAnimationSpeed[NUM_JAIQUAS];
Vector3 mSneakStartOffset;
Vector3 mSneakEndOffset;


Quaternion mOrientations[NUM_JAIQUAS];
Vector3 mBasePositions[NUM_JAIQUAS];
SceneNode* mSceneNode[NUM_JAIQUAS];
Degree mAnimationRotation(-60);
Real mAnimChop = 7.96666f;
Real mAnimChopBlend = 0.3f;


// Event handler to animate
class SkeletalAnimationFrameListener : public ExampleFrameListener
{
protected:
public:
SkeletalAnimationFrameListener(RenderWindow* win, Camera* cam, const std::string &debugText)
        : ExampleFrameListener(win, cam)
    {
mDebugText = debugText;
    }


    bool frameRenderingQueued(const FrameEvent& evt)
    {
if( ExampleFrameListener::frameRenderingQueued(evt) == false )
return false;


        for (int i = 0; i < NUM_JAIQUAS; ++i)
        {
Real inc = evt.timeSinceLastFrame * mAnimationSpeed[i]; 
if ((mAnimState[i]->getTimePosition() + inc) >= mAnimChop)
{
// Loop
// Need to reposition the scene node origin since animation includes translation
// Calculate as an offset to the end position, rotated by the
// amount the animation turns the character
Quaternion rot(mAnimationRotation, Vector3::UNIT_Y);
Vector3 startoffset = mSceneNode[i]->getOrientation() * -mSneakStartOffset;
Vector3 endoffset = mSneakEndOffset;
Vector3 offset = rot * startoffset;
Vector3 currEnd = mSceneNode[i]->getOrientation() * endoffset + mSceneNode[i]->getPosition();
mSceneNode[i]->setPosition(currEnd + offset);
mSceneNode[i]->rotate(rot);


mAnimState[i]->setTimePosition((mAnimState[i]->getTimePosition() + inc) - mAnimChop);
}
else
{
mAnimState[i]->addTime(inc);
}
        }


        return true;
    }
};






class SkeletalApplication : public ExampleApplication
{
public:
    SkeletalApplication() {}


protected:
std::string mDebugText;


    // Just override the mandatory create scene method
    void createScene(void)
    {
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
mSceneMgr->setShadowTextureSize(512);
mSceneMgr->setShadowColour(ColourValue(0.6, 0.6, 0.6));


        // Setup animation default
        Animation::setDefaultInterpolationMode(Animation::IM_LINEAR);
        Animation::setDefaultRotationInterpolationMode(Animation::RIM_LINEAR);


        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));


// The jaiqua sneak animation doesn't loop properly, so lets hack it so it does
// We want to copy the initial keyframes of all bones, but alter the Spineroot
// to give it an offset of where the animation ends
SkeletonPtr skel = SkeletonManager::getSingleton().load("jaiqua.skeleton", 
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Animation* anim = skel->getAnimation("Sneak");
Animation::NodeTrackIterator trackIter = anim->getNodeTrackIterator();
while (trackIter.hasMoreElements())
{
NodeAnimationTrack* track = trackIter.getNext();


TransformKeyFrame oldKf(0, 0);
track->getInterpolatedKeyFrame(mAnimChop, &oldKf);


// Drop all keyframes after the chop
while (track->getKeyFrame(track->getNumKeyFrames()-1)->getTime() >= mAnimChop - mAnimChopBlend)
track->removeKeyFrame(track->getNumKeyFrames()-1);


TransformKeyFrame* newKf = track->createNodeKeyFrame(mAnimChop);
TransformKeyFrame* startKf = track->getNodeKeyFrame(0);


Bone* bone = skel->getBone(track->getHandle());
if (bone->getName() == "Spineroot")
{
mSneakStartOffset = startKf->getTranslate() + bone->getInitialPosition();
mSneakEndOffset = oldKf.getTranslate() + bone->getInitialPosition();
mSneakStartOffset.y = mSneakEndOffset.y;
// Adjust spine root relative to new location
newKf->setRotation(oldKf.getRotation());
newKf->setTranslate(oldKf.getTranslate());
newKf->setScale(oldKf.getScale());




}
else
{
newKf->setRotation(startKf->getRotation());
newKf->setTranslate(startKf->getTranslate());
newKf->setScale(startKf->getScale());
}
}








        Entity *ent;
Real rotInc = Math::TWO_PI / (float)NUM_JAIQUAS;
Real rot = 0.0f;
        for (int i = 0; i < NUM_JAIQUAS; ++i)
        {
Quaternion q;
q.FromAngleAxis(Radian(rot), Vector3::UNIT_Y);




mOrientations[i] = q;
mBasePositions[i] = q * Vector3(0,0,-20);


            ent = mSceneMgr->createEntity("jaiqua" + StringConverter::toString(i), "jaiqua.mesh");
            // Add entity to the scene node
mSceneNode[i] = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mSceneNode[i]->attachObject(ent);
mSceneNode[i]->rotate(q);
mSceneNode[i]->translate(mBasePositions[i]);


Ogre::String oname = "jaiqua-Axis" + StringConverter::toString(i);
Ogre::Vector3 pos(0, 0, 0);
Ogre::Quaternion rotq(Ogre::Quaternion::IDENTITY);
AxisObject axisObj;
Ogre::ManualObject* o = axisObj.createAxis(mSceneMgr, oname, 2);


Bone* bone = ent->getSkeleton()->getBone(i);
Matrix4 boneMat4;
bone->getWorldTransforms(&boneMat4);
Matrix3 boneMat3;
boneMat4.extract3x3Matrix(boneMat3);


Vector3 offsetPos = pos * boneMat3;  //得到 旋转以后的原点


Quaternion quat = bone->_getDerivedOrientation().Inverse() * rotq;
ent->attachObjectToBone(bone->getName(), o, quat, offsetPos);

            mAnimState[i] = ent->getAnimationState("Sneak");
            mAnimState[i]->setEnabled(true);
mAnimState[i]->setLoop(false); // manual loop since translation involved
            mAnimationSpeed[i] = Math::RangeRandom(0.5, 1.5);


rot += rotInc;
        }






        // Give it a little ambience with lights
        Light* l;
        l = mSceneMgr->createLight("BlueLight");
l->setType(Light::LT_SPOTLIGHT);
        l->setPosition(-200,150,-100);
Vector3 dir(-l->getPosition());
dir.normalise();
l->setDirection(dir);
        l->setDiffuseColour(0.5, 0.5, 1.0);


        l = mSceneMgr->createLight("GreenLight");
l->setType(Light::LT_SPOTLIGHT);
        l->setPosition(0,150,-100);
dir = -l->getPosition();
dir.normalise();
l->setDirection(dir);
        l->setDiffuseColour(0.5, 1.0, 0.5);


        // Position the camera
        mCamera->setPosition(100,20,0);
        mCamera->lookAt(0,10,0);


        // Report whether hardware skinning is enabled or not
        Technique* t = ent->getSubEntity(0)->getMaterial()->getBestTechnique();
        Pass* p = t->getPass(0);
        if (p->hasVertexProgram() && p->getVertexProgram()->isSkeletalAnimationIncluded())
            mDebugText = "Hardware skinning is enabled";
        else
            mDebugText = "Software skinning is enabled";


Plane plane;
plane.normal = Vector3::UNIT_Y;
plane.d = 100;
MeshManager::getSingleton().createPlane("Myplane",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
1500,1500,20,20,true,1,60,60,Vector3::UNIT_Z);
Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
pPlaneEnt->setMaterialName("Examples/Rockwall");
pPlaneEnt->setCastShadows(false);
mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,99,0))->attachObject(pPlaneEnt);





Ogitors::AxisGizmo::createPlaneMesh(mSceneMgr, "FirstPlane");
Ogitors::AxisGizmo::createMesh(mSceneMgr, "FirstAxisMesh");


    }


    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new SkeletalAnimationFrameListener(mWindow, mCamera, mDebugText);
        mRoot->addFrameListener(mFrameListener);
    }




};



原创粉丝点击