1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | You may use this sample code for anything you like, it is not covered by the
|
---|
11 | LGPL like the rest of the engine.
|
---|
12 | -----------------------------------------------------------------------------
|
---|
13 | */
|
---|
14 |
|
---|
15 | /*
|
---|
16 | -----------------------------------------------------------------------------
|
---|
17 | Filename: BspCollision.cpp
|
---|
18 | Description: Somewhere to play in the sand...
|
---|
19 | -----------------------------------------------------------------------------
|
---|
20 | */
|
---|
21 |
|
---|
22 | #include "OgreReferenceAppLayer.h"
|
---|
23 |
|
---|
24 | #include "ExampleRefAppApplication.h"
|
---|
25 | #include "OgreStringConverter.h"
|
---|
26 |
|
---|
27 | // Hacky globals
|
---|
28 | ApplicationObject *ball;
|
---|
29 |
|
---|
30 | SceneNode* targetNode;
|
---|
31 | RaySceneQuery* rsq = 0;
|
---|
32 |
|
---|
33 |
|
---|
34 | // Event handler to add ability to alter curvature
|
---|
35 | class BspCollisionListener : public ExampleRefAppFrameListener
|
---|
36 | {
|
---|
37 | protected:
|
---|
38 | public:
|
---|
39 | BspCollisionListener(RenderWindow* win, CollideCamera* cam)
|
---|
40 | : ExampleRefAppFrameListener(win, cam)
|
---|
41 | {
|
---|
42 | }
|
---|
43 |
|
---|
44 |
|
---|
45 | bool frameEnded(const FrameEvent& evt)
|
---|
46 | {
|
---|
47 | // local just to stop toggles flipping too fast
|
---|
48 | static Real timeUntilNextToggle = 0;
|
---|
49 |
|
---|
50 | // Deal with time delays that are too large
|
---|
51 | // If we exceed this limit, we ignore
|
---|
52 | static const Real MAX_TIME_INCREMENT = 0.5f;
|
---|
53 | if (evt.timeSinceLastEvent > MAX_TIME_INCREMENT)
|
---|
54 | {
|
---|
55 | return true;
|
---|
56 | }
|
---|
57 |
|
---|
58 | if (timeUntilNextToggle >= 0)
|
---|
59 | timeUntilNextToggle -= evt.timeSinceLastFrame;
|
---|
60 |
|
---|
61 | // Call superclass
|
---|
62 | bool ret = ExampleRefAppFrameListener::frameEnded(evt);
|
---|
63 |
|
---|
64 | if (mInputDevice->isKeyDown(KC_SPACE) && timeUntilNextToggle <= 0)
|
---|
65 | {
|
---|
66 | timeUntilNextToggle = 2;
|
---|
67 | ball->setPosition(mCamera->getPosition() +
|
---|
68 | mCamera->getDirection() * mCamera->getNearClipDistance() * 2);
|
---|
69 | ball->setLinearVelocity(mCamera->getDirection() * 200);
|
---|
70 | ball->setAngularVelocity(Vector3::ZERO);
|
---|
71 | }
|
---|
72 |
|
---|
73 | // Move the targeter
|
---|
74 | rsq->setRay(mCamera->getRealCamera()->getCameraToViewportRay(0.5, 0.5));
|
---|
75 | RaySceneQueryResult& rsqResult = rsq->execute();
|
---|
76 | RaySceneQueryResult::iterator ri = rsqResult.begin();
|
---|
77 | if (ri != rsqResult.end())
|
---|
78 | {
|
---|
79 | RaySceneQueryResultEntry& res = *ri;
|
---|
80 | targetNode->setPosition(rsq->getRay().getPoint(res.distance));
|
---|
81 |
|
---|
82 | }
|
---|
83 |
|
---|
84 |
|
---|
85 |
|
---|
86 |
|
---|
87 | return ret;
|
---|
88 |
|
---|
89 | }
|
---|
90 | };
|
---|
91 |
|
---|
92 | class BspCollisionApplication : public ExampleRefAppApplication
|
---|
93 | {
|
---|
94 | public:
|
---|
95 | BspCollisionApplication() {
|
---|
96 |
|
---|
97 | }
|
---|
98 |
|
---|
99 | ~BspCollisionApplication()
|
---|
100 | {
|
---|
101 | delete rsq;
|
---|
102 | }
|
---|
103 |
|
---|
104 | protected:
|
---|
105 |
|
---|
106 | void chooseSceneManager(void)
|
---|
107 | {
|
---|
108 | mSceneMgr = mRoot->createSceneManager("BspSceneManager");
|
---|
109 | }
|
---|
110 | void createWorld(void)
|
---|
111 | {
|
---|
112 | // Create BSP-specific world
|
---|
113 | mWorld = new World(mSceneMgr, World::WT_REFAPP_BSP);
|
---|
114 | }
|
---|
115 | void createScene(void)
|
---|
116 | {
|
---|
117 | mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
|
---|
118 | // Set ambient light
|
---|
119 | mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
|
---|
120 | // Create a point light
|
---|
121 | Light* l = mSceneMgr->createLight("MainLight");
|
---|
122 | l->setPosition(-100,50,100);
|
---|
123 | l->setAttenuation(8000,1,0,0);
|
---|
124 |
|
---|
125 |
|
---|
126 | // Setup World
|
---|
127 | mWorld->setGravity(Vector3(0, 0, -60));
|
---|
128 | mWorld->getSceneManager()->setWorldGeometry("ogretestmap.bsp");
|
---|
129 |
|
---|
130 | // modify camera for close work
|
---|
131 | mCamera->setNearClipDistance(10);
|
---|
132 | mCamera->setFarClipDistance(20000);
|
---|
133 |
|
---|
134 | // Also change position, and set Quake-type orientation
|
---|
135 | // Get random player start point
|
---|
136 | ViewPoint vp = mSceneMgr->getSuggestedViewpoint(true);
|
---|
137 | mCamera->setPosition(vp.position);
|
---|
138 | mCamera->pitch(Degree(90)); // Quake uses X/Y horizon, Z up
|
---|
139 | mCamera->rotate(vp.orientation);
|
---|
140 | // Don't yaw along variable axis, causes leaning
|
---|
141 | mCamera->setFixedYawAxis(true, Vector3::UNIT_Z);
|
---|
142 | // Look at the boxes
|
---|
143 | mCamera->lookAt(-150,40,30);
|
---|
144 |
|
---|
145 | ball = mWorld->createBall("ball", 7, vp.position + Vector3(0,0,80));
|
---|
146 | ball->setDynamicsEnabled(true);
|
---|
147 | ball->getEntity()->setMaterialName("Ogre/Eyes");
|
---|
148 |
|
---|
149 | OgreRefApp::Box* box = mWorld->createBox("shelf", 75, 125, 5, Vector3(-150, 40, 30));
|
---|
150 | box->getEntity()->setMaterialName("Examples/Rocky");
|
---|
151 |
|
---|
152 | static const Real BOX_SIZE = 15.0f;
|
---|
153 | static const int num_rows = 3;
|
---|
154 |
|
---|
155 | for (int row = 0; row < num_rows; ++row)
|
---|
156 | {
|
---|
157 | for (int i = 0; i < (num_rows-row); ++i)
|
---|
158 | {
|
---|
159 | Real row_size = (num_rows - row) * BOX_SIZE * 1.25;
|
---|
160 | String name = "box";
|
---|
161 | name += StringConverter::toString((row*num_rows) + i);
|
---|
162 | box = mWorld->createBox(name, BOX_SIZE,BOX_SIZE,BOX_SIZE ,
|
---|
163 | Vector3(-150,
|
---|
164 | 40 - (row_size * 0.5) + (i * BOX_SIZE * 1.25) ,
|
---|
165 | 32.5 + (BOX_SIZE / 2) + (row * BOX_SIZE)));
|
---|
166 | box->setDynamicsEnabled(false, true);
|
---|
167 | box->getEntity()->setMaterialName("Examples/10PointBlock");
|
---|
168 | }
|
---|
169 | }
|
---|
170 | mCamera->setCollisionEnabled(false);
|
---|
171 | mCamera->getRealCamera()->setQueryFlags(0);
|
---|
172 |
|
---|
173 | // Create the targeting sphere
|
---|
174 | Entity* targetEnt = mSceneMgr->createEntity("testray", "sphere.mesh");
|
---|
175 | MaterialPtr mat = MaterialManager::getSingleton().create("targeter",
|
---|
176 | ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
---|
177 | Pass* pass = mat->getTechnique(0)->getPass(0);
|
---|
178 | TextureUnitState* tex = pass->createTextureUnitState();
|
---|
179 | tex->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT,
|
---|
180 | ColourValue::Red);
|
---|
181 | pass->setLightingEnabled(false);
|
---|
182 | pass->setSceneBlending(SBT_ADD);
|
---|
183 | pass->setDepthWriteEnabled(false);
|
---|
184 |
|
---|
185 |
|
---|
186 | targetEnt->setMaterialName("targeter");
|
---|
187 | targetEnt->setCastShadows(false);
|
---|
188 | targetEnt->setQueryFlags(0);
|
---|
189 | targetNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
|
---|
190 | targetNode->scale(0.025, 0.025, 0.025);
|
---|
191 | targetNode->attachObject(targetEnt);
|
---|
192 |
|
---|
193 | rsq = mSceneMgr->createRayQuery(Ray());
|
---|
194 | rsq->setSortByDistance(true, 1);
|
---|
195 | rsq->setWorldFragmentType(SceneQuery::WFT_SINGLE_INTERSECTION);
|
---|
196 |
|
---|
197 | mWindow->setDebugText("Press SPACE to throw the ball");
|
---|
198 | }
|
---|
199 | // Create new frame listener
|
---|
200 | void createFrameListener(void)
|
---|
201 | {
|
---|
202 | mFrameListener= new BspCollisionListener(mWindow, mCamera);
|
---|
203 | mRoot->addFrameListener(mFrameListener);
|
---|
204 | }
|
---|
205 |
|
---|
206 | public:
|
---|
207 |
|
---|
208 | };
|
---|
209 |
|
---|
210 |
|
---|
211 |
|
---|
212 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
---|
213 | #define WIN32_LEAN_AND_MEAN
|
---|
214 | #include "windows.h"
|
---|
215 |
|
---|
216 |
|
---|
217 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
|
---|
218 | #else
|
---|
219 | int main(int argc, char **argv)
|
---|
220 | #endif
|
---|
221 | {
|
---|
222 | // Create application object
|
---|
223 | BspCollisionApplication app;
|
---|
224 |
|
---|
225 | try {
|
---|
226 | app.go();
|
---|
227 | } catch( Exception& e ) {
|
---|
228 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
---|
229 | MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
|
---|
230 | #else
|
---|
231 | std::cerr << "An exception has occured: " << e.getFullDescription();
|
---|
232 | #endif
|
---|
233 | }
|
---|
234 |
|
---|
235 |
|
---|
236 | return 0;
|
---|
237 | }
|
---|
238 |
|
---|
239 |
|
---|
240 |
|
---|
241 |
|
---|
242 |
|
---|
243 |
|
---|
244 |
|
---|