· 6 years ago · Jan 30, 2020, 01:46 PM
1//==============================================================================================
2//==============================================================================================
3//
4// THIS IS IS A COMMON FILE FOR ALL THE GROUPS
5//
6// BE CAREFUL WHEN MODYFING IT !!!!!!!!!!!!!!!
7//
8// PLACE COMMENTS AROUND YOUR CHANGES TO MAKE IT CLEAR FOR THE OTHER GROUPS
9// WHAT PART OF THE CODE IS RESPONSIBLE FOR WHAT AND WHO WROTE IT
10//
11//==============================================================================================
12//==============================================================================================
13#include <ctime>
14#include <iostream>
15#include <cmath>
16#include <vector>
17
18#include "glew.h"
19#include "freeglut.h"
20#include "glm.hpp"
21#include "ext.hpp"
22#include "SOIL/SOIL.h"
23#include "ShaderLoader.h"
24
25#include "Scene.h"
26#include "PhysxScene.h"
27#include "Camera.h"
28
29#include "ExampleCameraController.h"
30#include "BallController.h"
31#include "ExampleRenderable.h"
32#include "ExampleTerrain.h"
33
34
35//==========================================================
36const float gravity = 9.8; // m / s^2
37// fixed timestep for stable and deterministic simulation
38const double physxStepTime = 1.f / 60.f;
39double physxTimeToProcess = 0;
40
41Scene scene;
42PhysxScene pxScene(gravity);
43Camera camera;
44//==========================================================
45
46
47//==========================================================
48// Group: Terrain
49ExampleTerrain terrain;
50// ...
51// ...
52
53//==========================================================
54// Group: Physics
55ExampleCameraController cameraController;
56BallController ballController;
57ExampleRenderable* ball;
58PxMaterial* groundMaterial = nullptr;
59PxMaterial* ballMaterial = nullptr;
60PxRigidStatic* groundBody = nullptr;
61PxRigidDynamic* ballBody = nullptr;
62int nbColumns = terrain.getCols();
63int nbRows = terrain.getRows();
64const PxU32 ts = nbRows;
65int terrainWidth = terrain.getSizeX();
66PxReal minHeight = PX_MAX_F32;
67PxReal maxHeight = -PX_MAX_F32;
68float terrainOffsetX = -50;
69float terrainOffsetZ = -50;
70PxHeightFieldGeometry innitHeightField();
71// ...
72// ...
73
74//==========================================================
75// Group: Effects
76
77// ...
78// ...
79
80//==========================================================
81
82void init()
83{
84 scene.setCamera(&camera);
85
86 //==========================================================
87 // Group: Terrain
88 terrain.init();
89 scene.addRenderable(&terrain);
90
91 //==========================================================
92 // Group: Physics
93
94 ball = new ExampleRenderable("models/ball.obj");
95 scene.addRenderable(ball);
96
97 ////----------------------------------------------
98 //// Use W,S,A,D,Q,E or mouse to control camera
99 cameraController.setCamera(&camera);
100 scene.addInput(&cameraController);
101
102 ////----------------------------------------------
103 //// Use I,J,K,L to move ball around the terrain
104 ballController.setTerrain(&terrain);
105 scene.addInput(&ballController);
106
107 ball->setMatrixFunction([](float time) {
108 // get position from controller
109 return glm::translate(ballController.getPos());
110 });
111
112
113
114
115
116
117
118
119
120 for (PxU32 row = 0; row < nbRows; row++)
121 {
122 for (PxU32 column = 0; column < nbColumns; column++)
123 {
124 minHeight = PxMin(minHeight, terrain.getHeight(column + terrainOffsetX, row + terrainOffsetZ));
125 maxHeight = PxMax(maxHeight, terrain.getHeight(column + terrainOffsetX, row + terrainOffsetZ));
126 }
127 }
128 groundBody = pxScene.physics->createRigidStatic(PxTransform(terrainOffsetX, minHeight, terrainOffsetZ));
129 // compute maximum height difference
130 PxHeightFieldGeometry hfGeom = innitHeightField();
131
132 PxShape* shape = PxRigidActorExt::createExclusiveShape(*groundBody, hfGeom, *groundMaterial); //w razie innych materialow dodac parametr nbMaterials
133
134 groundBody->attachShape(*shape);
135 groundBody->userData = nullptr;
136 pxScene.scene->addActor(*groundBody);
137
138
139
140
141
142 ballBody = pxScene.physics->createRigidDynamic(PxTransform(0, 10, 0));
143 ballMaterial = pxScene.physics->createMaterial(0.5f, 0.5f, 0.6f);
144 PxShape* ballShape = pxScene.physics->createShape(PxSphereGeometry(1), *ballMaterial);
145 ballBody->attachShape(*ballShape);
146 ballShape->release();
147 ballBody->userData = ball;
148 ballBody->setLinearVelocity(PxVec3(2, 10, -2));
149 PxRigidBodyExt::updateMassAndInertia(*ballBody, 10.0f);
150 pxScene.scene->addActor(*ballBody);
151
152 //==========================================================
153 // Group: Effects
154
155
156 //==========================================================
157
158 glEnable(GL_DEPTH_TEST);
159}
160
161PxHeightFieldGeometry innitHeightField() {
162 PxReal deltaHeight = maxHeight - minHeight;
163
164 // maximum positive value that can be represented with signed 16 bit integer
165 PxReal quantization = (PxReal)0x7fff;
166
167 // compute heightScale such that the forward transform will generate the closest point
168 // to the source
169 // clamp to at least PX_MIN_HEIGHTFIELD_Y_SCALE to respect the PhysX API specs
170 PxReal heightScale = PxMax(deltaHeight / quantization, PX_MIN_HEIGHTFIELD_Y_SCALE);
171
172 PxU32* hfSamples = new PxU32[ts * ts];
173 float colScale, rowScale;
174 colScale = terrainWidth / (ts - 1);
175 rowScale = terrainWidth / (ts - 1);
176 PxU32 index = 0;
177 for (PxU32 col = 0; col < ts; col++)
178 {
179 for (PxU32 row = 0; row < ts; row++)
180 {
181 float x = col * rowScale + terrainOffsetX;
182 float z = row * colScale + terrainOffsetZ;
183 PxI16 height;
184 height = PxI16(quantization * ((terrain.getHeight(x, z) - minHeight - 1) / deltaHeight));
185
186 PxHeightFieldSample& smp = (PxHeightFieldSample&)(hfSamples[(col * ts) + row]);
187 smp.height = height;
188 smp.materialIndex0 = 0;
189 smp.materialIndex1 = 1;
190 smp.clearTessFlag();
191 }
192 }
193
194 groundMaterial = pxScene.physics->createMaterial(0.5f, 0.5f, 0.6f);
195 // Build PxHeightFieldDesc from samples
196 PxHeightFieldDesc terrainDesc;
197 terrainDesc.format = PxHeightFieldFormat::eS16_TM;
198 terrainDesc.nbColumns = ts;
199 terrainDesc.nbRows = ts;
200 terrainDesc.samples.data = hfSamples;
201 terrainDesc.samples.stride = sizeof(PxU32);
202 terrainDesc.flags = PxHeightFieldFlags();
203
204 PxHeightFieldGeometry hfGeom;
205 hfGeom.columnScale = colScale;
206 hfGeom.rowScale = rowScale;
207 hfGeom.heightScale = deltaHeight != 0.0f ? heightScale : 1.0f;
208 hfGeom.heightField = pxScene.cooking->createHeightField(terrainDesc, pxScene.physics->getPhysicsInsertionCallback());
209
210 delete[] hfSamples;
211 return hfGeom;
212}
213
214
215void shutdown()
216{
217 //==========================================================
218 // Group: Terrain
219 // ...
220 // ...
221
222 //==========================================================
223 // Group: Physics
224 // ...
225 // ...
226
227 //==========================================================
228 // Group: Effects
229 // ...
230 // ...
231
232 //==========================================================
233}
234
235//==========================================================
236void updateTransforms()
237{
238 // Here we retrieve the current transforms of the objects from the physical simulation.
239 auto actorFlags = PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC;
240 PxU32 nbActors = pxScene.scene->getNbActors(actorFlags);
241 if (nbActors)
242 {
243 std::vector<PxRigidActor*> actors(nbActors);
244 pxScene.scene->getActors(actorFlags, (PxActor**)&actors[0], nbActors);
245 for (auto actor : actors)
246 {
247 // We use the userData of the objects to set up the proper model matrices.
248 if (!actor->userData) continue;
249 Renderable* renderable = (Renderable*)actor->userData;
250
251 // get world matrix of the object (actor)
252 PxMat44 transform = actor->getGlobalPose();
253 auto& c0 = transform.column0;
254 auto& c1 = transform.column1;
255 auto& c2 = transform.column2;
256 auto& c3 = transform.column3;
257
258 // set up the model matrix used for the rendering
259 renderable->setModelMatrix(glm::mat4(
260 c0.x, c0.y, c0.z, c0.w,
261 c1.x, c1.y, c1.z, c1.w,
262 c2.x, c2.y, c2.z, c2.w,
263 c3.x, c3.y, c3.z, c3.w));
264 }
265 }
266}
267
268void updatePhysics(float dtime)
269{
270 if (dtime < 1.f) // process physics only if more than 1 fps
271 {
272 physxTimeToProcess += dtime;
273 }
274 while (physxTimeToProcess > 0)
275 {
276 pxScene.step(physxStepTime);
277 physxTimeToProcess -= physxStepTime;
278 }
279}
280
281void renderScene()
282{
283 static double prevTime = 0;
284 double time = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
285 double dtime = time - prevTime;
286 prevTime = time;
287
288 updatePhysics(dtime);
289 updateTransforms();
290
291 scene.update(time);
292 scene.render();
293}
294
295//binding scene to mouse and keyboard input
296void mouse(int button, int state, int x, int y)
297{
298 scene.mouse(button, state, x, y);
299}
300void motion(int x, int y)
301{
302 scene.mouse(-1, -1, x, y);
303}
304void keyboard(unsigned char key, int x, int y)
305{
306 scene.keyboard(key, x, y);
307}
308
309void idle()
310{
311 glutPostRedisplay();
312}
313
314int main(int argc, char** argv)
315{
316 glutInit(&argc, argv);
317 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
318 glutInitWindowPosition(200, 200);
319 glutInitWindowSize(600, 600);
320 glutCreateWindow("OpenGL Project");
321
322 glewInit();
323
324 init();
325 glutDisplayFunc(renderScene);
326 glutMouseFunc(mouse);
327 glutMotionFunc(motion);
328 glutKeyboardFunc(keyboard);
329 glutIdleFunc(idle);
330
331 glutMainLoop();
332
333 shutdown();
334
335 return 0;
336}