Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Samples/SkeletalAnimation/include/SkeletalAnimation.h @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 7.4 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14/*
15-----------------------------------------------------------------------------
16Filename:    SkeletalAnimation.h
17Description: Specialisation of OGRE's framework application to show the
18             skeletal animation feature, including spline animation.
19-----------------------------------------------------------------------------
20*/
21
22
23#include "ExampleApplication.h"
24
25#define NUM_JAIQUAS 6
26AnimationState* mAnimState[NUM_JAIQUAS];
27Real mAnimationSpeed[NUM_JAIQUAS];
28Vector3 mSneakStartOffset;
29Vector3 mSneakEndOffset;
30
31Quaternion mOrientations[NUM_JAIQUAS];
32Vector3 mBasePositions[NUM_JAIQUAS];
33SceneNode* mSceneNode[NUM_JAIQUAS];
34Degree mAnimationRotation(-60);
35Real mAnimChop = 7.96666f;
36Real mAnimChopBlend = 0.3f;
37
38// Event handler to animate
39class SkeletalAnimationFrameListener : public ExampleFrameListener
40{
41protected:
42public:
43        SkeletalAnimationFrameListener(RenderWindow* win, Camera* cam, const std::string &debugText)
44        : ExampleFrameListener(win, cam)
45    {
46                mDebugText = debugText;
47    }
48
49    bool frameStarted(const FrameEvent& evt)
50    {
51        if( ExampleFrameListener::frameStarted(evt) == false )
52                return false;
53
54        for (int i = 0; i < NUM_JAIQUAS; ++i)
55        {
56                        Real inc = evt.timeSinceLastFrame * mAnimationSpeed[i]; 
57                        if ((mAnimState[i]->getTimePosition() + inc) >= mAnimChop)
58                        {
59                                // Loop
60                                // Need to reposition the scene node origin since animation includes translation
61                                // Calculate as an offset to the end position, rotated by the
62                                // amount the animation turns the character
63                                Quaternion rot(mAnimationRotation, Vector3::UNIT_Y);
64                                Vector3 startoffset = mSceneNode[i]->getOrientation() * -mSneakStartOffset;
65                                Vector3 endoffset = mSneakEndOffset;
66                                Vector3 offset = rot * startoffset;
67                                Vector3 currEnd = mSceneNode[i]->getOrientation() * endoffset + mSceneNode[i]->getPosition();
68                                mSceneNode[i]->setPosition(currEnd + offset);
69                                mSceneNode[i]->rotate(rot);
70
71                                mAnimState[i]->setTimePosition((mAnimState[i]->getTimePosition() + inc) - mAnimChop);
72                        }
73                        else
74                        {
75                                mAnimState[i]->addTime(inc);
76                        }
77        }
78
79        return true;
80    }
81};
82
83
84
85class SkeletalApplication : public ExampleApplication
86{
87public:
88    SkeletalApplication() {}
89
90protected:
91        std::string mDebugText;
92
93    // Just override the mandatory create scene method
94    void createScene(void)
95    {
96                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
97                mSceneMgr->setShadowTextureSize(512);
98                mSceneMgr->setShadowColour(ColourValue(0.6, 0.6, 0.6));
99
100        // Setup animation default
101        Animation::setDefaultInterpolationMode(Animation::IM_LINEAR);
102        Animation::setDefaultRotationInterpolationMode(Animation::RIM_LINEAR);
103
104        // Set ambient light
105        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
106
107                // The jaiqua sneak animation doesn't loop properly, so lets hack it so it does
108                // We want to copy the initial keyframes of all bones, but alter the Spineroot
109                // to give it an offset of where the animation ends
110                SkeletonPtr skel = SkeletonManager::getSingleton().load("jaiqua.skeleton", 
111                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
112                Animation* anim = skel->getAnimation("Sneak");
113                Animation::NodeTrackIterator trackIter = anim->getNodeTrackIterator();
114                while (trackIter.hasMoreElements())
115                {
116                        NodeAnimationTrack* track = trackIter.getNext();
117
118                        TransformKeyFrame oldKf(0, 0);
119                        track->getInterpolatedKeyFrame(mAnimChop, &oldKf);
120
121                        // Drop all keyframes after the chop
122                        while (track->getKeyFrame(track->getNumKeyFrames()-1)->getTime() >= mAnimChop - mAnimChopBlend)
123                                track->removeKeyFrame(track->getNumKeyFrames()-1);
124
125                        TransformKeyFrame* newKf = track->createNodeKeyFrame(mAnimChop);
126                        TransformKeyFrame* startKf = track->getNodeKeyFrame(0);
127
128                        Bone* bone = skel->getBone(track->getHandle());
129                        if (bone->getName() == "Spineroot")
130                        {
131                                mSneakStartOffset = startKf->getTranslate() + bone->getInitialPosition();
132                                mSneakEndOffset = oldKf.getTranslate() + bone->getInitialPosition();
133                                mSneakStartOffset.y = mSneakEndOffset.y;
134                                // Adjust spine root relative to new location
135                                newKf->setRotation(oldKf.getRotation());
136                                newKf->setTranslate(oldKf.getTranslate());
137                                newKf->setScale(oldKf.getScale());
138
139
140                        }
141                        else
142                        {
143                                newKf->setRotation(startKf->getRotation());
144                                newKf->setTranslate(startKf->getTranslate());
145                                newKf->setScale(startKf->getScale());
146                        }
147                }
148
149
150
151
152        Entity *ent;
153                Real rotInc = Math::TWO_PI / (float)NUM_JAIQUAS;
154                Real rot = 0.0f;
155        for (int i = 0; i < NUM_JAIQUAS; ++i)
156        {
157                        Quaternion q;
158                        q.FromAngleAxis(Radian(rot), Vector3::UNIT_Y);
159
160                        mOrientations[i] = q;
161                        mBasePositions[i] = q * Vector3(0,0,-20);
162
163            ent = mSceneMgr->createEntity("jaiqua" + StringConverter::toString(i), "jaiqua.mesh");
164            // Add entity to the scene node
165                        mSceneNode[i] = mSceneMgr->getRootSceneNode()->createChildSceneNode();
166                        mSceneNode[i]->attachObject(ent);
167                        mSceneNode[i]->rotate(q);
168                        mSceneNode[i]->translate(mBasePositions[i]);
169                       
170            mAnimState[i] = ent->getAnimationState("Sneak");
171            mAnimState[i]->setEnabled(true);
172                        mAnimState[i]->setLoop(false); // manual loop since translation involved
173            mAnimationSpeed[i] = Math::RangeRandom(0.5, 1.5);
174
175                        rot += rotInc;
176        }
177
178
179
180        // Give it a little ambience with lights
181        Light* l;
182        l = mSceneMgr->createLight("BlueLight");
183                l->setType(Light::LT_SPOTLIGHT);
184        l->setPosition(-200,150,-100);
185                Vector3 dir(-l->getPosition());
186                dir.normalise();
187                l->setDirection(dir);
188        l->setDiffuseColour(0.5, 0.5, 1.0);
189
190        l = mSceneMgr->createLight("GreenLight");
191                l->setType(Light::LT_SPOTLIGHT);
192        l->setPosition(0,150,-100);
193                dir = -l->getPosition();
194                dir.normalise();
195                l->setDirection(dir);
196        l->setDiffuseColour(0.5, 1.0, 0.5);
197
198        // Position the camera
199        mCamera->setPosition(100,20,0);
200        mCamera->lookAt(0,10,0);
201
202        // Report whether hardware skinning is enabled or not
203        Technique* t = ent->getSubEntity(0)->getMaterial()->getBestTechnique();
204        Pass* p = t->getPass(0);
205        if (p->hasVertexProgram() && p->getVertexProgram()->isSkeletalAnimationIncluded())
206            mDebugText = "Hardware skinning is enabled";
207        else
208            mDebugText = "Software skinning is enabled";
209
210                Plane plane;
211                plane.normal = Vector3::UNIT_Y;
212                plane.d = 100;
213                MeshManager::getSingleton().createPlane("Myplane",
214                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
215                        1500,1500,20,20,true,1,60,60,Vector3::UNIT_Z);
216                Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
217                pPlaneEnt->setMaterialName("Examples/Rockwall");
218                pPlaneEnt->setCastShadows(false);
219                mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,99,0))->attachObject(pPlaneEnt);
220
221
222
223
224    }
225
226    // Create new frame listener
227    void createFrameListener(void)
228    {
229        mFrameListener= new SkeletalAnimationFrameListener(mWindow, mCamera, mDebugText);
230        mRoot->addFrameListener(mFrameListener);
231    }
232
233
234};
235
Note: See TracBrowser for help on using the repository browser.