Merge rendering branch and fix conflicts

This commit is contained in:
Daniel Chappuis 2020-01-17 17:11:19 +01:00
commit 5df91f2338
25 changed files with 1389 additions and 1047 deletions

View File

@ -84,12 +84,6 @@ Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::Physi
const std::string& meshFolderPath)
: PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cube.obj", *this);
// Calculate the normals of the mesh
calculateNormals();
// Initialize the size of the box
mSize[0] = size.x * 0.5f;
mSize[1] = size.y * 0.5f;
@ -201,8 +195,7 @@ void Box::render(openglframework::Shader& shader, const openglframework::Matrix4
}
// Create the Vertex Buffer Objects used to render to box with OpenGL.
/// We create two VBOs (one for vertices and one for indices) to render all the boxes
/// in the simulation.
/// We create two VBOs (one for vertices and one for indices) to render the box
void Box::createVBOAndVAO() {
// Create the VBO for the vertices data
@ -228,7 +221,7 @@ void Box::createVBOAndVAO() {
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
// Create the VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int);

View File

@ -25,6 +25,7 @@
// Libraries
#include "ConvexMesh.h"
#include <unordered_set>
// Constructor
ConvexMesh::ConvexMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshPath)
@ -39,6 +40,19 @@ ConvexMesh::ConvexMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld*
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
for (int f=0; f < getNbFaces(0); f++) {
for (int v = 0; v < 3; v++) {
const openglframework::Vector3 vertex = mVertices[mIndices[0][f*3 + v]];
int vIndex = findVertexIndex(mConvexMeshVertices, vertex);
if (vIndex == -1) {
vIndex = mConvexMeshVertices.size();
mConvexMeshVertices.push_back(vertex);
}
mConvexMeshIndices.push_back(vIndex);
}
face->indexBase = f * 3;
face->nbVertices = 3;
face++;
@ -46,8 +60,8 @@ ConvexMesh::ConvexMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld*
// Create the polygon vertex array
mPolygonVertexArray =
new rp3d::PolygonVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
&(mIndices[0][0]), sizeof(int),
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
&(mConvexMeshIndices[0]), sizeof(int),
getNbFaces(0), mPolygonFaces,
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
@ -86,6 +100,19 @@ ConvexMesh::ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::Dyn
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
for (int f=0; f < getNbFaces(0); f++) {
for (int v = 0; v < 3; v++) {
const openglframework::Vector3 vertex = mVertices[mIndices[0][f*3 + v]];
int vIndex = findVertexIndex(mConvexMeshVertices, vertex);
if (vIndex == -1) {
vIndex = mConvexMeshVertices.size();
mConvexMeshVertices.push_back(vertex);
}
mConvexMeshIndices.push_back(vIndex);
}
face->indexBase = f * 3;
face->nbVertices = 3;
face++;
@ -93,8 +120,8 @@ ConvexMesh::ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::Dyn
// Create the polygon vertex array
mPolygonVertexArray =
new rp3d::PolygonVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
&(mIndices[0][0]), sizeof(int),
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
&(mConvexMeshIndices[0]), sizeof(int),
getNbFaces(0), mPolygonFaces,
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
@ -255,3 +282,16 @@ void ConvexMesh::createVBOAndVAO() {
// Unbind the VAO
mVAO.unbind();
}
// Return the index of a given vertex in the mesh
int ConvexMesh::findVertexIndex(const std::vector<openglframework::Vector3>& vertices, const openglframework::Vector3& vertex) {
for (int i = 0; i < vertices.size(); i++) {
if (vertices[i] == vertex) {
return i;
}
}
return -1;
}

View File

@ -69,11 +69,21 @@ class ConvexMesh : public PhysicsObject {
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Array with the vertices of the convex mesh
/// (only the vertices used for the physics shape, not duplicate vertices used for rendering)
std::vector<openglframework::Vector3> mConvexMeshVertices;
/// Array with the vertex indices of the convex mesh (used for the physics shape)
std::vector<int> mConvexMeshIndices;
// -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
/// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO();
/// Return the index of a given vertex in the mesh
int findVertexIndex(const std::vector<openglframework::Vector3>& vertices, const openglframework::Vector3& vertex);
public :
// -------------------- Methods -------------------- //

View File

@ -41,8 +41,12 @@ PhysicsObject::PhysicsObject(rp3d::PhysicsCommon& physicsCommon, const std::stri
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshPath, *this);
// Calculate the normals of the mesh
calculateNormals();
// If the mesh file do not have normals
if (mNormals.empty()) {
// Calculate the normals of the mesh
calculateNormals();
}
}
// Compute the new transform matrix

View File

@ -1,125 +1,205 @@
# Blender v2.66 (sub 0) OBJ File: ''
# Blender v2.80 (sub 75) OBJ File: ''
# www.blender.org
v 0.000000 -1.000000 0.000000
v 0.723607 -0.447220 0.525725
v -0.276388 -0.447220 0.850649
v -0.894426 -0.447216 0.000000
v -0.276388 -0.447220 -0.850649
v 0.723607 -0.447220 -0.525725
v 0.276388 0.447220 0.850649
v -0.723607 0.447220 0.525725
v -0.723607 0.447220 -0.525725
v 0.276388 0.447220 -0.850649
v 0.894426 0.447216 0.000000
v 0.000000 1.000000 0.000000
v 0.000000 -1.000000 -0.000000
v 0.425323 -0.850654 0.309011
v 0.262869 -0.525738 0.809012
v -0.162456 -0.850654 0.499995
v 0.425323 -0.850654 -0.309011
v 0.850648 -0.525736 0.000000
v -0.688189 -0.525736 0.499997
v -0.525730 -0.850652 0.000000
v -0.688189 -0.525736 -0.499997
v 0.723607 -0.447220 0.525725
v 0.850648 -0.525736 -0.000000
v -0.525730 -0.850652 -0.000000
v -0.162456 -0.850654 -0.499995
v 0.262869 -0.525738 -0.809012
v 0.951058 0.000000 -0.309013
v 0.951058 0.000000 0.309013
v 0.587786 0.000000 0.809017
v 0.000000 0.000000 1.000000
v -0.587786 0.000000 0.809017
v -0.951058 0.000000 0.309013
v -0.951058 0.000000 -0.309013
v 0.425323 -0.850654 -0.309011
v 0.951058 -0.000000 0.309013
v -0.276388 -0.447220 0.850649
v 0.262869 -0.525738 0.809012
v 0.000000 -0.000000 1.000000
v -0.894426 -0.447216 -0.000000
v -0.688189 -0.525736 0.499997
v -0.951058 -0.000000 0.309013
v -0.276388 -0.447220 -0.850649
v -0.688189 -0.525736 -0.499997
v -0.587786 0.000000 -0.809017
v 0.000000 0.000000 -1.000000
v 0.723607 -0.447220 -0.525725
v 0.262869 -0.525738 -0.809012
v 0.587786 0.000000 -0.809017
v 0.587786 -0.000000 0.809017
v -0.587786 -0.000000 0.809017
v -0.951058 0.000000 -0.309013
v 0.000000 0.000000 -1.000000
v 0.951058 0.000000 -0.309013
v 0.276388 0.447220 0.850649
v 0.688189 0.525736 0.499997
v 0.162456 0.850654 0.499995
v -0.723607 0.447220 0.525725
v -0.262869 0.525738 0.809012
v -0.425323 0.850654 0.309011
v -0.723607 0.447220 -0.525725
v -0.850648 0.525736 0.000000
v -0.425323 0.850654 -0.309011
v 0.276388 0.447220 -0.850649
v -0.262869 0.525738 -0.809012
v 0.162456 0.850654 -0.499995
v 0.894426 0.447216 0.000000
v 0.688189 0.525736 -0.499997
v 0.525730 0.850652 0.000000
v 0.162456 0.850654 0.499995
v -0.425323 0.850654 0.309011
v -0.425323 0.850654 -0.309011
v 0.162456 0.850654 -0.499995
v 0.000000 1.000000 0.000000
vn 0.1024 -0.9435 0.3151
vn 0.7002 -0.6617 0.2680
vn -0.2680 -0.9435 0.1947
vn -0.2680 -0.9435 -0.1947
vn 0.1024 -0.9435 -0.3151
vn 0.9050 -0.3304 0.2680
vn 0.0247 -0.3304 0.9435
vn -0.8897 -0.3304 0.3151
vn -0.5746 -0.3304 -0.7488
vn 0.5346 -0.3304 -0.7779
vn 0.8026 -0.1256 0.5831
vn -0.3066 -0.1256 0.9435
vn -0.9921 -0.1256 -0.0000
vn -0.3066 -0.1256 -0.9435
vn 0.8026 -0.1256 -0.5831
vn 0.4089 0.6617 0.6284
vn -0.4713 0.6617 0.5831
vn -0.7002 0.6617 -0.2680
vn 0.0385 0.6617 -0.7488
vn 0.7240 0.6617 -0.1947
vn -0.0385 -0.6617 0.7488
vn 0.1876 -0.7947 0.5773
vn 0.4713 -0.6617 0.5831
vn 0.7002 -0.6617 -0.2680
vn 0.6071 -0.7947 0.0000
vn 0.3313 -0.9435 -0.0000
vn -0.7240 -0.6617 0.1947
vn -0.4911 -0.7947 0.3568
vn -0.4089 -0.6617 0.6284
vn -0.4089 -0.6617 -0.6284
vn -0.4911 -0.7947 -0.3568
vn -0.7240 -0.6617 -0.1947
vn 0.4713 -0.6617 -0.5831
vn 0.1876 -0.7947 -0.5773
vn -0.0385 -0.6617 -0.7488
vn 0.9921 0.1256 0.0000
vn 0.9822 -0.1876 -0.0000
vn 0.9050 -0.3304 -0.2680
vn 0.3066 0.1256 0.9435
vn 0.3035 -0.1876 0.9342
vn 0.5346 -0.3304 0.7779
vn -0.8026 0.1256 0.5831
vn -0.7947 -0.1876 0.5773
vn -0.5746 -0.3304 0.7488
vn -0.8026 0.1256 -0.5831
vn -0.7947 -0.1876 -0.5773
vn -0.8897 -0.3304 -0.3151
vn 0.3066 0.1256 -0.9435
vn 0.3035 -0.1876 -0.9342
vn 0.0247 -0.3304 -0.9435
vn 0.5746 0.3304 0.7488
vn 0.7947 0.1876 0.5773
vn 0.8897 0.3304 0.3151
vn -0.5346 0.3304 0.7779
vn -0.3035 0.1876 0.9342
vn -0.0247 0.3304 0.9435
vn -0.9050 0.3304 -0.2680
vn -0.9822 0.1876 0.0000
vn -0.9050 0.3304 0.2680
vn -0.0247 0.3304 -0.9435
vn -0.3035 0.1876 -0.9342
vn -0.5346 0.3304 -0.7779
vn 0.8897 0.3304 -0.3151
vn 0.7947 0.1876 -0.5773
vn 0.5746 0.3304 -0.7488
vn 0.2680 0.9435 0.1947
vn 0.4911 0.7947 0.3568
vn 0.7240 0.6617 0.1947
vn -0.1024 0.9435 0.3151
vn -0.1876 0.7947 0.5773
vn 0.0385 0.6617 0.7488
vn -0.3313 0.9435 0.0000
vn -0.6071 0.7947 0.0000
vn -0.7002 0.6617 0.2680
vn -0.1024 0.9435 -0.3151
vn -0.1876 0.7947 -0.5773
vn -0.4713 0.6617 -0.5831
vn 0.2680 0.9435 -0.1947
vn 0.4911 0.7947 -0.3568
vn 0.4089 0.6617 -0.6284
s off
f 1 13 15
f 2 13 17
f 1 15 19
f 1 19 21
f 1 21 16
f 2 17 24
f 3 14 26
f 4 18 28
f 5 20 30
f 6 22 32
f 2 24 25
f 3 26 27
f 4 28 29
f 5 30 31
f 6 32 23
f 7 33 39
f 8 34 40
f 9 35 41
f 10 36 42
f 11 37 38
f 15 14 3
f 15 13 14
f 13 2 14
f 17 16 6
f 17 13 16
f 13 1 16
f 19 18 4
f 19 15 18
f 15 3 18
f 21 20 5
f 21 19 20
f 19 4 20
f 16 22 6
f 16 21 22
f 21 5 22
f 24 23 11
f 24 17 23
f 17 6 23
f 26 25 7
f 26 14 25
f 14 2 25
f 28 27 8
f 28 18 27
f 18 3 27
f 30 29 9
f 30 20 29
f 20 4 29
f 32 31 10
f 32 22 31
f 22 5 31
f 25 33 7
f 25 24 33
f 24 11 33
f 27 34 8
f 27 26 34
f 26 7 34
f 29 35 9
f 29 28 35
f 28 8 35
f 31 36 10
f 31 30 36
f 30 9 36
f 23 37 11
f 23 32 37
f 32 10 37
f 39 38 12
f 39 33 38
f 33 11 38
f 40 39 12
f 40 34 39
f 34 7 39
f 41 40 12
f 41 35 40
f 35 8 40
f 42 41 12
f 42 36 41
f 36 9 41
f 38 42 12
f 38 37 42
f 37 10 42
f 1//1 2//1 3//1
f 4//2 2//2 5//2
f 1//3 3//3 6//3
f 1//4 6//4 7//4
f 1//5 7//5 8//5
f 4//6 5//6 9//6
f 10//7 11//7 12//7
f 13//8 14//8 15//8
f 16//9 17//9 18//9
f 19//10 20//10 21//10
f 4//11 9//11 22//11
f 10//12 12//12 23//12
f 13//13 15//13 24//13
f 16//14 18//14 25//14
f 19//15 21//15 26//15
f 27//16 28//16 29//16
f 30//17 31//17 32//17
f 33//18 34//18 35//18
f 36//19 37//19 38//19
f 39//20 40//20 41//20
f 3//21 11//21 10//21
f 3//22 2//22 11//22
f 2//23 4//23 11//23
f 5//24 8//24 19//24
f 5//25 2//25 8//25
f 2//26 1//26 8//26
f 6//27 14//27 13//27
f 6//28 3//28 14//28
f 3//29 10//29 14//29
f 7//30 17//30 16//30
f 7//31 6//31 17//31
f 6//32 13//32 17//32
f 8//33 20//33 19//33
f 8//34 7//34 20//34
f 7//35 16//35 20//35
f 9//36 26//36 39//36
f 9//37 5//37 26//37
f 5//38 19//38 26//38
f 12//39 22//39 27//39
f 12//40 11//40 22//40
f 11//41 4//41 22//41
f 15//42 23//42 30//42
f 15//43 14//43 23//43
f 14//44 10//44 23//44
f 18//45 24//45 33//45
f 18//46 17//46 24//46
f 17//47 13//47 24//47
f 21//48 25//48 36//48
f 21//49 20//49 25//49
f 20//50 16//50 25//50
f 22//51 28//51 27//51
f 22//52 9//52 28//52
f 9//53 39//53 28//53
f 23//54 31//54 30//54
f 23//55 12//55 31//55
f 12//56 27//56 31//56
f 24//57 34//57 33//57
f 24//58 15//58 34//58
f 15//59 30//59 34//59
f 25//60 37//60 36//60
f 25//61 18//61 37//61
f 18//62 33//62 37//62
f 26//63 40//63 39//63
f 26//64 21//64 40//64
f 21//65 36//65 40//65
f 29//66 41//66 42//66
f 29//67 28//67 41//67
f 28//68 39//68 41//68
f 32//69 29//69 42//69
f 32//70 31//70 29//70
f 31//71 27//71 29//71
f 35//72 32//72 42//72
f 35//73 34//73 32//73
f 34//74 30//74 32//74
f 38//75 35//75 42//75
f 38//76 37//76 35//76
f 37//77 33//77 35//77
f 41//78 38//78 42//78
f 41//79 40//79 38//79
f 40//80 36//80 38//80

View File

@ -1,17 +1,43 @@
# Blender v2.72 (sub 0) OBJ File: ''
# Blender v2.80 (sub 75) OBJ File: ''
# www.blender.org
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.375000 0.750000
vt 0.125000 0.750000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
s off
f 5 6 2 1
f 6 7 3 2
f 7 8 4 3
f 8 5 1 4
f 1 2 3 4
f 8 7 6 5
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/6/2 7/7/2 8/8/2
f 8/8/3 7/7/3 5/9/3 6/10/3
f 6/10/4 2/11/4 4/12/4 8/13/4
f 2/14/5 1/15/5 3/16/5 4/17/5
f 6/18/6 5/19/6 1/20/6 2/11/6

View File

@ -31,6 +31,8 @@
#include <cctype>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <tuple>
using namespace openglframework;
using namespace std;
@ -112,6 +114,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
std::vector<uint> normalsIndices;
std::vector<uint> uvsIndices;
// ---------- Collect the data from the file ---------- //
// For each line of the file
@ -142,7 +145,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
line = buffer;
found1 = (int)line.find("/");
bool isFaceQuad = false;
int foundNext = (int)line.substr(found1+1).find("/");
found2 = (int)line.substr(found1+1).find("/");
// If the face definition is of the form "f v1 v2 v3 v4"
if(found1 == string::npos) {
@ -150,11 +153,21 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
if (nbVertices == 4) isFaceQuad = true;
}
// If the face definition is of the form "f v1// v2// v3// v4//"
else if (foundNext == 0) {
else if (found2 == 0 && (int)line.substr(found1+found2+1).find(" ") == 0) {
int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4);
if (nbVertices == 4) isFaceQuad = true;
}
else { // If the face definition contains vertices and texture coordinates
else { // If the face definition contains vertices and (texture coordinates or normals)
tId1 = -1;
tId2 = -1;
tId3 = -1;
tId4 = -1;
nId1 = -1;
nId2 = -1;
nId3 = -1;
nId4 = -1;
//get the part of the string until the second index
tmp = line.substr(found1+1);
@ -166,6 +179,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
if(found2 == string::npos) {
int n = sscanf(buffer.c_str(), "%*s %d/%d %d/%d %d/%d %d/%d", &id1, &tId1, &id2, &tId2, &id3, &tId3, &id4, &tId4);
if (n == 8) isFaceQuad = true;
uvsIndices.push_back(tId1-1);
uvsIndices.push_back(tId2-1);
uvsIndices.push_back(tId3-1);
@ -174,8 +188,11 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
else {
tmp = line.substr(found1+1);
found2 = (int)tmp.find("/");
if (found2 > 1000) {
int test = 2;
}
// If the face definition is of the form "f vert1/normal1 vert2/normal2 ..."
// If the face definition is of the form "f vert1//normal1 vert2//normal2 ..."
if(found2 == 0) {
int n = sscanf(buffer.c_str(), "%*s %d//%d %d//%d %d//%d %d//%d", &id1, &nId1, &id2, &nId2, &id3, &nId3, &id4, &nId4);
if (n == 8) isFaceQuad = true;
@ -213,39 +230,84 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
// Destroy the current mesh
meshToCreate.destroy();
// This is used to create duplicate vertices if a vertex with index "i" from a face does not
// have same texture coordinates or normals as a previous vertex with index "i".
unordered_map<tuple<int, int, int>, uint> mapVertNormTexToVertexIndex;
// Mesh data
vector<std::vector<uint> > meshIndices;
vector<Vector3> meshVertices;
vector<Vector3> meshNormals;
if (!normals.empty()) meshNormals = vector<Vector3>(vertices.size(), Vector3(0, 0, 0));
//if (!normals.empty()) meshNormals = vector<Vector3>(vertices.size(), Vector3(0, 0, 0));
vector<Vector2> meshUVs;
if (!uvs.empty()) meshUVs = vector<Vector2>(vertices.size(), Vector2(0, 0));
//if (!uvs.empty()) meshUVs = vector<Vector2>(vertices.size(), Vector2(0, 0));
// We cannot load mesh with several parts for the moment
uint meshPart = 0;
const bool hasNormals = !normalsIndices.empty() && !normals.empty();
const bool hasUvs = !uvsIndices.empty() && !uvs.empty();
// Fill in the vertex indices
// We also triangulate each quad face
meshIndices.push_back(std::vector<uint>());
for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) {
// Get the current vertex IDs
uint i1 = verticesIndices[i];
uint i2 = verticesIndices[i+1];
uint i3 = verticesIndices[i+2];
// 3 if the current vertices form a triangle and 4 if they form a quad
const int nbVertices = isQuad[j] ? 4 : 3;
int newVerticesIndices[4] = { -1, -1, -1, -1 };
// For each vertex, we check if there is already a vertex with same UV and normals.
for (int v = 0; v < nbVertices; v++) {
int normalIndex = hasNormals ? normalsIndices[i + v] : -1;
int uvIndex = hasUvs ? uvsIndices[i + v] : -1;
// If the vertex with same UV and normal doesn't exist yet in the map
tuple<int, int, int> key = std::make_tuple(verticesIndices[i+v], normalIndex, uvIndex);
auto itFound = mapVertNormTexToVertexIndex.find(key);
if (itFound == mapVertNormTexToVertexIndex.end()) {
// Create a new vertex
newVerticesIndices[v]= meshVertices.size();
meshVertices.push_back(vertices[verticesIndices[i+v]]);
if (hasNormals) {
meshNormals.push_back(normals[normalsIndices[i+v]]);
}
if (hasUvs) {
meshUVs.push_back(uvs[uvsIndices[i+v]]);
}
mapVertNormTexToVertexIndex.insert(std::make_pair(key, newVerticesIndices[v]));
}
else {
// Get the vertex index to use
newVerticesIndices[v] = itFound->second;
}
}
// Get the current vertex IDs
uint i1 = newVerticesIndices[0];
uint i2 = newVerticesIndices[1];
uint i3 = newVerticesIndices[2];
uint i4 = newVerticesIndices[3];
/*
// Add the vertex normal
if (!normalsIndices.empty() && !normals.empty()) {
if (hasNormals) {
meshNormals[i1] = normals[normalsIndices[i]];
meshNormals[i2] = normals[normalsIndices[i+1]];
meshNormals[i3] = normals[normalsIndices[i+2]];
}
// Add the vertex UV texture coordinates
if (!uvsIndices.empty() && !uvs.empty()) {
if (hasUvs) {
meshUVs[i1] = uvs[uvsIndices[i]];
meshUVs[i2] = uvs[uvsIndices[i+1]];
meshUVs[i3] = uvs[uvsIndices[i+2]];
}
*/
// If the current vertex not in a quad (it is part of a triangle)
if (!isQuad[j]) {
@ -259,11 +321,10 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
}
else { // If the current vertex is in a quad
Vector3 v1 = vertices[i1];
Vector3 v2 = vertices[i2];
Vector3 v3 = vertices[i3];
uint i4 = verticesIndices[i+3];
Vector3 v4 = vertices[i4];
Vector3 v1 = meshVertices[i1];
Vector3 v2 = meshVertices[i2];
Vector3 v3 = meshVertices[i3];
Vector3 v4 = meshVertices[i4];
Vector3 v13 = v3-v1;
Vector3 v12 = v2-v1;
@ -288,6 +349,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
meshIndices[meshPart].push_back(i4);
}
/*
// Add the vertex normal
if (!normalsIndices.empty() && !normals.empty()) {
meshNormals[i4] = normals[normalsIndices[i]];
@ -297,17 +359,18 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
if (!uvsIndices.empty() && !uvs.empty()) {
meshUVs[i4] = uvs[uvsIndices[i]];
}
*/
i+=4;
}
}
assert(meshNormals.empty() || meshNormals.size() == vertices.size());
assert(meshUVs.empty() || meshUVs.size() == vertices.size());
assert(meshNormals.empty() || meshNormals.size() == meshVertices.size());
assert(meshUVs.empty() || meshUVs.size() == meshVertices.size());
// Set the data to the mesh
meshToCreate.setIndices(meshIndices);
meshToCreate.setVertices(vertices);
meshToCreate.setVertices(meshVertices);
meshToCreate.setNormals(meshNormals);
meshToCreate.setUVs(meshUVs);
}

View File

@ -93,4 +93,15 @@ class VertexMergingDataComparison {
}
namespace std {
template<>
struct hash<std::tuple<int, int, int>>
{
size_t operator()(const std::tuple<int, int, int>& key) const
{
return std::get<0>(key) ^ std::get<1>(key) ^ std::get<2>(key);
}
};
}
#endif

View File

@ -95,6 +95,11 @@ class Shader {
// to set it, an assert will occur)
void setIntUniform(const std::string& variableName, int value, bool errorIfMissing = true) const;
// Set an array of int uniform values to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try
// to set it, an assert will occur)
void setIntArrayUniform(const std::string& variableName, GLint* values, int nbValues, bool errorIfMissing = true) const;
// Set a vector 2 uniform value to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try
// to set it, an assert will occur)
@ -159,7 +164,7 @@ inline GLint Shader::getUniformLocation(const std::string& variableName, bool er
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
<< std::endl;
throw std::logic_error("Error in Shader");
//throw std::logic_error("Error in Shader");
}
return location;
@ -209,6 +214,16 @@ inline void Shader::setIntUniform(const std::string& variableName, int value, bo
}
}
// Set an array of int uniform values to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try
// to set it, an assert will occur)
inline void Shader::setIntArrayUniform(const std::string& variableName, GLint* values, int nbValues, bool errorIfMissing) const {
assert(mProgramObjectID != 0);
GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform1iv(location, nbValues, values);
}
}
// Set a vector 2 uniform value to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try
// to set it, an assert will occur)

View File

@ -1,345 +1,345 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2016 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "CollisionDetectionScene.h"
#include "constraint/ContactPoint.h"
#include "collision/ContactManifold.h"
// Namespaces
using namespace openglframework;
using namespace collisiondetectionscene;
// Constructor
CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
mContactManager(mPhongShader, mMeshFolderPath, mContactPoints),
mAreNormalsDisplayed(false) {
mSelectedShapeIndex = 0;
mIsContactPointsDisplayed = true;
mIsWireframeEnabled = true;
// Compute the radius and the center of the scene
openglframework::Vector3 center(0, 0, 0);
// Set the center of the scene
setScenePosition(center, SCENE_RADIUS);
rp3d::WorldSettings worldSettings;
worldSettings.worldName = name;
// Create the dynamics world for the physics simulation
mPhysicsWorld = mPhysicsCommon.createCollisionWorld(worldSettings);
// ---------- Sphere 1 ---------- //
// Create a sphere and a corresponding collision body in the dynamics world
mSphere1 = new Sphere(4, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mSphere1);
// Set the color
mSphere1->setColor(mGreyColorDemo);
mSphere1->setSleepingColor(mRedColorDemo);
//mSphere1->setScaling(0.5f);
mPhysicsObjects.push_back(mSphere1);
// ---------- Sphere 2 ---------- //
// Create a sphere and a corresponding collision body in the dynamics world
mSphere2 = new Sphere(2, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mSphere2);
// Set the color
mSphere2->setColor(mGreyColorDemo);
mSphere2->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mSphere2);
// ---------- Capsule 1 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule1);
// Set the color
mCapsule1->setColor(mGreyColorDemo);
mCapsule1->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mCapsule1);
// ---------- Capsule 2 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule2);
// Set the color
mCapsule2->setColor(mGreyColorDemo);
mCapsule2->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mCapsule2);
// ---------- Concave Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the dynamics world
mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
mAllShapes.push_back(mConcaveMesh);
// Set the color
mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Box 1 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mBox1 = new Box(BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mBox1);
// Set the color
mBox1->setColor(mGreyColorDemo);
mBox1->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mBox1);
// ---------- Box 2 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mBox2);
// Set the color
mBox2->setColor(mGreyColorDemo);
mBox2->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mBox2);
// ---------- Convex Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the dynamics world
mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
mAllShapes.push_back(mConvexMesh);
// Set the color
mConvexMesh->setColor(mGreyColorDemo);
mConvexMesh->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mConvexMesh);
// ---------- Heightfield ---------- //
// Create a convex mesh and a corresponding collision body in the dynamics world
mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld);
// Set the color
mHeightField->setColor(mGreyColorDemo);
mHeightField->setSleepingColor(mRedColorDemo);
mPhysicsObjects.push_back(mHeightField);
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
}
// Reset the scene
void CollisionDetectionScene::reset() {
SceneDemo::reset();
mSphere1->setTransform(rp3d::Transform(rp3d::Vector3(15, 5, 0), rp3d::Quaternion::identity()));
mSphere2->setTransform(rp3d::Transform(rp3d::Vector3(0, 6, 0), rp3d::Quaternion::identity()));
mCapsule1->setTransform(rp3d::Transform(rp3d::Vector3(-8, 7, 0), rp3d::Quaternion::identity()));
mCapsule2->setTransform(rp3d::Transform(rp3d::Vector3(11, -8, 0), rp3d::Quaternion::identity()));
mBox1->setTransform(rp3d::Transform(rp3d::Vector3(-4, -7, 0), rp3d::Quaternion::identity()));
mBox2->setTransform(rp3d::Transform(rp3d::Vector3(0, 9, 0), rp3d::Quaternion::identity()));
mConvexMesh->setTransform(rp3d::Transform(rp3d::Vector3(-5, 0, 0), rp3d::Quaternion::identity()));
mConcaveMesh->setTransform(rp3d::Transform(rp3d::Vector3(0, 15, 0), rp3d::Quaternion::identity()));
mHeightField->setTransform(rp3d::Transform(rp3d::Vector3(0, -22, 0), rp3d::Quaternion::identity()));
}
// Destructor
CollisionDetectionScene::~CollisionDetectionScene() {
// Destroy the box rigid body from the dynamics world
//mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody());
//delete mBox;
// Destroy the spheres
mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody());
delete mSphere1;
mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody());
delete mSphere2;
mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody());
delete mCapsule1;
mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody());
delete mCapsule2;
mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody());
delete mBox1;
mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody());
delete mBox2;
mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody());
delete mConvexMesh;
mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody());
delete mConcaveMesh;
mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
delete mHeightField;
// Destroy the static data for the visual contact points
VisualContactPoint::destroyStaticData();
// Destroy the collision world
mPhysicsCommon.destroyCollisionWorld(mPhysicsWorld);
}
// Take a step for the simulation
void CollisionDetectionScene::update() {
mContactPoints.clear();
mPhysicsWorld->testCollision(mContactManager);
SceneDemo::update();
}
void CollisionDetectionScene::selectNextShape() {
uint previousIndex = mSelectedShapeIndex;
mSelectedShapeIndex++;
if (mSelectedShapeIndex >= mAllShapes.size()) {
mSelectedShapeIndex = 0;
}
mAllShapes[previousIndex]->setColor(mGreyColorDemo);
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
}
// Called when a keyboard event occurs
bool CollisionDetectionScene::keyboardEvent(int key, int scancode, int action, int mods) {
// If the space key has been pressed
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
selectNextShape();
return true;
}
float stepDist = 0.2f;
float stepAngle = 15 * (3.14f / 180.0f);
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(stepDist, 0, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(-stepDist, 0, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_UP && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, stepDist, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, -stepDist, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_Z && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, stepDist));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_H && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, -stepDist));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_A && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, stepAngle, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_D && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, -stepAngle, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_W && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(stepAngle, 0, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_S && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(-stepAngle, 0, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_F && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, stepAngle) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_G && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, -stepAngle) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
return false;
}
// This method is called when some contacts occur
void ContactManager::onContact(const CallbackData& callbackData) {
// For each contact pair
for (uint p=0; p < callbackData.getNbContactPairs(); p++) {
ContactPair contactPair = callbackData.getContactPair(p);
// For each contact point of the contact pair
for (uint c=0; c < contactPair.getNbContactPoints(); c++) {
ContactPoint contactPoint = contactPair.getContactPoint(c);
// Contact normal
rp3d::Vector3 normal = contactPoint.getWorldNormal();
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
rp3d::Vector3 point1 = contactPoint.getLocalPointOnShape1();
point1 = contactPair.getProxyShape1()->getLocalToWorldTransform() * point1;
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
mContactPoints.push_back(SceneContactPoint(position1, contactNormal, openglframework::Color::red()));
rp3d::Vector3 point2 = contactPoint.getLocalPointOnShape2();
point2 = contactPair.getProxyShape2()->getLocalToWorldTransform() * point2;
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
mContactPoints.push_back(SceneContactPoint(position2, contactNormal, openglframework::Color::blue()));
}
}
}
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2016 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "CollisionDetectionScene.h"
#include "constraint/ContactPoint.h"
#include "collision/ContactManifold.h"
// Namespaces
using namespace openglframework;
using namespace collisiondetectionscene;
// Constructor
CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
mContactManager(mPhongShader, mMeshFolderPath, mContactPoints),
mAreNormalsDisplayed(false) {
mSelectedShapeIndex = 0;
mIsContactPointsDisplayed = true;
mIsWireframeEnabled = true;
// Compute the radius and the center of the scene
openglframework::Vector3 center(0, 0, 0);
// Set the center of the scene
setScenePosition(center, SCENE_RADIUS);
rp3d::WorldSettings worldSettings;
worldSettings.worldName = name;
// Create the dynamics world for the physics simulation
mPhysicsWorld = mPhysicsCommon.createCollisionWorld(worldSettings);
// ---------- Sphere 1 ---------- //
// Create a sphere and a corresponding collision body in the dynamics world
mSphere1 = new Sphere(4, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mSphere1);
// Set the color
mSphere1->setColor(mObjectColorDemo);
mSphere1->setSleepingColor(mSleepingColorDemo);
//mSphere1->setScaling(0.5f);
mPhysicsObjects.push_back(mSphere1);
// ---------- Sphere 2 ---------- //
// Create a sphere and a corresponding collision body in the dynamics world
mSphere2 = new Sphere(2, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mSphere2);
// Set the color
mSphere2->setColor(mObjectColorDemo);
mSphere2->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mSphere2);
// ---------- Capsule 1 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule1);
// Set the color
mCapsule1->setColor(mObjectColorDemo);
mCapsule1->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mCapsule1);
// ---------- Capsule 2 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mCapsule2);
// Set the color
mCapsule2->setColor(mObjectColorDemo);
mCapsule2->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mCapsule2);
// ---------- Concave Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the dynamics world
mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
mAllShapes.push_back(mConcaveMesh);
// Set the color
mConcaveMesh->setColor(mObjectColorDemo);
mConcaveMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Box 1 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mBox1 = new Box(BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mBox1);
// Set the color
mBox1->setColor(mObjectColorDemo);
mBox1->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mBox1);
// ---------- Box 2 ---------- //
// Create a cylinder and a corresponding collision body in the dynamics world
mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
mAllShapes.push_back(mBox2);
// Set the color
mBox2->setColor(mObjectColorDemo);
mBox2->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mBox2);
// ---------- Convex Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the dynamics world
mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
mAllShapes.push_back(mConvexMesh);
// Set the color
mConvexMesh->setColor(mObjectColorDemo);
mConvexMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConvexMesh);
// ---------- Heightfield ---------- //
// Create a convex mesh and a corresponding collision body in the dynamics world
mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld);
// Set the color
mHeightField->setColor(mObjectColorDemo);
mHeightField->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mHeightField);
mAllShapes[mSelectedShapeIndex]->setColor(mObjectColorDemo);
}
// Reset the scene
void CollisionDetectionScene::reset() {
SceneDemo::reset();
mSphere1->setTransform(rp3d::Transform(rp3d::Vector3(15, 5, 0), rp3d::Quaternion::identity()));
mSphere2->setTransform(rp3d::Transform(rp3d::Vector3(0, 6, 0), rp3d::Quaternion::identity()));
mCapsule1->setTransform(rp3d::Transform(rp3d::Vector3(-8, 7, 0), rp3d::Quaternion::identity()));
mCapsule2->setTransform(rp3d::Transform(rp3d::Vector3(11, -8, 0), rp3d::Quaternion::identity()));
mBox1->setTransform(rp3d::Transform(rp3d::Vector3(-4, -7, 0), rp3d::Quaternion::identity()));
mBox2->setTransform(rp3d::Transform(rp3d::Vector3(0, 9, 0), rp3d::Quaternion::identity()));
mConvexMesh->setTransform(rp3d::Transform(rp3d::Vector3(-5, 0, 0), rp3d::Quaternion::identity()));
mConcaveMesh->setTransform(rp3d::Transform(rp3d::Vector3(0, 15, 0), rp3d::Quaternion::identity()));
mHeightField->setTransform(rp3d::Transform(rp3d::Vector3(0, -22, 0), rp3d::Quaternion::identity()));
}
// Destructor
CollisionDetectionScene::~CollisionDetectionScene() {
// Destroy the box rigid body from the dynamics world
//mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody());
//delete mBox;
// Destroy the spheres
mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody());
delete mSphere1;
mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody());
delete mSphere2;
mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody());
delete mCapsule1;
mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody());
delete mCapsule2;
mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody());
delete mBox1;
mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody());
delete mBox2;
mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody());
delete mConvexMesh;
mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody());
delete mConcaveMesh;
mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
delete mHeightField;
// Destroy the static data for the visual contact points
VisualContactPoint::destroyStaticData();
// Destroy the collision world
mPhysicsCommon.destroyCollisionWorld(mPhysicsWorld);
}
// Take a step for the simulation
void CollisionDetectionScene::update() {
mContactPoints.clear();
mPhysicsWorld->testCollision(mContactManager);
SceneDemo::update();
}
void CollisionDetectionScene::selectNextShape() {
uint previousIndex = mSelectedShapeIndex;
mSelectedShapeIndex++;
if (mSelectedShapeIndex >= mAllShapes.size()) {
mSelectedShapeIndex = 0;
}
mAllShapes[previousIndex]->setColor(mObjectColorDemo);
mAllShapes[mSelectedShapeIndex]->setColor(mSelectedObjectColorDemo);
}
// Called when a keyboard event occurs
bool CollisionDetectionScene::keyboardEvent(int key, int scancode, int action, int mods) {
// If the space key has been pressed
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
selectNextShape();
return true;
}
float stepDist = 0.2f;
float stepAngle = 15 * (3.14f / 180.0f);
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(stepDist, 0, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(-stepDist, 0, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_UP && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, stepDist, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, -stepDist, 0));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_Z && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, stepDist));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_H && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, -stepDist));
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_A && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, stepAngle, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_D && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, -stepAngle, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_W && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(stepAngle, 0, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_S && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(-stepAngle, 0, 0) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_F && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, stepAngle) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
else if (key == GLFW_KEY_G && action == GLFW_PRESS) {
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, -stepAngle) * transform.getOrientation());
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
}
return false;
}
// This method is called when some contacts occur
void ContactManager::onContact(const CallbackData& callbackData) {
// For each contact pair
for (uint p=0; p < callbackData.getNbContactPairs(); p++) {
ContactPair contactPair = callbackData.getContactPair(p);
// For each contact point of the contact pair
for (uint c=0; c < contactPair.getNbContactPoints(); c++) {
ContactPoint contactPoint = contactPair.getContactPoint(c);
// Contact normal
rp3d::Vector3 normal = contactPoint.getWorldNormal();
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
rp3d::Vector3 point1 = contactPoint.getLocalPointOnShape1();
point1 = contactPair.getProxyShape1()->getLocalToWorldTransform() * point1;
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
mContactPoints.push_back(SceneContactPoint(position1, contactNormal, openglframework::Color::red()));
rp3d::Vector3 point2 = contactPoint.getLocalPointOnShape2();
point2 = contactPair.getProxyShape2()->getLocalToWorldTransform() * point2;
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
mContactPoints.push_back(SceneContactPoint(position2, contactNormal, openglframework::Color::blue()));
}
}
}

View File

@ -59,8 +59,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
Dumbbell* dumbbell = new Dumbbell(mPhysicsCommon, getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -78,8 +78,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -100,8 +100,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -122,8 +122,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -141,8 +141,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -159,8 +159,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
mPhysicsObjects.push_back(mFloor);
// Set the box color
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -60,8 +60,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
Dumbbell* dumbbell = new Dumbbell(mPhysicsCommon, getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -79,8 +79,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -101,8 +101,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -123,8 +123,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -142,8 +142,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -166,8 +166,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);
// Set the box color
mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mGreyColorDemo);
mConcaveMesh->setColor(mFloorColorDemo);
mConcaveMesh->setSleepingColor(mFloorColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);

View File

@ -1,143 +1,141 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2016 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "CubesScene.h"
// Namespaces
using namespace openglframework;
using namespace cubesscene;
// Constructor
CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, settings, SCENE_RADIUS) {
// Compute the radius and the center of the scene
openglframework::Vector3 center(0, 5, 0);
// Set the center of the scene
setScenePosition(center, SCENE_RADIUS);
// Gravity vector in the dynamics world
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
rp3d::WorldSettings worldSettings;
worldSettings.worldName = name;
// Create the dynamics world for the physics simulation
rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings);
dynamicsWorld->setEventListener(this);
mPhysicsWorld = dynamicsWorld;
// Create all the cubes of the scene
for (int i=0; i<NB_CUBES; i++) {
// Create a cube and a corresponding rigid in the dynamics world
Box* cube = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
cube->setColor(mDemoColors[i % mNbDemoColors]);
cube->setSleepingColor(mRedColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial();
material.setBounciness(rp3d::decimal(0.4));
// Add the box the list of box in the scene
mBoxes.push_back(cube);
mPhysicsObjects.push_back(cube);
}
// ------------------------- FLOOR ----------------------- //
// Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
mPhysicsObjects.push_back(mFloor);
// Get the physics engine parameters
mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
}
// Destructor
CubesScene::~CubesScene() {
// Destroy all the cubes of the scene
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
// Destroy the corresponding rigid body from the dynamics world
getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
// Destroy the cube
delete (*it);
}
// Destroy the rigid body of the floor
getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody());
// Destroy the floor
delete mFloor;
// Destroy the dynamics world
mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld());
}
// Reset the scene
void CubesScene::reset() {
SceneDemo::reset();
float radius = 2.0f;
// Create all the cubes of the scene
std::vector<Box*>::iterator it;
int i = 0;
for (it = mBoxes.begin(); it != mBoxes.end(); ++it) {
// Position of the cubes
float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
10 + i * (BOX_SIZE.y + 0.3f),
0);
(*it)->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
i++;
}
mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
}
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2016 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "CubesScene.h"
// Namespaces
using namespace openglframework;
using namespace cubesscene;
// Constructor
CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
: SceneDemo(name, settings, SCENE_RADIUS) {
// Compute the radius and the center of the scene
openglframework::Vector3 center(0, 5, 0);
// Set the center of the scene
setScenePosition(center, SCENE_RADIUS);
// Gravity vector in the dynamics world
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
rp3d::WorldSettings worldSettings;
worldSettings.worldName = name;
// Create the dynamics world for the physics simulation
rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings);
dynamicsWorld->setEventListener(this);
mPhysicsWorld = dynamicsWorld;
// Create all the cubes of the scene
for (int i=0; i<NB_CUBES; i++) {
// Create a cube and a corresponding rigid in the dynamics world
Box* cube = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
cube->setColor(mObjectColorDemo);
cube->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial();
material.setBounciness(rp3d::decimal(0.4));
// Add the box the list of box in the scene
mBoxes.push_back(cube);
mPhysicsObjects.push_back(cube);
}
// ------------------------- FLOOR ----------------------- //
// Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
mPhysicsObjects.push_back(mFloor);
// Get the physics engine parameters
mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
}
// Destructor
CubesScene::~CubesScene() {
// Destroy all the cubes of the scene
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
// Destroy the corresponding rigid body from the dynamics world
getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
// Destroy the cube
delete (*it);
}
// Destroy the rigid body of the floor
getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody());
// Destroy the floor
delete mFloor;
// Destroy the dynamics world
mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld());
}
// Reset the scene
void CubesScene::reset() {
float radius = 2.0f;
// Create all the cubes of the scene
std::vector<Box*>::iterator it;
int i = 0;
for (it = mBoxes.begin(); it != mBoxes.end(); ++it) {
// Position of the cubes
float angle = i * 30.0f;
rp3d::Vector3 position(radius * std::cos(angle),
10 + i * (BOX_SIZE.y + 0.3f),
0);
(*it)->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
i++;
}
mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
}

View File

@ -60,8 +60,8 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
Box* cube = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
cube->setColor(mDemoColors[i % mNbDemoColors]);
cube->setSleepingColor(mRedColorDemo);
cube->setColor(mObjectColorDemo);
cube->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial();
@ -77,8 +77,8 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
// Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -59,8 +59,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
Dumbbell* dumbbell = new Dumbbell(mPhysicsCommon, getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -78,8 +78,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -100,8 +100,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
sphere->getRigidBody()->getMaterial().setRollingResistance(0.08f);
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -122,8 +122,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f);
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -141,8 +141,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -167,8 +167,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
mPhysicsObjects.push_back(mHeightField);
// Set the color
mHeightField->setColor(mGreyColorDemo);
mHeightField->setSleepingColor(mGreyColorDemo);
mHeightField->setColor(mFloorColorDemo);
mHeightField->setSleepingColor(mFloorColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mHeightField->getRigidBody()->getMaterial();

View File

@ -218,8 +218,8 @@ void JointsScene::createBallAndSocketJoints() {
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
// Set the box color
mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]);
mBallAndSocketJointChainBoxes[i]->setSleepingColor(mRedColorDemo);
mBallAndSocketJointChainBoxes[i]->setColor(mObjectColorDemo);
mBallAndSocketJointChainBoxes[i]->setSleepingColor(mSleepingColorDemo);
// The fist box cannot move (static body)
if (i == 0) {
@ -270,8 +270,8 @@ void JointsScene::createSliderJoint() {
mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color
mSliderJointBottomBox->setColor(mBlueColorDemo);
mSliderJointBottomBox->setSleepingColor(mRedColorDemo);
mSliderJointBottomBox->setColor(mObjectColorDemo);
mSliderJointBottomBox->setSleepingColor(mSleepingColorDemo);
// The fist box cannot move
mSliderJointBottomBox->getRigidBody()->setType(rp3d::BodyType::STATIC);
@ -292,8 +292,8 @@ void JointsScene::createSliderJoint() {
mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
// Set the box color
mSliderJointTopBox->setColor(mOrangeColorDemo);
mSliderJointTopBox->setSleepingColor(mRedColorDemo);
mSliderJointTopBox->setColor(mObjectColorDemo);
mSliderJointTopBox->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
@ -334,8 +334,8 @@ void JointsScene::createPropellerHingeJoint() {
mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color
mPropellerBox->setColor(mYellowColorDemo);
mPropellerBox->setSleepingColor(mRedColorDemo);
mPropellerBox->setColor(mObjectColorDemo);
mPropellerBox->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
@ -375,8 +375,8 @@ void JointsScene::createFixedJoints() {
mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color
mFixedJointBox1->setColor(mPinkColorDemo);
mFixedJointBox1->setSleepingColor(mRedColorDemo);
mFixedJointBox1->setColor(mObjectColorDemo);
mFixedJointBox1->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
@ -393,8 +393,8 @@ void JointsScene::createFixedJoints() {
mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
// Set the box color
mFixedJointBox2->setColor(mBlueColorDemo);
mFixedJointBox2->setSleepingColor(mRedColorDemo);
mFixedJointBox2->setColor(mObjectColorDemo);
mFixedJointBox2->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
@ -433,8 +433,8 @@ void JointsScene::createFloor() {
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -57,8 +57,8 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
Dumbbell* dumbbell = new Dumbbell(mPhysicsCommon, getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -76,8 +76,8 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
Box* box = new Box(BOX_SIZE, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -98,8 +98,8 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -120,8 +120,8 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -139,8 +139,8 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -163,8 +163,8 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC);
// Set the box color
mSandbox->setColor(mGreyColorDemo);
mSandbox->setSleepingColor(mGreyColorDemo);
mSandbox->setColor(mFloorColorDemo);
mSandbox->setSleepingColor(mFloorColorDemo);
mPhysicsObjects.push_back(mSandbox);

View File

@ -56,8 +56,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mDumbbell = new Dumbbell(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the box color
mDumbbell->setColor(mGreyColorDemo);
mDumbbell->setSleepingColor(mRedColorDemo);
mDumbbell->setColor(mObjectColorDemo);
mDumbbell->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mDumbbell);
// ---------- Box ---------- //
@ -67,8 +67,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mBox->getCollisionBody()->setIsActive(false);
// Set the box color
mBox->setColor(mGreyColorDemo);
mBox->setSleepingColor(mRedColorDemo);
mBox->setColor(mObjectColorDemo);
mBox->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mBox);
// ---------- Sphere ---------- //
@ -77,8 +77,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mSphere = new Sphere(SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the color
mSphere->setColor(mGreyColorDemo);
mSphere->setSleepingColor(mRedColorDemo);
mSphere->setColor(mObjectColorDemo);
mSphere->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mSphere);
// ---------- Capsule ---------- //
@ -88,8 +88,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath);
// Set the color
mCapsule->setColor(mGreyColorDemo);
mCapsule->setSleepingColor(mRedColorDemo);
mCapsule->setColor(mObjectColorDemo);
mCapsule->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mCapsule);
// ---------- Convex Mesh ---------- //
@ -98,8 +98,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
// Set the color
mConvexMesh->setColor(mGreyColorDemo);
mConvexMesh->setSleepingColor(mRedColorDemo);
mConvexMesh->setColor(mObjectColorDemo);
mConvexMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConvexMesh);
// ---------- Concave Mesh ---------- //
@ -108,8 +108,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
// Set the color
mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mRedColorDemo);
mConcaveMesh->setColor(mObjectColorDemo);
mConcaveMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Heightfield ---------- //
@ -118,8 +118,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld);
// Set the color
mHeightField->setColor(mGreyColorDemo);
mHeightField->setSleepingColor(mRedColorDemo);
mHeightField->setColor(mObjectColorDemo);
mHeightField->setSleepingColor(mObjectColorDemo);
mPhysicsObjects.push_back(mHeightField);
// Create the lines that will be used for raycasting

View File

@ -1,103 +1,121 @@
#version 330
/********************************************************************************
* OpenGL-Framework *
* Copyright (c) 2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Uniform variables
uniform vec3 lightAmbientColor; // Lights ambient color
uniform vec3 light0PosCameraSpace; // Camera-space position of the light
uniform vec3 light0DiffuseColor; // Light 0 diffuse color
uniform sampler2D textureSampler; // Texture
uniform sampler2D shadowMapSampler; // Shadow map texture sampler
uniform bool isTexture; // True if we need to use the texture
uniform vec4 vertexColor; // Vertex color
uniform bool isShadowEnabled; // True if shadow mapping is enabled
uniform vec2 shadowMapDimension; // Shadow map dimension
// In variables
in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
in vec2 texCoords; // Texture coordinates
in vec4 shadowMapCoords; // Shadow map texture coords
// Out variable
out vec4 color; // Output color
// Texture for PCF Shadow mapping
float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset)
{
vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension;
return texture(map, texCoords.xy + offset * shadowMapScale).r;
}
void main() {
// Compute the ambient term
vec3 ambient = lightAmbientColor;
// Get the texture color
vec3 textureColor = vertexColor.rgb;
if (isTexture) textureColor = texture(textureSampler, texCoords).rgb;
// Compute the surface normal vector
vec3 N = normalize(vertexNormalCameraSpace);
// Compute the diffuse term of light 0
vec3 L0 = normalize(light0PosCameraSpace - vertexPosCameraSpace);
float diffuseFactor = max(dot(N, L0), 0.0);
vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor;
// Compute shadow factor
float shadow = 1.0;
if (isShadowEnabled) {
shadow = 0.0;
float bias = 0.0003;
float shadowBias = -0.000;
vec4 shadowMapUV = shadowMapCoords;
shadowMapUV.z -= shadowBias;
vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w;
// PCF Shadow Mapping
for (float i=-1; i<=1; i++) {
for (float j=-1; j<=1; j++) {
float distInShadowMap = textureLookupPCF(shadowMapSampler, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
if (shadowMapCoords.w > 0) {
shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
}
}
}
shadow /= 9.0;
/*
float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias;
if (shadowMapCoords.w > 0) {
shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
}
*/
}
// Compute the final color
color = vec4(ambient + shadow * diffuse, 1.0);
}
#version 330
/********************************************************************************
* OpenGL-Framework *
* Copyright (c) 2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Uniform variables
uniform vec3 lightAmbientColor; // Lights ambient color
uniform vec3 light0PosCameraSpace; // Camera-space position of the light 0
uniform vec3 light1PosCameraSpace; // Camera-space position of the light 1
uniform vec3 light2PosCameraSpace; // Camera-space position of the light 2
uniform vec3 light0DiffuseColor; // Light 0 diffuse color
uniform vec3 light1DiffuseColor; // Light 1 diffuse color
uniform vec3 light2DiffuseColor; // Light 2 diffuse color
uniform sampler2D textureSampler; // Texture
uniform sampler2D shadowMapSampler0; // Shadow map texture sampler
uniform sampler2D shadowMapSampler1; // Shadow map texture sampler
uniform sampler2D shadowMapSampler2; // Shadow map texture sampler
uniform bool isTexture; // True if we need to use the texture
uniform vec4 vertexColor; // Vertex color
uniform bool isShadowEnabled; // True if shadow mapping is enabled
uniform vec2 shadowMapDimension; // Shadow map dimension
// In variables
in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
in vec2 texCoords; // Texture coordinates
in vec4 shadowMapCoords[3]; // Shadow map texture coords
// Out variable
out vec4 color; // Output color
// Texture for PCF Shadow mapping
float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset)
{
vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension;
return texture(map, texCoords.xy + offset * shadowMapScale).r;
}
void main() {
// Compute the ambient term
vec3 ambient = lightAmbientColor;
// Get the texture color
vec3 textureColor = vertexColor.rgb;
if (isTexture) textureColor = texture(textureSampler, texCoords).rgb;
// Compute the surface normal vector
vec3 N = normalize(vertexNormalCameraSpace);
color = vec4(ambient, 1);
vec3 lightPosCameraSpace[3];
lightPosCameraSpace[0] = light0PosCameraSpace;
lightPosCameraSpace[1] = light1PosCameraSpace;
lightPosCameraSpace[2] = light2PosCameraSpace;
vec3 lightDiffuseColor[3];
lightDiffuseColor[0] = light0DiffuseColor;
lightDiffuseColor[1] = light1DiffuseColor;
lightDiffuseColor[2] = light2DiffuseColor;
// For each light source
for (int l=0; l < 3; l++) {
// Compute the diffuse term of light 0
vec3 L0 = normalize(lightPosCameraSpace[l] - vertexPosCameraSpace);
float diffuseFactor = max(dot(N, L0), 0.0);
vec3 diffuse = lightDiffuseColor[l] * diffuseFactor * textureColor;
// Compute shadow factor
float shadow = 1.0;
if (isShadowEnabled) {
shadow = 0.0;
float bias = 0.0003;
float shadowBias = -0.000;
vec4 shadowMapUV = shadowMapCoords[l];
shadowMapUV.z -= shadowBias;
vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w;
// PCF Shadow Mapping
for (float i=-1; i<=1; i++) {
for (float j=-1; j<=1; j++) {
float distInShadowMap0 = textureLookupPCF(shadowMapSampler0, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
float distInShadowMap1 = textureLookupPCF(shadowMapSampler1, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
float distInShadowMap2 = textureLookupPCF(shadowMapSampler2, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
float distInShadowMap = l == 0 ? distInShadowMap0 : (l == 1 ? distInShadowMap1 : distInShadowMap2);
if (shadowMapCoords[l].w > 0) {
shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
}
}
}
shadow /= 9.0;
}
// Compute the final color
color += vec4(shadow * diffuse, 0.0);
}
}

View File

@ -1,64 +1,78 @@
#version 330
/********************************************************************************
* OpenGL-Framework *
* Copyright (c) 2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Uniform variables
uniform mat4 localToWorldMatrix; // Local-space to world-space matrix
uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix
uniform mat4 worldToLight0CameraMatrix; // World-space to light0 camera-space matrix (for shadow mapping)
uniform mat4 projectionMatrix; // Projection matrix
uniform mat3 normalMatrix; // Normal matrix
uniform mat4 shadowMapProjectionMatrix; // Shadow map projection matrix
// In variables
in vec4 vertexPosition;
in vec3 vertexNormal;
in vec2 textureCoords;
// Out variables
out vec3 vertexPosCameraSpace; // Camera-space position of the vertex
out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
out vec2 texCoords; // Texture coordinates
out vec4 shadowMapCoords; // Shadow map texture coords
void main() {
// Compute the vertex position
vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition;
vertexPosCameraSpace = positionCameraSpace.xyz;
// Compute the world surface normal
vertexNormalCameraSpace = normalMatrix * vertexNormal;
// Get the texture coordinates
texCoords = textureCoords;
// Compute the texture coords of the vertex in the shadow map
shadowMapCoords = shadowMapProjectionMatrix * worldToLight0CameraMatrix * localToWorldMatrix * vertexPosition;
// Compute the clip-space vertex coordinates
gl_Position = projectionMatrix * positionCameraSpace;
}
#version 330
/********************************************************************************
* OpenGL-Framework *
* Copyright (c) 2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Uniform variables
uniform mat4 localToWorldMatrix; // Local-space to world-space matrix
uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix
uniform mat4 worldToLight0CameraMatrix; // World-space to light0 camera-space matrix (for shadow mapping)
uniform mat4 worldToLight1CameraMatrix; // World-space to light1 camera-space matrix (for shadow mapping)
uniform mat4 worldToLight2CameraMatrix; // World-space to light2 camera-space matrix (for shadow mapping)
uniform mat4 projectionMatrix; // Projection matrix
uniform mat3 normalMatrix; // Normal matrix
uniform mat4 shadowMapLight0ProjectionMatrix; // Shadow map projection matrix for light 0
uniform mat4 shadowMapLight1ProjectionMatrix; // Shadow map projection matrix for light 1
uniform mat4 shadowMapLight2ProjectionMatrix; // Shadow map projection matrix for light 2
// In variables
in vec4 vertexPosition;
in vec3 vertexNormal;
in vec2 textureCoords;
// Out variables
out vec3 vertexPosCameraSpace; // Camera-space position of the vertex
out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
out vec2 texCoords; // Texture coordinates
out vec4 shadowMapCoords[3]; // Shadow map texture coords
void main() {
// Compute the vertex position
vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition;
vertexPosCameraSpace = positionCameraSpace.xyz;
// Compute the world surface normal
vertexNormalCameraSpace = normalMatrix * vertexNormal;
// Get the texture coordinates
texCoords = textureCoords;
// Compute the texture coords of the vertex in the shadow map
mat4 worldToLightCameraMatrix[3];
worldToLightCameraMatrix[0] = worldToLight0CameraMatrix;
worldToLightCameraMatrix[1] = worldToLight1CameraMatrix;
worldToLightCameraMatrix[2] = worldToLight2CameraMatrix;
mat4 shadowMapProjectionMatrix[3];
shadowMapProjectionMatrix[0] = shadowMapLight0ProjectionMatrix;
shadowMapProjectionMatrix[1] = shadowMapLight1ProjectionMatrix;
shadowMapProjectionMatrix[2] = shadowMapLight2ProjectionMatrix;
for (int l=0; l < 3; l++) {
shadowMapCoords[l] = shadowMapProjectionMatrix[l] * worldToLightCameraMatrix[l] * localToWorldMatrix * vertexPosition;
}
// Compute the clip-space vertex coordinates
gl_Position = projectionMatrix * positionCameraSpace;
}

View File

@ -1,49 +1,64 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2016 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "TestbedApplication.h"
#include "nanogui/nanogui.h"
using namespace nanogui;
// Main function
int main(int argc, char** argv) {
nanogui::init();
{
// Create and start the testbed application
bool isFullscreen = false;
nanogui::ref<TestbedApplication> application = new TestbedApplication(isFullscreen);
application->setVisible(true);
nanogui::mainloop();
}
nanogui::shutdown();
return 0;
}
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2016 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "TestbedApplication.h"
#include "nanogui/nanogui.h"
using namespace nanogui;
// Main function
int main(int argc, char** argv) {
nanogui::init();
{
bool isFullscreen = false;
// Get the primary monitor
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
// Window size
int windowWidth = mode->width;
int windowHeight = mode->height;
if (!isFullscreen) {
windowWidth *= 0.9;
windowHeight *= 0.9;
}
// Create and start the testbed application
nanogui::ref<TestbedApplication> application = new TestbedApplication(isFullscreen, windowWidth, windowHeight);
application->setVisible(true);
nanogui::mainloop();
}
nanogui::shutdown();
return 0;
}

View File

@ -33,15 +33,10 @@
using namespace openglframework;
int SceneDemo::shadowMapTextureLevel = 0;
openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0f);
openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9f, 0.88f, 0.145f, 1.0f);
openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66f, 0.95f, 1.0f);
openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9f, 0.35f, 0, 1.0f);
openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83f, 0.48f, 0.64f, 1.0f);
openglframework::Color SceneDemo::mRedColorDemo = Color(0.95f, 0, 0, 1.0f);
int SceneDemo::mNbDemoColors = 4;
openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo,
SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo};
openglframework::Color SceneDemo::mObjectColorDemo = Color(0.76f, 0.67f, 0.47f, 1.0f);
openglframework::Color SceneDemo::mFloorColorDemo = Color(0.47f, 0.48f, 0.49f, 1.0f);
openglframework::Color SceneDemo::mSleepingColorDemo = Color(1.0f, 0.25f, 0.25f, 1.0f);
openglframework::Color SceneDemo::mSelectedObjectColorDemo = Color(0.09f, 0.59f, 0.88f, 1.0f);
// Constructor
SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled)
@ -55,17 +50,34 @@ SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sc
shadowMapTextureLevel++;
// Move the light0
mLight0.translateWorld(Vector3(-2, 35, 40));
// Move the lights
float lightsRadius = 30.0f;
float lightsHeight = 20.0f;
mLight0.translateWorld(Vector3(0 * lightsRadius, lightsHeight, 1 * lightsRadius));
mLight1.translateWorld(Vector3(0.95f * lightsRadius, lightsHeight, -0.3f * lightsRadius));
mLight2.translateWorld(Vector3(-0.58f * lightsRadius, lightsHeight, -0.81f * lightsRadius));
// Camera at light0 postion for the shadow map
mShadowMapLightCamera.translateWorld(mLight0.getOrigin());
mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 4.0f);
mShadowMapLightCamera.rotateWorld(Vector3(0, 1, 0), PI / 8.0f);
// Set the lights colors
mLight0.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
mLight1.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
mLight2.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
mShadowMapLightCamera.setFieldOfView(80.0f);
mShadowMapLightCamera.setSceneRadius(100);
mShadowMapLightCameras[0].translateWorld(mLight0.getOrigin());
mShadowMapLightCameras[0].rotateLocal(Vector3(1, 0, 0), -PI / 4.0f);
mShadowMapLightCameras[1].translateWorld(mLight1.getOrigin());
mShadowMapLightCameras[1].rotateLocal(Vector3(0, 1, 0), -5.0f * PI/3.7f);
mShadowMapLightCameras[1].rotateLocal(Vector3(1, 0, 0), -PI/4.0f);
mShadowMapLightCameras[2].translateWorld(mLight2.getOrigin());
mShadowMapLightCameras[2].rotateLocal(Vector3(0, 1, 0), 5 * PI/4.0f);
mShadowMapLightCameras[2].rotateLocal(Vector3(1, 0 , 0), -PI/4.0f);
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapLightCameras[i].setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
mShadowMapLightCameras[i].setFieldOfView(100.0f);
mShadowMapLightCameras[i].setSceneRadius(100);
}
mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
@ -87,15 +99,19 @@ SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sc
// Destructor
SceneDemo::~SceneDemo() {
mShadowMapTexture.destroy();
mFBOShadowMap.destroy();
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapTexture[i].destroy();
mFBOShadowMap[i].destroy();
}
mVBOQuad.destroy();
mDepthShader.destroy();
mPhongShader.destroy();
mQuadShader.destroy();
mColorShader.destroy();
mDepthShader.destroy();
mPhongShader.destroy();
mQuadShader.destroy();
mColorShader.destroy();
// Destroy the contact points
removeAllVisualContactPoints();
@ -137,15 +153,18 @@ void SceneDemo::updatePhysics() {
// Render the scene (in multiple passes for shadow mapping)
void SceneDemo::render() {
const Color& diffCol = mLight0.getDiffuseColor();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
Matrix4 shadowMapProjMatrix[NB_SHADOW_MAPS];
openglframework::Matrix4 worldToLightCameraMatrix[NB_SHADOW_MAPS];
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
const Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix();
const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse();
shadowMapProjMatrix[i] = mShadowMapLightCameras[i].getProjectionMatrix();
worldToLightCameraMatrix[i] = mShadowMapLightCameras[i].getTransformMatrix().getInverse();
}
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
// If Shadow Mapping is enabled
if (mIsShadowMappingEnabled) {
@ -153,30 +172,34 @@ void SceneDemo::render() {
// Culling switching, rendering only backface, this is done to avoid self-shadowing
glCullFace(GL_BACK);
mFBOShadowMap.bind();
// For each shadow map
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
// Bind the shader
mDepthShader.bind();
mFBOShadowMap[i].bind();
// Set the variables of the shader
mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix);
// Bind the shader
mDepthShader.bind();
// Set the viewport to render into the shadow map texture
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
// Set the variables of the shader
mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix[i]);
// Clear previous frame values
glClear(GL_DEPTH_BUFFER_BIT);
// Set the viewport to render into the shadow map texture
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
// Disable color rendering, we only want to write to the Z-Buffer
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// Clear previous frame values
glClear(GL_DEPTH_BUFFER_BIT);
// Render the objects of the scene
renderSinglePass(mDepthShader, worldToLightCameraMatrix);
// Disable color rendering, we only want to write to the Z-Buffer
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// Unbind the shader
mDepthShader.unbind();
// Render the objects of the scene
renderSinglePass(mDepthShader, worldToLightCameraMatrix[i]);
mFBOShadowMap.unbind();
// Unbind the shader
mDepthShader.unbind();
mFBOShadowMap[i].unbind();
}
glDisable(GL_POLYGON_OFFSET_FILL);
}
@ -190,17 +213,36 @@ void SceneDemo::render() {
mPhongShader.bind();
if (mIsShadowMappingEnabled) mShadowMapTexture.bind();
const GLuint textureUnit = 0;
// Is shadow mapping is enabled
GLint textureUnits[NB_SHADOW_MAPS];
if (mIsShadowMappingEnabled) {
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapTexture[i].bind();
}
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
textureUnits[i] = mShadowMapTexture[i].getUnit();
}
}
// Set the variables of the phong shader
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix);
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix);
mPhongShader.setMatrix4x4Uniform("shadowMapLight0ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[0]);
mPhongShader.setMatrix4x4Uniform("shadowMapLight1ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[1]);
mPhongShader.setMatrix4x4Uniform("shadowMapLight2ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[2]);
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix[0]);
mPhongShader.setMatrix4x4Uniform("worldToLight1CameraMatrix", worldToLightCameraMatrix[1]);
mPhongShader.setMatrix4x4Uniform("worldToLight2CameraMatrix", worldToLightCameraMatrix[2]);
mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.4f, 0.4f, 0.4f));
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setIntUniform("shadowMapSampler", textureUnit);
mPhongShader.setVector3Uniform("light1PosCameraSpace", worldToCameraMatrix * mLight1.getOrigin());
mPhongShader.setVector3Uniform("light2PosCameraSpace", worldToCameraMatrix * mLight2.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(mLight0.getDiffuseColor().r, mLight0.getDiffuseColor().g, mLight0.getDiffuseColor().b));
mPhongShader.setVector3Uniform("light1DiffuseColor", Vector3(mLight1.getDiffuseColor().r, mLight1.getDiffuseColor().g, mLight1.getDiffuseColor().b));
mPhongShader.setVector3Uniform("light2DiffuseColor", Vector3(mLight2.getDiffuseColor().r, mLight2.getDiffuseColor().g, mLight2.getDiffuseColor().b));
mPhongShader.setIntUniform("shadowMapSampler0", textureUnits[0]);
mPhongShader.setIntUniform("shadowMapSampler1", textureUnits[1]);
mPhongShader.setIntUniform("shadowMapSampler2", textureUnits[2]);
mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled);
mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT));
mPhongShader.unbind();
@ -232,7 +274,14 @@ void SceneDemo::render() {
renderAABBs(worldToCameraMatrix);
}
if (mIsShadowMappingEnabled) mShadowMapTexture.unbind();
// Is shadow mapping is enabled
if (mIsShadowMappingEnabled) {
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapTexture[i].unbind();
}
}
mPhongShader.unbind();
//drawTextureQuad();
@ -264,20 +313,33 @@ void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglfr
// Create the Shadow map FBO and texture
void SceneDemo::createShadowMapFBOAndTexture() {
// Create the texture for the depth values
mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, NULL);
// For each shadow map
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
// Create the FBO for the shadow map
mFBOShadowMap.create(0, 0, false);
mFBOShadowMap.bind();
// Create the texture for the depth values
mShadowMapTexture[i].create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE, GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, NULL);
// Tell OpenGL that we won't bind a color texture with the currently binded FBO
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
mShadowMapTexture[i].setUnit(i);
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT, mShadowMapTexture.getID());
mFBOShadowMap.unbind();
// Make sure that texture lookups outside the texture coords range will not
// treated as beeing in shadow
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture[i].getID());
GLfloat border[] = { 1.0f, 0.0f, 0.0f, 0.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
glBindTexture(GL_TEXTURE_2D, 0);
// Create the FBO for the shadow map
mFBOShadowMap[i].create(0, 0, false);
mFBOShadowMap[i].bind();
// Tell OpenGL that we won't bind a color texture with the currently binded FBO
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
mFBOShadowMap[i].attachTexture(GL_DEPTH_ATTACHMENT, mShadowMapTexture[i].getID());
mFBOShadowMap[i].unbind();
}
mIsShadowMappingInitialized = true;
}
@ -313,11 +375,13 @@ void SceneDemo::drawTextureQuad() {
// Clear previous frame values
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const GLuint textureUnit = 0;
const int SHADOW_MAP_TEXTURE_TO_DRAW = 0;
const GLuint textureUnit = SHADOW_MAP_TEXTURE_TO_DRAW;
mVAOQuad.bind();
mQuadShader.bind();
mShadowMapTexture.bind();
mShadowMapTexture[SHADOW_MAP_TEXTURE_TO_DRAW].bind();
mQuadShader.setIntUniform("textureSampler", textureUnit);
mVBOQuad.bind();
@ -339,7 +403,7 @@ void SceneDemo::drawTextureQuad() {
glDisableVertexAttribArray(vertexPositionLoc);
mVBOQuad.unbind();
mShadowMapTexture.unbind();
mShadowMapTexture[SHADOW_MAP_TEXTURE_TO_DRAW].unbind();
mQuadShader.unbind();
mVAOQuad.unbind();
}

View File

@ -43,19 +43,29 @@ class SceneDemo : public Scene {
protected:
// -------------------- Constants -------------------- //
static constexpr int NB_SHADOW_MAPS = 3;
// -------------------- Attributes -------------------- //
/// Light 0
openglframework::Light mLight0;
/// Light 1
openglframework::Light mLight1;
/// Light 2
openglframework::Light mLight2;
/// True if the shadows FBO, textures have been created
bool mIsShadowMappingInitialized;
/// FBO for the shadow map
openglframework::FrameBufferObject mFBOShadowMap;
/// Array of FBO for the shadow maps
openglframework::FrameBufferObject mFBOShadowMap[NB_SHADOW_MAPS];
/// Shadow map texture
openglframework::Texture2D mShadowMapTexture;
openglframework::Texture2D mShadowMapTexture[NB_SHADOW_MAPS];
static int shadowMapTextureLevel;
@ -65,8 +75,8 @@ class SceneDemo : public Scene {
/// Shadow map bias matrix
openglframework::Matrix4 mShadowMapBiasMatrix;
/// Camera at light0 position for the shadow map
openglframework::Camera mShadowMapLightCamera;
/// Cameras at lights position for the shadow maps
openglframework::Camera mShadowMapLightCameras[NB_SHADOW_MAPS];
/// Depth shader to render the shadow map
openglframework::Shader mDepthShader;
@ -85,14 +95,10 @@ class SceneDemo : public Scene {
openglframework::VertexBufferObject mVBOQuad;
static openglframework::Color mGreyColorDemo;
static openglframework::Color mYellowColorDemo;
static openglframework::Color mBlueColorDemo;
static openglframework::Color mOrangeColorDemo;
static openglframework::Color mPinkColorDemo;
static openglframework::Color mRedColorDemo;
static openglframework::Color mDemoColors[];
static int mNbDemoColors;
static openglframework::Color mObjectColorDemo;
static openglframework::Color mFloorColorDemo;
static openglframework::Color mSleepingColorDemo;
static openglframework::Color mSelectedObjectColorDemo;
std::string mMeshFolderPath;
@ -120,7 +126,6 @@ class SceneDemo : public Scene {
void renderContactPoints(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
/// Render the AABBs
void renderAABBs(const openglframework::Matrix4& worldToCameraMatrix);
@ -146,9 +151,6 @@ class SceneDemo : public Scene {
/// Update the scene
virtual void update() override;
/// Reset the scene
virtual void reset() override;
/// Update the physics world (take a simulation step)
/// Can be called several times per frame
virtual void updatePhysics() override;
@ -186,14 +188,4 @@ inline const rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() const {
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
}
// Reset the scene
inline void SceneDemo::reset() {
Scene::reset();
removeAllVisualContactPoints();
}
#endif

View File

@ -54,13 +54,13 @@ using namespace pilescene;
const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f;
// Constructor
TestbedApplication::TestbedApplication(bool isFullscreen)
: Screen(Vector2i(1280, 800), "Testbed ReactPhysics3D", true, isFullscreen, 8, 8, 24, 8, 8),
TestbedApplication::TestbedApplication(bool isFullscreen, int windowWidth, int windowHeight)
: Screen(Vector2i(windowWidth, windowHeight), "Testbed ReactPhysics3D", true, isFullscreen, 8, 8, 24, 8, 8),
mIsInitialized(false), mGui(this), mCurrentScene(nullptr),
mEngineSettings(EngineSettings::defaultSettings()),
mFPS(0), mNbFrames(0), mPreviousTime(0),
mLastTimeComputedFPS(0), mFrameTime(0), mTotalPhysicsTime(0), mPhysicsStepTime(0),
mWidth(1280), mHeight(720),
mWidth(windowWidth), mHeight(windowHeight),
mSinglePhysicsStepEnabled(false), mSinglePhysicsStepDone(false),
mWindowToFramebufferRatio(Vector2(1, 1)), mIsShadowMappingEnabled(true),
mIsContactPointsDisplayed(false), mIsAABBsDisplayed(false), mIsWireframeEnabled(false),
@ -130,7 +130,6 @@ void TestbedApplication::createScenes() {
// Pile scene
PileScene* pileScene = new PileScene("Pile", mEngineSettings);
mScenes.push_back(pileScene);
assert(mScenes.size() > 0);
const int firstSceneIndex = 0;
@ -145,7 +144,7 @@ void TestbedApplication::destroyScenes() {
delete mScenes[i];
}
mCurrentScene = nullptr;
mCurrentScene = NULL;
}
void TestbedApplication::updateSinglePhysicsStep() {

View File

@ -167,7 +167,7 @@ class TestbedApplication : public Screen {
// -------------------- Methods -------------------- //
/// Private constructor (for the singleton class)
TestbedApplication(bool isFullscreen);
TestbedApplication(bool isFullscreen, int windowWidth, int windowHeight);
/// Destructor
virtual ~TestbedApplication() override;