📄 testsims.cpp
字号:
/** @file TestSims.cpp
@brief Contains functions for setting up various test simulations.
*/
// Includes
#include "Demo.h"
// testBreakageCallback()
void testBreakageCallback(PhysicalObject* oldObject, Element* brokenElement,
DynamicFragment* newObject)
{
// Log the name of the new object (as a test)
LogManager::getSingleton().logMessage("Fragment '" + newObject->getName() + "' created.");
}
// testCollisionCallback()
void testCollisionCallback(const CollisionInfo& info)
{
// Log the name of the colliding objects
LogManager::getSingleton().logMessage("'" + info.objA->getName() +
"' collided with '" +
info.objB->getName() + "'.");
}
// testTriMeshQueryCallback()
void testTriMeshQueryCallback(const neV3& minBound,
const neV3& maxBound,
signed int** candidateTriangles,
neTriangle** triangles,
neV3** vertices,
signed int* candidateCount,
signed int* triangleCount)
{
// Perform no collision checks
(*candidateCount) = 0;
(*triangleCount) = 0;
}
// setupTestSim1()
/* THIS SIM ONLY:
I've placed additional comments in this sim to provide a tutorial of sorts for
OgreTok users. Tutorial comments are in /* format.
*/
DynamicSphere* setupTestSim1(SceneNode* rootNode)
{
// Test sims will return a bullet object for interactivity
DynamicSphere* bullet;
// Simulation already running
/* If the Simulation is already running, we should shut it down and recreate it
This is primarily becuase Tokamak needs to know a maximum number of objects
at initialisation, so the Simulation must be recreated if those numbers change.
*/
if(Simulation::getSingleton().isInitialised())
{
// Shutdown the Simulation (clears all existing objects automatically)
Simulation::getSingleton().shutdown();
}
// Initalise the Simulation
/* Sets up the Simulation's root node, update speed, gravity, and object maximums.
*/
Simulation::getSingleton().initialise(rootNode, // Node at the top of the object hierarchy (usually root)
OGRETOK_DEFAULT_STEPS_PER_SECOND, // Physics update rate
Vector3(0.0f, -490.0f, 0.0f), // Gravity
5, // Maximum StaticObjects
50, // Maximum DynamicObjects
0); // Maximum Joints
// Set the collision response/callback
/* Set the default collision response (0, 0) to respond with normal collision impulse,
but also to call the user callback. Set the user callback as the test callback
function. Commented out because, if you see the test callback above in this file,
what it does is log the name of the colliding objects. Considering the number
of collision that occur, this can quickly cause the log file to be VERY large.
Uncomment and run for about 0.5 seconds to see the effect on Ogre.log.
*/
//Simulation::getSingleton().setCollisionResponse(0, 0, RESPONSE_IMPULSE_CALLBACK);
//Simulation::getSingleton().setCollisionCallback(testCollisionCallback);
// Create the ground
/* This creates a the first object, a StaticBox that serves as the ground for the
Simulation. The name parameter should be unique for each object. In these demos
it's easy to use arbitrary names, but in a larger game you would likely want
some sort of naming system. The second and third parameters are the mesh and
material properties that govern the visible object. Either of these can be
omitted as in all these examples. This simply means that the Object has no
visual component. The next three parameters are self-explanatory, but the last
one is fairly important. If 'true', an alternate (debug) visual object will be
created. This will be either a box, a cylinder, or a sphere (depending on the
object type, obviously) using a default texture, that can be used to either A)
visualize an object for which graphics are not in place (as is done in these
examples... I'm a terrible modeller :P), or, more likely in a large project, they
can be displayed as a debug collision viewer. Note that the visual and debug
objects can be viewed one at a time or simulataneously. Creating a debug object
incures no extra physics computation, it is purely a visual imposter. Debug
objects can be especially handy because if the physical body is changed in size,
they change to match.
*/
Simulation::getSingleton().createStaticBox("ground", // Name
String::BLANK, // Mesh
String::BLANK, // Material
Vector3(0.0f, -2.5f, 0.0f), // Position
Quaternion::IDENTITY, // Orientation
String::BLANK, // Surface
Vector3(2500.0f, 5.0f, 2500.0f), // Size
true); // Create a debug object
// Create a few arbitrary obstacles
/* Here we create a few obstacles for the tower of blocks to fall into/over/around.
These should all be fairly self-explanatory.
*/
Simulation::getSingleton().createStaticSphere("obstacle1",
String::BLANK,
String::BLANK,
Vector3(450.0f, 250.0f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
500,
true);
Simulation::getSingleton().createStaticBox("obstacle2",
String::BLANK,
String::BLANK,
Vector3(-550.0f, 75.0f, -450.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(500.0f, 150.0f, 750.0f),
true);
Simulation::getSingleton().createStaticCapsule("obstacle3",
String::BLANK,
String::BLANK,
Vector3(-500.0f, 525.0f, 100.0f),
Quaternion::IDENTITY,
String::BLANK,
50.0f, 1000.0f,
true);
// Create the bullet
/* This creates the first dynamic object, a DynamicSphere which will serve as a
'bullet' of sorts in the demo. Take note of the new parameter, mass.
Also, just for fun (and to prove it's possible) I do something a little
different here and load a visual element and material instead of using the debug
object. (Yes, I know I said you can use them both, but I didn't say you could
control which one you see if they are exactly the same size, which they will be
in this case.)
*/
bullet = Simulation::getSingleton().createDynamicSphere("bullet", // Name
"sphere100.mesh", // Mesh
"Demo/Scales", // Material
Vector3(1000.0f, 25.0f, 1000.0f), // Position
Quaternion::IDENTITY, // Orientation
String::BLANK, // Surface
50.0f, // Diameter
25.0f, // Mass
false); // Create a debug object
/* In this case we have to perform one extra step and scale the bullet so that it is
the same size as the physical object. Why? Because the sphere mesh I loaded has
a diameter of 100, but the physical object has a diameter of 50. Incidentally,
this is the same trick that OgreTok uses to create the debug objects. I've just
chosen to replicate it here to prove a point. (that the visual elements work)
*/
bullet->scale(50.0f / 100.0f, 50.0f / 100.0f, 50.0f / 100.0f);
// Prevent the bullet from rolling forever
/* Setting the angular damping of the bullet allows it to 'settle' on the ground,
rather than rolling forever until it finds an edge and falls into the abyss. :)
*/
bullet->setAngularDamping(0.0025f);
// Construct a building (normal)
/* This is a handy little function I tossed together to build an abitrarily sized
test structure for stressing Tokamak. It builds a tower of stacked blocks. Nice
for debugging, and plenty of fun to look at. ;)
*/
constructBuilding("NormalBuilding", // Name
Vector3::ZERO, // Base position (bottom center)
Vector3(50.0f, 90.0f, 50.0f), // Corner size
25.0f, // Corner mass
String::BLANK, // Corner surface
Vector3(300.0f, 10.0f, 300.0f), // Floor size
25.0f, // Floor mass
String::BLANK, // floor surface
5); // Number of floors
// Return the bullet
/* We return the bullet object so the Application can use it to interact with the
user.
*/
return bullet;
}
// setupTestSim2()
DynamicSphere* setupTestSim2(SceneNode* rootNode)
{
// Test sims will return a bullet object for interactivity
DynamicSphere* bullet;
// Simulation already running
if(Simulation::getSingleton().isInitialised())
{
// Shutdown the Simulation (clears all existing objects)
Simulation::getSingleton().shutdown();
}
// Initalise the Simulation
Simulation::getSingleton().initialise(rootNode,
OGRETOK_DEFAULT_STEPS_PER_SECOND,
Vector3(0.0f, -490.0f, 0.0f),
5,
100,
0);
// Create the ground
Simulation::getSingleton().createStaticBox("ground",
String::BLANK,
String::BLANK,
Vector3(0.0f, -2.5f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(2500.0f, 5.0f, 2500.0f),
true);
// Create a few arbitrary obstacles
Simulation::getSingleton().createStaticBox("obstacle1",
String::BLANK,
String::BLANK,
Vector3(400.0f, 250.0f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(50.0f, 500.0f, 500.0f),
true);
Simulation::getSingleton().createStaticBox("obstacle2",
String::BLANK,
String::BLANK,
Vector3(-550.0f, 300.0f, -450.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(500.0f, 150.0f, 750.0f),
true);
Simulation::getSingleton().createStaticCapsule(String::BLANK,
String::BLANK,
String::BLANK,
Vector3(-500.0f, 525.0f, 100.0f),
Quaternion::IDENTITY,
String::BLANK,
50.0f, 1000.0f,
true);
// Create the bullet
bullet = Simulation::getSingleton().createDynamicSphere("bullet",
String::BLANK,
String::BLANK,
Vector3(1000.0f, 25.0f, 1000.0f),
Quaternion::IDENTITY,
String::BLANK,
50.0f,
25.0,
true);
// Prevent the bullet from rolling forever
bullet->setAngularDamping(0.0025f);
// Construct a building (fat)
constructBuilding("FatBuilding",
Vector3(0.0f, 0.0f, 0.0f),
Vector3(50.0f, 100.0f, 50.0f),
25.0f,
String::BLANK,
Vector3(250.0f,50.0f,250.0f),
25.0f,
String::BLANK,
10);
// Return the bullet
return bullet;
}
// setupTestSim3()
DynamicSphere* setupTestSim3(SceneNode* rootNode)
{
// Test sims will return a bullet object for interactivity
DynamicSphere* bullet;
// Simulation already running
if(Simulation::getSingleton().isInitialised())
{
// Shutdown the Simulation (clears all existing objects)
Simulation::getSingleton().shutdown();
}
// Initalise the Simulation
Simulation::getSingleton().initialise(rootNode,
OGRETOK_DEFAULT_STEPS_PER_SECOND,
Vector3(0.0f, -490.0f, 0.0f),
5,
50,
0);
// Create the ground
Simulation::getSingleton().createStaticBox("ground",
String::BLANK,
String::BLANK,
Vector3(0.0f, -2.5f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(2500.0f, 5.0f, 2500.0f),
true);
// Create a few arbitrary obstacles
Simulation::getSingleton().createStaticBox("rearWall",
String::BLANK,
String::BLANK,
Vector3(0.0f, 75.0f, -75.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(150.0f, 150.0f, 10.0f),
true);
Simulation::getSingleton().createStaticBox("frontWall",
String::BLANK,
String::BLANK,
Vector3(0.0f, 15.0f, 75.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(150.0f, 30.0f, 10.0f),
true);
Simulation::getSingleton().createStaticBox("rightWall",
String::BLANK,
String::BLANK,
Vector3(75.0f, 150.0f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(10.0f, 300.0f, 130.0f),
true);
Simulation::getSingleton().createStaticBox("leftWall",
String::BLANK,
String::BLANK,
Vector3(-75.0f, 50.0f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(10.0f, 100.0f, 130.0f),
true);
// Create the bullet
bullet = Simulation::getSingleton().createDynamicSphere("bullet",
String::BLANK,
String::BLANK,
Vector3(1000.0f, 25.0f, 1000.0f),
Quaternion::IDENTITY,
String::BLANK,
50.0f,
25.0,
true);
// Prevent the bullet from rolling forever
bullet->setAngularDamping(0.0025f);
// Construct a building (impossibly thin)
constructBuilding("ThinBuilding",
Vector3(0.0f, 0.0f, 0.0f),
Vector3(5.0f, 200.0f, 5.0f),
25.0f,
String::BLANK,
Vector3(100.0f, 10.0f, 100.0f),
25.0f,
String::BLANK,
5);
// Return the bullet
return bullet;
}
// setupTestSim4()
DynamicSphere* setupTestSim4(SceneNode* rootNode)
{
// Test sims will return a bullet object for interactivity
DynamicSphere* bullet;
// Simulation already running
if(Simulation::getSingleton().isInitialised())
{
// Shutdown the Simulation (clears all existing objects)
Simulation::getSingleton().shutdown();
}
// Initalise the Simulation
Simulation::getSingleton().initialise(rootNode,
OGRETOK_DEFAULT_STEPS_PER_SECOND,
Vector3(0.0f, -490.0f, 0.0f),
5,
150,
0);
// Create the ground
Simulation::getSingleton().createStaticBox("ground",
String::BLANK,
String::BLANK,
Vector3(0.0f, -2.5f, 0.0f),
Quaternion::IDENTITY,
String::BLANK,
Vector3(2500.0f, 5.0f, 2500.0f),
true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -