3 #ifdef OSG_BUILD_ACTIVE
7 #include <OSGAnimation.h>
8 #include <OSGAnimBindAction.h>
9 #include <OSGAnimKeyFrameTemplate.h>
10 #include <OSGGlobalsAttachment.h>
12 #include <OSGGLUTWindow.h>
13 #include <OSGImageFileHandler.h>
14 #include <OSGMatrixUtility.h>
15 #include <OSGNameAttachment.h>
16 #include <OSGSceneFileHandler.h>
17 #include <OSGShaderProgram.h>
18 #include <OSGShaderProgramChunk.h>
19 #include <OSGSimpleGeometry.h>
20 #include <OSGSimpleSceneManager.h>
21 #include <OSGSkinnedGeometry.h>
22 #include <OSGSkyBackground.h>
23 #include <OSGTextureObjChunk.h>
25 #else // OSG_BUILD_ACTIVE
27 #include <OpenSG/OSGConfig.h>
28 #include <OpenSG/OSGAnimation.h>
29 #include <OpenSG/OSGAnimBindAction.h>
30 #include <OpenSG/OSGAnimKeyFrameTemplate.h>
31 #include <OpenSG/OSGGlobalsAttachment.h>
32 #include <OpenSG/OSGGLUT.h>
33 #include <OpenSG/OSGGLUTWindow.h>
34 #include <OpenSG/OSGImageFileHandler.h>
35 #include <OpenSG/OSGNameAttachment.h>
36 #include <OpenSG/OSGMatrixUtility.h>
37 #include <OpenSG/OSGSceneFileHandler.h>
38 #include <OpenSG/OSGShaderProgram.h>
39 #include <OpenSG/OSGShaderProgramChunk.h>
40 #include <OpenSG/OSGSimpleGeometry.h>
41 #include <OpenSG/OSGSimpleSceneManager.h>
42 #include <OpenSG/OSGSkinnedGeometry.h>
43 #include <OpenSG/OSGSkyBackground.h>
44 #include <OpenSG/OSGTextureObjChunk.h>
46 #endif // OSG_BUILD_ACTIVE
48 #include <boost/array.hpp>
52 typedef std::set
<OSG::SkinnedGeometry
*> SkinnedGeoStore
;
53 typedef std::set
<OSG::Material
*> MaterialStore
;
54 typedef std::map
<std::string
, OSG::TextureObjChunkRefPtr
> TextureMap
;
87 OSG::SimpleSceneManagerRefPtr mgr
;
88 OSG::GLUTWindowRefPtr win
;
90 OSG::NodeRefPtr rootN
;
91 OSG::TransformRefPtr xform
;
95 CharacterStateE charState
;
96 CharacterStateE prevCharState
;
97 AnimStateE animState
[AnimIdMAX
];
98 OSG::AnimationRefPtr anims
[AnimIdMAX
];
100 SkinnedGeoStore skinGeos
;
101 MaterialStore materials
;
104 OSG::SkinnedGeometry::RenderModeE renderMode
;
105 OSG::ShaderProgramChunkRefPtr skinShader
;
116 charState (CharIdle
),
117 prevCharState(CharIdle
),
123 renderMode (OSG::SkinnedGeometry::RMSkinnedCPU
),
129 const OSG::Real32 idleAngleVel
= 0.f
;
130 const OSG::Real32 walkAngleVel
= OSG::TwoPi
/ 20.f
;
131 const OSG::Real32 runAngleVel
= OSG::TwoPi
/ 10.f
;
133 boost::array
<const std::string
, AnimIdMAX
> animNames
= {
144 GlobalVars
*g
= NULL
;
146 void init (int argc
, char *argv
[]);
149 void loadCharacter (void);
150 void loadTextures (void);
151 void initAnimations(void);
152 void loadBackground(void);
153 void initFloor (void);
154 void initShader (void);
155 void enableRenderMode(OSG::SkinnedGeometry::RenderModeE rm
);
157 void reshapeCB (int w
, int h
);
158 void displayCB (void);
159 void mouseCB (int button
, int state
, int mouseX
, int mouseY
);
160 void motionCB (int mouseX
, int mouseY
);
161 void keyboardCB(unsigned char k
, int mouseX
, int mouseY
);
163 int setupGLUT (int *argc
, char *argv
[]);
165 int main(int argc
, char *argv
[])
177 // ============================================================================
179 void init(int argc
, char *argv
[])
181 OSG::osgInit(argc
, argv
);
185 int glutWinId
= setupGLUT(&argc
, argv
);
187 g
->win
= OSG::GLUTWindow::create();
188 g
->win
->setGlutId(glutWinId
);
191 g
->mgr
= OSG::SimpleSceneManager::create();
192 g
->mgr
->setWindow(g
->win
);
194 g
->rootN
= OSG::makeCoredNode
<OSG::Group
>();
195 g
->mgr
->setRoot(g
->rootN
);
196 g
->mgr
->getHeadlight()->setDiffuse (0.7f
, 0.7f
, 0.5f
, 1.f
);
197 g
->mgr
->getHeadlight()->setAmbient (0.3f
, 0.3f
, 0.3f
, 1.f
);
198 g
->mgr
->getHeadlight()->setSpecular(0.3f
, 0.3f
, 0.3f
, 1.f
);
200 g
->charState
= CharIdle
;
201 g
->prevCharState
= CharIdle
;
204 g
->angleVel
= idleAngleVel
;
205 g
->renderMode
= OSG::SkinnedGeometry::RMSkinnedCPU
;
218 // ============================================================================
233 // ============================================================================
235 class ObjectCollector
238 void operator()(OSG::Node
*root
);
241 OSG::Action::ResultE
enterFunc(OSG::Node
*node
);
245 ObjectCollector::operator()(OSG::Node
*root
)
247 g
->skinGeos
.clear();
248 g
->materials
.clear();
250 OSG::traverse(root
, boost::bind(&ObjectCollector::enterFunc
, this, _1
));
254 ObjectCollector::enterFunc(OSG::Node
*node
)
256 OSG::NodeCore
*core
= node
->getCore();
258 if(core
->getType().isDerivedFrom(OSG::SkinnedGeometry::getClassType()))
260 OSG::SkinnedGeometry
*skinGeo
= dynamic_cast<OSG::SkinnedGeometry
*>(core
);
262 g
->skinGeos
.insert(skinGeo
);
263 g
->materials
.insert(skinGeo
->getMaterial());
266 return OSG::Action::Continue
;
269 // ============================================================================
271 void loadCharacter(void)
273 OSG::NodeUnrecPtr modelN
= OSG::SceneFileHandler::the()->read("western.male01.mesh", NULL
);
274 ObjectCollector()(modelN
);
276 SkinnedGeoStore::iterator sIt
= g
->skinGeos
.begin();
277 SkinnedGeoStore::iterator sEnd
= g
->skinGeos
.end ();
279 for(; sIt
!= sEnd
; ++sIt
)
281 (*sIt
)->setRenderMode(g
->renderMode
);
284 g
->xform
= OSG::Transform::create();
285 OSG::NodeUnrecPtr xformN
= OSG::makeNodeFor(g
->xform
);
287 xformN
->addChild(modelN
);
288 g
->rootN
->addChild(xformN
);
291 // ============================================================================
293 void loadTextures(void)
295 MaterialStore::iterator mIt
= g
->materials
.begin();
296 MaterialStore::iterator mEnd
= g
->materials
.end ();
298 for(; mIt
!= mEnd
; ++mIt
)
300 if(OSG::getName(*mIt
) != NULL
)
302 FLOG(("mat name '%s'\n", OSG::getName(*mIt
)));
304 std::string matName
= OSG::getName(*mIt
);
305 TextureMap::iterator tIt
= g
->texMap
.find(matName
);
307 if(tIt
== g
->texMap
.end())
309 std::string::size_type pos
= matName
.find("_");
310 std::string texName
= matName
.substr(0, pos
) + "_diffuse.tga";
312 OSG::ImageUnrecPtr texImg
= OSG::ImageFileHandler::the()->read(texName
.c_str());
313 OSG::TextureObjChunkUnrecPtr texObj
= OSG::TextureObjChunk::create();
315 texObj
->setImage(texImg
);
317 g
->texMap
.insert(TextureMap::value_type(matName
, texObj
));
319 tIt
= g
->texMap
.find(matName
);
322 OSG_ASSERT(tIt
!= g
->texMap
.end());
324 OSG::ChunkMaterial
*chunkMat
= dynamic_cast<OSG::ChunkMaterial
*>(*mIt
);
328 FLOG(("adding texture chunk\n"));
329 chunkMat
->addChunk((*tIt
).second
);
335 // ============================================================================
338 initAnimationsEnterFunc(OSG::Node
*node
)
340 OSG::Action::ResultE retVal
= OSG::Action::Continue
;
341 OSG::GlobalsAttachment
*globals
= dynamic_cast<OSG::GlobalsAttachment
*>(
342 node
->findAttachment(OSG::GlobalsAttachment::getClassType()));
347 OSG::GlobalsAttachment::MFElementsType::const_iterator eIt
= globals
->getMFElements()->begin();
348 OSG::GlobalsAttachment::MFElementsType::const_iterator eEnd
= globals
->getMFElements()->end ();
350 for(; eIt
!= eEnd
; ++eIt
)
352 OSG::AnimTemplate
*animTmpl
= dynamic_cast<OSG::AnimTemplate
*>(*eIt
);
357 for(OSG::UInt32 i
= 0; i
< animNames
.size(); ++i
)
359 if(animNames
[i
] == animTmpl
->getName())
361 FLOG(("instantiating anim %s\n", animNames
[i
].c_str()));
362 g
->anims
[i
] = animTmpl
->instantiate(node
);
363 g
->anims
[i
]->setWeight(0.f
);
364 g
->animState
[i
] = AnimOff
;
372 void initAnimations(void)
374 OSG::traverse(g
->rootN
, &initAnimationsEnterFunc
);
376 g
->animState
[AnimIdIdleUB
] = AnimFadeIn
;
377 g
->animState
[AnimIdIdleLB
] = AnimFadeIn
;
380 // ============================================================================
382 void updateAnimations(OSG::Time currT
, OSG::Time deltaT
)
384 for(OSG::UInt32 i
= 0; i
< AnimIdMAX
; ++i
)
386 switch(g
->animState
[i
])
390 if(g
->anims
[i
]->getEnabled() == true)
392 // FLOG(("AnimOff: disabling anim %d %s\n",
393 // i, g->anims[i]->getName().c_str()));
395 g
->anims
[i
]->stop ();
396 g
->anims
[i
]->setEnabled(false);
397 g
->anims
[i
]->setWeight (0.f
);
404 OSG::Real32 oldW
= g
->anims
[i
]->getWeight();
405 OSG::Real32 newW
= OSG::osgMin
<OSG::Real32
>(1.f
, oldW
+ deltaT
);
408 // FLOG(("AnimFadeIn: new weight %f - %d %s\n",
409 // newW, i, g->anims[i]->getName().c_str()));
410 g
->anims
[i
]->setWeight(newW
);
415 // FLOG(("AnimFadeIn: new state AnimOn %d %s\n",
416 // i, g->anims[i]->getName().c_str()));
417 g
->animState
[i
] = AnimOn
;
418 g
->anims
[i
]->setWeight(1.f
);
421 if(g
->anims
[i
]->getEnabled() == false)
423 // FLOG(("AnimFadeIn: enabling anim %d %s\n",
424 // i, g->anims[i]->getName().c_str()));
426 g
->anims
[i
]->reset ();
427 g
->anims
[i
]->setEnabled(true);
428 g
->anims
[i
]->startLoop (OSG::FrameHandler::the()->getTimeStamp());
435 OSG::Real32 oldW
= g
->anims
[i
]->getWeight();
436 OSG::Real32 newW
= OSG::osgMax
<OSG::Real32
>(0.f
, oldW
- deltaT
);
439 // FLOG(("AnimFadeOut: new weight %f - %d %s\n",
440 // newW, i, g->anims[i]->getName().c_str()));
441 g
->anims
[i
]->setWeight(newW
);
446 // FLOG(("AnimFadeOut: new state AnimOff %d %s\n",
447 // i, g->anims[i]->getName().c_str()));
448 g
->animState
[i
] = AnimOff
;
449 g
->anims
[i
]->setWeight(0.f
);
456 if(g
->anims
[i
]->getEnabled() == false)
458 // FLOG(("AnimOn: enabling anim %d %s\n",
459 // i, g->anims[i]->getName().c_str()));
461 g
->anims
[i
]->reset ();
462 g
->anims
[i
]->setEnabled(true);
463 g
->anims
[i
]->startLoop (OSG::FrameHandler::the()->getTimeStamp());
464 g
->anims
[i
]->setWeight (1.f
);
472 // ============================================================================
474 OSG::Real32
speedByState(CharacterStateE state
)
476 OSG::Real32 retVal
= 0.f
;
481 retVal
= idleAngleVel
;
484 retVal
= walkAngleVel
;
487 retVal
= runAngleVel
;
494 void updatePosition(OSG::Time deltaT
)
496 OSG::Real32 oldVel
= speedByState(g
->prevCharState
);
497 OSG::Real32 newVel
= speedByState(g
->charState
);
503 OSG::Real32 w1
= g
->anims
[AnimIdIdleLB
]->getWeight();
504 OSG::Real32 w0
= 1.f
- w1
;
506 g
->angleVel
= w0
* oldVel
+ w1
* newVel
;
512 OSG::Real32 w1
= g
->anims
[AnimIdWalkLB
]->getWeight();
513 OSG::Real32 w0
= 1.f
- w1
;
515 g
->angleVel
= w0
* oldVel
+ w1
* newVel
;
521 OSG::Real32 w1
= g
->anims
[AnimIdRunLB
]->getWeight();
522 OSG::Real32 w0
= 1.f
- w1
;
524 g
->angleVel
= w0
* oldVel
+ w1
* newVel
;
529 g
->angle
+= deltaT
* g
->angleVel
;
532 from
[0] = 500.f
* OSG::osgCos(g
->angle
);
533 from
[2] = 500.f
* OSG::osgSin(g
->angle
);
536 at
[0] = from
[0] + from
[2];
537 at
[2] = from
[2] - from
[0];
543 OSG::MatrixLookAt(mat
, from
, at
, up
);
545 g
->xform
->setMatrix(mat
);
548 // ============================================================================
550 void loadBackground(void)
552 OSG::ImageUnrecPtr imgFront
= OSG::ImageFileHandler::the()->read("skyBoxFront.jpg");
553 OSG::TextureObjChunkUnrecPtr texFront
= OSG::TextureObjChunk::create();
554 texFront
->setImage(imgFront
);
556 OSG::ImageUnrecPtr imgBack
= OSG::ImageFileHandler::the()->read("skyBoxBack.jpg");
557 OSG::TextureObjChunkUnrecPtr texBack
= OSG::TextureObjChunk::create();
558 texBack
->setImage(imgBack
);
560 OSG::ImageUnrecPtr imgLeft
= OSG::ImageFileHandler::the()->read("skyBoxLeft.jpg");
561 OSG::TextureObjChunkUnrecPtr texLeft
= OSG::TextureObjChunk::create();
562 texLeft
->setImage(imgLeft
);
564 OSG::ImageUnrecPtr imgRight
= OSG::ImageFileHandler::the()->read("skyBoxRight.jpg");
565 OSG::TextureObjChunkUnrecPtr texRight
= OSG::TextureObjChunk::create();
566 texRight
->setImage(imgRight
);
568 OSG::ImageUnrecPtr imgTop
= OSG::ImageFileHandler::the()->read("skyBoxTop.jpg");
569 OSG::TextureObjChunkUnrecPtr texTop
= OSG::TextureObjChunk::create();
570 texTop
->setImage(imgTop
);
572 OSG::ImageUnrecPtr imgBottom
= OSG::ImageFileHandler::the()->read("skyBoxBottom.jpg");
573 OSG::TextureObjChunkUnrecPtr texBottom
= OSG::TextureObjChunk::create();
574 texBottom
->setImage(imgBottom
);
576 OSG::SkyBackgroundUnrecPtr skyBG
= OSG::SkyBackground::create();
577 skyBG
->setFrontTexture (texFront
);
578 skyBG
->setBackTexture (texBack
);
579 skyBG
->setLeftTexture (texLeft
);
580 skyBG
->setRightTexture (texRight
);
581 skyBG
->setTopTexture (texTop
);
582 skyBG
->setBottomTexture(texBottom
);
584 g
->mgr
->setBackground(skyBG
);
587 // ============================================================================
591 OSG::GeometryUnrecPtr floor
= OSG::makePlaneGeo(2000.f
, 2000.f
, 10, 10);
592 OSG::NodeUnrecPtr floorN
= OSG::makeNodeFor(floor
);
593 OSG::TransformUnrecPtr xform
= OSG::Transform::create();
594 OSG::NodeUnrecPtr xformN
= OSG::makeNodeFor(xform
);
596 OSG::ImageUnrecPtr img
= OSG::ImageFileHandler::the()->read("sand1Tile.png");
597 OSG::TextureObjChunkUnrecPtr tex
= OSG::TextureObjChunk::create();
600 OSG::ChunkMaterial
*chunkMat
= dynamic_cast<OSG::ChunkMaterial
*>(floor
->getMaterial());
603 chunkMat
->addChunk(tex
);
606 OSG::Quaternion quat
;
607 quat
.setValueAsAxisDeg(OSG::Vec3f(1.f
, 0.f
, 0.f
), -90.f
);
609 xform
->editMatrix().setRotate(quat
);
611 xformN
->addChild(floorN
);
612 g
->rootN
->addChild(xformN
);
615 // ============================================================================
617 void initShader(void)
619 OSG::ShaderProgramUnrecPtr vp
= OSG::ShaderProgram::createVertexShader();
620 vp
->readProgram("vertex_skinned.vp.glsl");
622 OSG::ShaderProgramUnrecPtr fp
= OSG::ShaderProgram::createFragmentShader();
623 fp
->readProgram("vertex_skinned.fp.glsl");
625 fp
->addUniformVariable("diffuseMap", 0);
626 fp
->addOSGVariable ("OSGLight0Active");
627 fp
->addOSGVariable ("OSGLight1Active");
628 fp
->addOSGVariable ("OSGLight2Active");
629 fp
->addOSGVariable ("OSGLight3Active");
631 g
->skinShader
= OSG::ShaderProgramChunk::create();
632 g
->skinShader
->addShader(vp
);
633 g
->skinShader
->addShader(fp
);
636 void enableRenderMode(OSG::SkinnedGeometry::RenderModeE rm
)
638 if(g
->renderMode
== rm
)
641 if(g
->renderMode
== OSG::SkinnedGeometry::RMSkinnedGPU
)
643 // remove shader chunk
644 MaterialStore::iterator mIt
= g
->materials
.begin();
645 MaterialStore::iterator mEnd
= g
->materials
.end ();
647 for(; mIt
!= mEnd
; ++mIt
)
649 OSG::ChunkMaterial
*chunkMat
= dynamic_cast<OSG::ChunkMaterial
*>((*mIt
));
652 chunkMat
->subChunk(g
->skinShader
);
656 if(rm
== OSG::SkinnedGeometry::RMSkinnedGPU
)
659 MaterialStore::iterator mIt
= g
->materials
.begin();
660 MaterialStore::iterator mEnd
= g
->materials
.end ();
662 for(; mIt
!= mEnd
; ++mIt
)
664 OSG::ChunkMaterial
*chunkMat
= dynamic_cast<OSG::ChunkMaterial
*>((*mIt
));
667 chunkMat
->addChunk(g
->skinShader
);
671 SkinnedGeoStore::iterator sIt
= g
->skinGeos
.begin();
672 SkinnedGeoStore::iterator sEnd
= g
->skinGeos
.end ();
674 for(; sIt
!= sEnd
; ++sIt
)
676 (*sIt
)->setRenderMode(rm
);
679 FLOG(("enable render mode %d\n", rm
));
684 // ============================================================================
685 // GLUT callback functions
688 void reshapeCB(int w
, int h
)
690 g
->mgr
->resize(w
, h
);
696 static OSG::Time prevT
= OSG::getSystemTime();
697 OSG::Time currT
= OSG::getSystemTime();
698 OSG::Time deltaT
= currT
- prevT
;
700 updateAnimations(currT
, deltaT
);
701 updatePosition (deltaT
);
703 OSG::FrameHandler::the()->frame(currT
);
705 OSG::commitChangesAndClear();
712 void mouseCB(int button
, int state
, int mouseX
, int mouseY
)
715 g
->mgr
->mouseButtonRelease(button
, mouseX
, mouseY
);
717 g
->mgr
->mouseButtonPress(button
, mouseX
, mouseY
);
722 void motionCB(int mouseX
, int mouseY
)
724 g
->mgr
->mouseMove(mouseX
, mouseY
);
728 void keyboardCB(unsigned char k
, int mouseX
, int mouseY
)
743 if(g
->animState
[AnimIdWalkUB
] != AnimOn
)
744 g
->animState
[AnimIdWalkUB
] = AnimFadeIn
;
745 if(g
->animState
[AnimIdWalkLB
] != AnimOn
)
746 g
->animState
[AnimIdWalkLB
] = AnimFadeIn
;
749 if(g
->animState
[AnimIdRunUB
] != AnimOff
)
750 g
->animState
[AnimIdRunUB
] = AnimFadeOut
;
751 if(g
->animState
[AnimIdRunLB
] != AnimOff
)
752 g
->animState
[AnimIdRunLB
] = AnimFadeOut
;
754 if(g
->animState
[AnimIdIdleUB
] != AnimOff
)
755 g
->animState
[AnimIdIdleUB
] = AnimFadeOut
;
756 if(g
->animState
[AnimIdIdleLB
] != AnimOff
)
757 g
->animState
[AnimIdIdleLB
] = AnimFadeOut
;
759 g
->prevCharState
= g
->charState
;
760 g
->charState
= CharWalk
;
767 if(g
->animState
[AnimIdRunUB
] != AnimOn
)
768 g
->animState
[AnimIdRunUB
] = AnimFadeIn
;
769 if(g
->animState
[AnimIdRunLB
] != AnimOn
)
770 g
->animState
[AnimIdRunLB
] = AnimFadeIn
;
773 if(g
->animState
[AnimIdWalkUB
] != AnimOff
)
774 g
->animState
[AnimIdWalkUB
] = AnimFadeOut
;
775 if(g
->animState
[AnimIdWalkLB
] != AnimOff
)
776 g
->animState
[AnimIdWalkLB
] = AnimFadeOut
;
778 if(g
->animState
[AnimIdIdleUB
] != AnimOff
)
779 g
->animState
[AnimIdIdleUB
] = AnimFadeOut
;
780 if(g
->animState
[AnimIdIdleLB
] != AnimOff
)
781 g
->animState
[AnimIdIdleLB
] = AnimFadeOut
;
783 g
->prevCharState
= g
->charState
;
784 g
->charState
= CharRun
;
791 if(g
->animState
[AnimIdIdleUB
] != AnimOn
)
792 g
->animState
[AnimIdIdleUB
] = AnimFadeIn
;
793 if(g
->animState
[AnimIdIdleLB
] != AnimOn
)
794 g
->animState
[AnimIdIdleLB
] = AnimFadeIn
;
797 if(g
->animState
[AnimIdRunUB
] != AnimOff
)
798 g
->animState
[AnimIdRunUB
] = AnimFadeOut
;
799 if(g
->animState
[AnimIdRunLB
] != AnimOff
)
800 g
->animState
[AnimIdRunLB
] = AnimFadeOut
;
802 if(g
->animState
[AnimIdWalkUB
] != AnimOff
)
803 g
->animState
[AnimIdWalkUB
] = AnimFadeOut
;
804 if(g
->animState
[AnimIdWalkLB
] != AnimOff
)
805 g
->animState
[AnimIdWalkLB
] = AnimFadeOut
;
807 g
->prevCharState
= g
->charState
;
808 g
->charState
= CharIdle
;
814 OSG::SkinnedGeometry::RenderModeE newRM
=
815 static_cast<OSG::SkinnedGeometry::RenderModeE
>((g
->renderMode
+ 1) % 4);
817 enableRenderMode(newRM
);
830 int setupGLUT (int *argc
, char *argv
[])
832 glutInit(argc
, argv
);
833 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
835 int winId
= glutCreateWindow("OpenSG");
837 glutReshapeFunc(reshapeCB
);
838 glutDisplayFunc(displayCB
);
839 glutIdleFunc(idleCB
);
840 glutMouseFunc(mouseCB
);
841 glutMotionFunc(motionCB
);
842 glutKeyboardFunc(keyboardCB
);