📄 tornado.cpp
字号:
#include "vsgu.h"
#include "vsSwitch.h"
#include "vrString.h"
#include "vp.h"
#include "vpLight.h"
#include "vpApp.h"
#include "vpIsector.h"
#include <vpFxParticleSystem.h>
#include <vpObject.h>
#include <vpTransform.h>
#include <vpPositionable.h>
#include <vuAllocTracer.h>
vuAllocTracer tracer;
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
// your user defined Subscriber class
derived from vpIsector::Subscriber
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~**/
class myAppSubscribers:public vpIsector::Subscriber{
public:
// variable declaration
// variables for the farmhouse and switch node
// public methods for this class
int initializeSubscriberInstances();
void initializeSubscriberFlags();
// methods for retrieving pointers
vpObject * getFarmhouse(){ return m_farmhouse;};
vpObject * getCow() { return m_cow;};
vpObject * getGrainStorage() {return m_grainStorage;};
// processing methods
void processFarmhouseSwitch();
void processGrainStorageHit();
void processRoadKill();
void rotateDebris();
// method to reset everything
void resetSubscriberInstances();
// Vega Prime requires the user to implement ALL subscriber signitures for
// typedef safety.
// By forcing the user to implement the subscriber functions Vega Prime
// will be able to catch major errors at compile time.
// first signiture which we don't really care about at this time
virtual void notify(vpIsector::Event event, const vpIsector *)
{
switch(event)
{
case vpIsector::EVENT_PRE_TRAVERSE:
case vpIsector::EVENT_CLEAR_HIT:
case vpIsector::EVENT_POST_TRAVERSE:
break;
}// end of switch
}
// 2nd signiture which contains all of the hit information; This is the one we will use
virtual uint notify(vpIsector::Event event, const vpIsector *isector, vsIsector::Hit *hitInstance )
{
switch (event)
{
case vsIsector::EVENT_HIT:
{
// retrieve a pointer to the object the isector has hit
// the object will be one of the targets assigned to the
// isector
vpObject *hitObj = isector->getHitObject();
// validate the pointer
if (hitObj != NULL)
{
// check to see which object was hit and then act accordingly
if ( hitObj->compare(m_farmhouse)) // if this is the farmhouse
{
// this message will appear with the error notification set to DEBUG.
vuNotify::print(vuNotify::LEVEL_DEBUG, NULL, "You are hitting the farmhouse\n");
// this method activate the switch node rendering the farm house as a pile of rubble
processFarmhouseSwitch();
}
else if (hitObj->compare(m_grainStorage)) // if this is the grain storage unit
{
// this message will appear with the error notification set to DEBUG.
vuNotify::print(vuNotify::LEVEL_DEBUG, NULL, "You are hitting the grain storage unit\n");
// this method will turn on the explosion,fire and debris special effects
processGrainStorageHit();
}
else if (hitObj->compare(m_cow)) // if this is the cow
{
// this message will appear with the error notification set to DEBUG.
vuNotify::print(vuNotify::LEVEL_DEBUG, NULL, "You are hitting the cow\n");
// this method will sweep the cow into the debris cloud
processRoadKill();
}
}// end if hitObj ! = NULL
}// end of EVENT_HIT
break;
}// end of switch
return vsTraversal::RESULT_CONTINUE;
}// end of notify
private:
vpObject *m_hitObj;
vpObject *m_farmhouse;
vsSwitch *m_farmhouseSwitch;
vpObject *m_grainStorage;
vpFx *m_grainStorageFire, *m_grainStorageExplosion, *m_grainStorageDebris;
bool m_farmhouseDestroyed, m_grainStorageDestroyed, m_roadKillDestroyed;
vpObject *m_cow;
vpFx *m_tornadoDebrisCloud;
};// end of myAppSubscribers
// other methods for the subscribers class
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- initializeSubscriberInstances
find the pointers for the instances
the farm house, grainStorage,
the switch in the farm house etc.
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
int myAppSubscribers::initializeSubscriberInstances()
{
m_farmhouse = vpObject::find("farmhouse");
if (m_farmhouse == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "farmhouse not found");
return vsgu::FAILURE;
}
// find and validate a pointer to the farmhouse switch node
// this node was defined and named when the farmhouse was created.
m_farmhouseSwitch = (vsSwitch *) m_farmhouse->findNamed("damage");
if (m_farmhouseSwitch == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "damage switch not found");
return vsgu::FAILURE;
}
// find and validate a pointer to the grainstorage unit
m_grainStorage = vpObject::find("grainStorage");
if (m_grainStorage == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "grainStorage not found");
return vsgu::FAILURE;
}
//find and validate the pointer to the grainStorageFire
m_grainStorageFire = vpFx::find("grainStorageFire");
if (m_grainStorageFire == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "grainStorageFire not found");
return vsgu::FAILURE;
}
//find and validate the pointer to the grainStorageDebris
m_grainStorageDebris = vpFx::find("grainStorageDebris");
if (m_grainStorageDebris == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "grainStorageDebris not found");
return vsgu::FAILURE;
}
//find and validate the pointer to the grainStorageExplosion
m_grainStorageExplosion = vpFx::find("grainStorageExplosion");
if (m_grainStorageExplosion == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "grainStorageExplosion not found");
return vsgu::FAILURE;
}
// find and validate the pointer to the cow 'road kill'
m_cow = vpObject::find("cow");
if (m_cow == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "cow not found");
return vsgu::FAILURE;
}
// find and validate the pointer to the cow 'road kill'
m_tornadoDebrisCloud = vpFx::find("tornadoDebris");
if (m_tornadoDebrisCloud == NULL)
{
vuNotify::print(vuNotify::LEVEL_WARN, NULL, "tornadoDebris not found");
return vsgu::FAILURE;
}
return vsgu::SUCCESS;
}
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- resetSubscriberInstances
put everything back where it was
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
void myAppSubscribers::resetSubscriberInstances()
{
// put the farmhouse back together
m_farmhouseSwitch->setActiveMask(0);
// restore the grainStorage Unit special effects
// turn off all of the special effects
m_grainStorageFire->setEnable(false);
m_grainStorageExplosion->setEnable(false);
m_grainStorageDebris->setEnable(false);
// put the cow back in it's grazing state
// take it out of the debris cloud
// restore the initial translation and orientation
m_tornadoDebrisCloud->removeChild(m_cow);
m_cow->setTranslate(2300, 1625, 0);
m_cow->setRotate(0, 0, 0);
m_roadKillDestroyed = false;
// turn off the farmhouse destroyed flag
// turn off the grainStorage destroyed flag
// turn off the roadKillDestroyed flag
initializeSubscriberFlags();
}
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- initializeSubscriberFlags
turn off the flags
The flags are used later to determine
if the tornado has already damaged the
farmhouse, grainstorage or cow to
avoid overkilling anything.
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
void myAppSubscribers::initializeSubscriberFlags()
{
m_farmhouseDestroyed = false;
m_grainStorageDestroyed = false;
m_roadKillDestroyed = false;
}
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- processFarmhouseSwitch()
change the farmhouse from
perfect farmhouse to tornado
damaged farmhouse.
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
void myAppSubscribers::processFarmhouseSwitch()
{
int currentMask;
int mask;
if (m_farmhouseDestroyed == false)
{
// get the current mask
mask = m_farmhouseSwitch->getActiveMask();
if (mask == 0)
{
currentMask = 1;
m_farmhouseSwitch->setActiveMask(currentMask);
m_farmhouseDestroyed = true;
}
}// farmhouse is not destroyed
}// end of farmhouse processing
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- processGrainStorageHit()
trigger just the right special effects
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
void myAppSubscribers::processGrainStorageHit()
{
if (m_grainStorageDestroyed == false)
{
// turn on the grainstorage special effects
m_grainStorageExplosion->setEnable( true );
m_grainStorageDebris->setEnable( true );
m_grainStorageFire->setEnable(true );
}
}// end of grainStorage hit
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- processRoadKill()
pick up the cow and add it to the
debris cloud
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
void myAppSubscribers::processRoadKill()
{
if (m_roadKillDestroyed == false)
{
// pick up the cow and add it to the debris cloud
m_tornadoDebrisCloud->addChild(m_cow);
// tilt the cow
m_cow->setTranslate(10, 0, 39);
m_cow->setRotate (22, 11, -26);
m_roadKillDestroyed = true;
}
}
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
method -- rotateDebris()
rotate the debris by 30 degrees
This method is called from th update
which means the debris cloud will rotate
30 degrees per frame
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
void myAppSubscribers::rotateDebris()
{
// rotate the debris cloud in 30 degree increments
m_tornadoDebrisCloud->setRotateH(30, true);
}
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~
// your user defined myApp class
derived from vpApp
This master class will take care of basic
application and rendering needs.
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
class myApp : public vpApp {
public:
// Constructor do all of the little initializations here
myApp()
{
// create a file pointer instance
m_file = new vuFile();
}; // end of constructor
// do all of your cleanup here
~myApp()
{
// just in case the tornado.path file was accidentally
// left open somewhere
m_file->close();
delete m_file;
}; // destructor
// other methods for this class
int initializeInstances();
void processHeadlights();
void processObserverLookAt();
void processTornado();
void moveTornado();
void resetEverything();
/*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*
Method-- onKeyInput
This method is defined in the vpApp class
Users can overload this method to redirect
keystrokes. The 'default' keys are
in tact until you override the commands
with your own.
Supported/ defined KEYS are:
KEY_ESCAPE: // quit the application
KEY_TILDE: // toggle the frame rate display
KEY_BACKSPACE: // reset observer state vector
KEY_ENTER: // recapture observer state vector
KEY_c: // put observer at the center of the scene
KEY_f: // enable / disable fog
KEY_l: // enable / disable lighting
KEY_p: // print observer absolute position
KEY_t: // enable / disable texture
KEY_T: // enable / disable transparency
KEY_w: // enable / disable wireframe
KEY_x: // enable / disable the motion model
~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*/
virtual void onKeyInput(vrWindow::Key key, int mod)
{
switch (key)
{
case vrWindow::KEY_L: // toggle the head light on and off
{
processHeadlights();
}
break;
case vrWindow::KEY_G: // start the tornado motion
{
processTornado();
}
break;
case vrWindow::KEY_O:
// toggle the lookAt target for the observer
processObserverLookAt();
break;
case vrWindow::KEY_R:
// start it all over
resetEverything();
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -