#include <Inventor/Win/sowin.h>
#include <Inventor/Win/viewers/SoWinExaminerViewer.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/SoInput.h>
#include <Inventor/SoDB.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPointLight.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/VRMLnodes/SoVRMLMovieTexture.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor\nodes\SoMaterial.h>
SoSeparator *readfile(char *a)
{
SoInput myInput;
if (!myInput.openFile(a))
{
(void)fprintf(stdout,"不能打开文件");
exit(0);
}
else
{
SoSeparator * fileContents=SoDB::readAll(&myInput);
if (fileContents==NULL)
{
exit(0);
}
else
return fileContents;
}
}
SoPerspectiveCamera *pcam;
SoRotation *g_pLookupdownRotation;
SoRotation *g_pScenerotyRotation;
SoTranslation *g_pPosTrans;
float xpos,zpos;
float heading = 0.0f;
float yrot = 0.0f;
float walkbias = 0;
float walkbiasangle = 0;
float lookupdown = 0.0f;
float piover180=M_PI/180.0f;
void KeyboardEventCB(void *userData, SoEventCallback *pEventCB)
{
const SoEvent *pEvent = pEventCB->getEvent();
if(SO_KEY_PRESS_EVENT(pEvent,UP_ARROW))//好像不能实现 或 运算
{
xpos -= (float)sin(heading * piover180) * 2;
zpos -= (float)cos(heading * piover180) * 2;
if (walkbiasangle >= 359.0f)
walkbiasangle = 0.0f;
else
walkbiasangle += 10;
walkbias = (float)sin(walkbiasangle * piover180) / 20.0f;
g_pPosTrans->translation.setValue(-xpos,-walkbias - 0.25f,-zpos);
}
else
if(SO_KEY_PRESS_EVENT(pEvent,DOWN_ARROW))
{
xpos += (float)sin(heading * piover180) * 2;
zpos += (float)cos(heading * piover180) * 2;
if (walkbiasangle <= 1.0f)
walkbiasangle = 359.0f;
else
walkbiasangle -= 10;
walkbias = (float)sin(walkbiasangle * piover180) / 20.0f;
g_pPosTrans->translation.setValue(-xpos,-walkbias - 0.25f,-zpos);
}
else
if(SO_KEY_PRESS_EVENT(pEvent,LEFT_ARROW))
{
heading += 1.0f;
yrot = heading;
float sceneroty = 360.0f - yrot;
g_pScenerotyRotation->rotation.setValue(SbVec3f(0,1.0f,0),sceneroty * piover180);
}
else
if(SO_KEY_PRESS_EVENT(pEvent,RIGHT_ARROW))
{
heading -= 1.0f;
yrot = heading;
float sceneroty = 360.0f - yrot;
g_pScenerotyRotation->rotation.setValue(SbVec3f(0,1.0f,0),sceneroty * piover180);
}
else
if(SO_KEY_PRESS_EVENT(pEvent,PAGE_UP))
{
lookupdown -= 1.0f;
g_pLookupdownRotation->rotation.setValue(SbVec3f(1.0f,0,0),lookupdown * piover180);
}
else
if(SO_KEY_PRESS_EVENT(pEvent,PAGE_DOWN))
{
lookupdown += 1.0f;
g_pLookupdownRotation->rotation.setValue(SbVec3f(1.0f,0,0),lookupdown * piover180);
}
pEventCB->setHandled();
}
int main(int argc, char ** argv)
{
HWND mainwin=SoWin::init(argv[0]);
if (mainwin==NULL) {
MessageBox(NULL,"Error",NULL,NULL);
exit(1);
}
SoSeparator *root=new SoSeparator;
root->ref();
pcam=new SoPerspectiveCamera;
pcam->position.setValue(SbVec3f(0,0,40));
// pcam->orientation.setValue(0,-1,0,1);
root->addChild(pcam);
g_pLookupdownRotation = new SoRotation;
g_pLookupdownRotation->rotation.setValue(SbVec3f(1.0f,0,0),0);
root->addChild(g_pLookupdownRotation);
g_pScenerotyRotation = new SoRotation;
g_pScenerotyRotation->rotation.setValue(SbVec3f(0.0f,1.0f,0.0f),M_PI * 2);
root->addChild(g_pScenerotyRotation);
g_pPosTrans = new SoTranslation;
xpos -= (float)sin(heading * M_PI/180.0f) * 0.05f;
zpos -= (float)cos(heading * M_PI/180.0f) * 0.05f;
if (walkbiasangle >= 359.0f)
walkbiasangle = 0.0f;
else
walkbiasangle += 10;
walkbias = (float)sin(walkbiasangle * M_PI/180.0f) / 20.0f;
g_pPosTrans->translation.setValue(-xpos,-walkbias - 0.25f,-zpos);
root->addChild(g_pPosTrans);
SoEventCallback *peventcallback=new SoEventCallback;
peventcallback->addEventCallback(SoKeyboardEvent::getClassTypeId(),
KeyboardEventCB,root);
root->addChild(peventcallback);
/*
SoPointLight *pointlight=new SoPointLight;
pointlight->color.setValue(1.0f,1.0f,1.0f);
pointlight->location.setValue(0.0f,100.0f,0.0f);
pointlight->intensity.setValue(0.6f);
root->addChild(pointlight);
*/
SoSeparator *scene=new SoSeparator;
SoSeparator *date=readfile("date\\hall.wrl");
scene->addChild(date);
root->addChild(scene);
SoSeparator *scene1=new SoSeparator;//movie
root->addChild(scene1);
SoSeparator *scene2=new SoSeparator;//desk
root->addChild(scene2);
SoMaterial *material=new SoMaterial;
material->diffuseColor.setValue(0.5,0.5,0.5);
scene1->addChild(material);
SoVRMLMovieTexture *movie=new SoVRMLMovieTexture;
movie->loop.setValue(TRUE);
movie->pauseTime.setValue(3.0f);
movie->speed.setValue(0.9f);
movie->blendColor.setValue(0,0,0);
movie->url.setValue("date\\fox.avi");
scene1->addChild(movie);
SoCube *cube=new SoCube;
cube->depth.setValue(0.001f);
cube->height.setValue(21);
cube->width.setValue(38);
scene1->addChild(cube);
SoTransform *movietrans=new SoTransform;
movietrans->translation.setValue(101.55,-43,30);
movietrans->rotation.setValue(SbVec3f(0.0f,1.0f,0.0f),M_PI/2.0);
scene1->insertChild(movietrans,0);
// movietrans->rotation.setvalue()
/*
SoCube *cube2=new SoCube;
cube2->height=3;
cube2->width=4;
scene2->addChild(cube2);
SoTransform *mytransform2=new SoTransform;
mytransform2->translation.setValue(0,0,-1);
scene2->insertChild(mytransform2,0);
*/
SoWinExaminerViewer *mainviewer=new SoWinExaminerViewer(mainwin);
mainviewer->setSceneGraph(root);
mainviewer->setDecoration(FALSE);
mainviewer->setBackgroundColor(SbColor(0,0,0.8));
mainviewer->setViewing(FALSE);
// mainviewer->setHeadlight(FALSE);
mainviewer->show();
SoWin::show(mainwin);
SoWin::mainLoop();
return 0;
}