Improve rendering of testbed application (flat shading, 3 light sources, ...)
This commit is contained in:
parent
bcb4febb16
commit
43b818573a
|
@ -84,12 +84,6 @@ Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::Dynam
|
||||||
const std::string& meshFolderPath)
|
const std::string& meshFolderPath)
|
||||||
: PhysicsObject(meshFolderPath + "cube.obj") {
|
: PhysicsObject(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
|
// Initialize the size of the box
|
||||||
mSize[0] = size.x * 0.5f;
|
mSize[0] = size.x * 0.5f;
|
||||||
mSize[1] = size.y * 0.5f;
|
mSize[1] = size.y * 0.5f;
|
||||||
|
@ -200,8 +194,7 @@ void Box::render(openglframework::Shader& shader, const openglframework::Matrix4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Vertex Buffer Objects used to render to box with OpenGL.
|
// 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
|
/// We create two VBOs (one for vertices and one for indices) to render the box
|
||||||
/// in the simulation.
|
|
||||||
void Box::createVBOAndVAO() {
|
void Box::createVBOAndVAO() {
|
||||||
|
|
||||||
// Create the VBO for the vertices data
|
// Create the VBO for the vertices data
|
||||||
|
@ -227,7 +220,7 @@ void Box::createVBOAndVAO() {
|
||||||
mVBOTextureCoords.unbind();
|
mVBOTextureCoords.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create th VBO for the indices data
|
// Create the VBO for the indices data
|
||||||
mVBOIndices.create();
|
mVBOIndices.create();
|
||||||
mVBOIndices.bind();
|
mVBOIndices.bind();
|
||||||
size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int);
|
size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "ConvexMesh.h"
|
#include "ConvexMesh.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
|
ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
|
||||||
|
@ -39,6 +40,19 @@ ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
|
||||||
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
|
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
|
||||||
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
|
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
|
||||||
for (int f=0; f < getNbFaces(0); f++) {
|
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->indexBase = f * 3;
|
||||||
face->nbVertices = 3;
|
face->nbVertices = 3;
|
||||||
face++;
|
face++;
|
||||||
|
@ -46,8 +60,8 @@ ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
|
||||||
|
|
||||||
// Create the polygon vertex array
|
// Create the polygon vertex array
|
||||||
mPolygonVertexArray =
|
mPolygonVertexArray =
|
||||||
new rp3d::PolygonVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
|
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
|
||||||
&(mIndices[0][0]), sizeof(int),
|
&(mConvexMeshIndices[0]), sizeof(int),
|
||||||
getNbFaces(0), mPolygonFaces,
|
getNbFaces(0), mPolygonFaces,
|
||||||
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
|
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
|
||||||
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
|
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
|
||||||
|
@ -86,6 +100,19 @@ ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std
|
||||||
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
|
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
|
||||||
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
|
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
|
||||||
for (int f=0; f < getNbFaces(0); f++) {
|
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->indexBase = f * 3;
|
||||||
face->nbVertices = 3;
|
face->nbVertices = 3;
|
||||||
face++;
|
face++;
|
||||||
|
@ -93,8 +120,8 @@ ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std
|
||||||
|
|
||||||
// Create the polygon vertex array
|
// Create the polygon vertex array
|
||||||
mPolygonVertexArray =
|
mPolygonVertexArray =
|
||||||
new rp3d::PolygonVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
|
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
|
||||||
&(mIndices[0][0]), sizeof(int),
|
&(mConvexMeshIndices[0]), sizeof(int),
|
||||||
getNbFaces(0), mPolygonFaces,
|
getNbFaces(0), mPolygonFaces,
|
||||||
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
|
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
|
||||||
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
|
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
|
||||||
|
@ -254,3 +281,16 @@ void ConvexMesh::createVBOAndVAO() {
|
||||||
// Unbind the VAO
|
// Unbind the VAO
|
||||||
mVAO.unbind();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,21 @@ class ConvexMesh : public PhysicsObject {
|
||||||
/// Vertex Array Object for the vertex data
|
/// Vertex Array Object for the vertex data
|
||||||
openglframework::VertexArrayObject mVAO;
|
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 -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Create the Vertex Buffer Objects used to render with OpenGL.
|
/// Create the Vertex Buffer Objects used to render with OpenGL.
|
||||||
void createVBOAndVAO();
|
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 :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
|
@ -40,8 +40,12 @@ PhysicsObject::PhysicsObject(const std::string& meshPath) : PhysicsObject() {
|
||||||
// Load the mesh from a file
|
// Load the mesh from a file
|
||||||
openglframework::MeshReaderWriter::loadMeshFromFile(meshPath, *this);
|
openglframework::MeshReaderWriter::loadMeshFromFile(meshPath, *this);
|
||||||
|
|
||||||
// Calculate the normals of the mesh
|
// If the mesh file do not have normals
|
||||||
calculateNormals();
|
if (mNormals.empty()) {
|
||||||
|
|
||||||
|
// Calculate the normals of the mesh
|
||||||
|
calculateNormals();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the new transform matrix
|
// Compute the new transform matrix
|
||||||
|
|
|
@ -1,125 +1,205 @@
|
||||||
# Blender v2.66 (sub 0) OBJ File: ''
|
# Blender v2.80 (sub 75) OBJ File: ''
|
||||||
# www.blender.org
|
# www.blender.org
|
||||||
v 0.000000 -1.000000 0.000000
|
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.425323 -0.850654 0.309011
|
v 0.425323 -0.850654 0.309011
|
||||||
v 0.262869 -0.525738 0.809012
|
|
||||||
v -0.162456 -0.850654 0.499995
|
v -0.162456 -0.850654 0.499995
|
||||||
v 0.425323 -0.850654 -0.309011
|
v 0.723607 -0.447220 0.525725
|
||||||
v 0.850648 -0.525736 0.000000
|
v 0.850648 -0.525736 -0.000000
|
||||||
v -0.688189 -0.525736 0.499997
|
v -0.525730 -0.850652 -0.000000
|
||||||
v -0.525730 -0.850652 0.000000
|
|
||||||
v -0.688189 -0.525736 -0.499997
|
|
||||||
v -0.162456 -0.850654 -0.499995
|
v -0.162456 -0.850654 -0.499995
|
||||||
v 0.262869 -0.525738 -0.809012
|
v 0.425323 -0.850654 -0.309011
|
||||||
v 0.951058 0.000000 -0.309013
|
v 0.951058 -0.000000 0.309013
|
||||||
v 0.951058 0.000000 0.309013
|
v -0.276388 -0.447220 0.850649
|
||||||
v 0.587786 0.000000 0.809017
|
v 0.262869 -0.525738 0.809012
|
||||||
v 0.000000 0.000000 1.000000
|
v 0.000000 -0.000000 1.000000
|
||||||
v -0.587786 0.000000 0.809017
|
v -0.894426 -0.447216 -0.000000
|
||||||
v -0.951058 0.000000 0.309013
|
v -0.688189 -0.525736 0.499997
|
||||||
v -0.951058 0.000000 -0.309013
|
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.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.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.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.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.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.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.688189 0.525736 -0.499997
|
||||||
v 0.525730 0.850652 0.000000
|
v 0.525730 0.850652 0.000000
|
||||||
v 0.162456 0.850654 0.499995
|
v 0.000000 1.000000 0.000000
|
||||||
v -0.425323 0.850654 0.309011
|
vn 0.1024 -0.9435 0.3151
|
||||||
v -0.425323 0.850654 -0.309011
|
vn 0.7002 -0.6617 0.2680
|
||||||
v 0.162456 0.850654 -0.499995
|
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
|
s off
|
||||||
f 1 13 15
|
f 1//1 2//1 3//1
|
||||||
f 2 13 17
|
f 4//2 2//2 5//2
|
||||||
f 1 15 19
|
f 1//3 3//3 6//3
|
||||||
f 1 19 21
|
f 1//4 6//4 7//4
|
||||||
f 1 21 16
|
f 1//5 7//5 8//5
|
||||||
f 2 17 24
|
f 4//6 5//6 9//6
|
||||||
f 3 14 26
|
f 10//7 11//7 12//7
|
||||||
f 4 18 28
|
f 13//8 14//8 15//8
|
||||||
f 5 20 30
|
f 16//9 17//9 18//9
|
||||||
f 6 22 32
|
f 19//10 20//10 21//10
|
||||||
f 2 24 25
|
f 4//11 9//11 22//11
|
||||||
f 3 26 27
|
f 10//12 12//12 23//12
|
||||||
f 4 28 29
|
f 13//13 15//13 24//13
|
||||||
f 5 30 31
|
f 16//14 18//14 25//14
|
||||||
f 6 32 23
|
f 19//15 21//15 26//15
|
||||||
f 7 33 39
|
f 27//16 28//16 29//16
|
||||||
f 8 34 40
|
f 30//17 31//17 32//17
|
||||||
f 9 35 41
|
f 33//18 34//18 35//18
|
||||||
f 10 36 42
|
f 36//19 37//19 38//19
|
||||||
f 11 37 38
|
f 39//20 40//20 41//20
|
||||||
f 15 14 3
|
f 3//21 11//21 10//21
|
||||||
f 15 13 14
|
f 3//22 2//22 11//22
|
||||||
f 13 2 14
|
f 2//23 4//23 11//23
|
||||||
f 17 16 6
|
f 5//24 8//24 19//24
|
||||||
f 17 13 16
|
f 5//25 2//25 8//25
|
||||||
f 13 1 16
|
f 2//26 1//26 8//26
|
||||||
f 19 18 4
|
f 6//27 14//27 13//27
|
||||||
f 19 15 18
|
f 6//28 3//28 14//28
|
||||||
f 15 3 18
|
f 3//29 10//29 14//29
|
||||||
f 21 20 5
|
f 7//30 17//30 16//30
|
||||||
f 21 19 20
|
f 7//31 6//31 17//31
|
||||||
f 19 4 20
|
f 6//32 13//32 17//32
|
||||||
f 16 22 6
|
f 8//33 20//33 19//33
|
||||||
f 16 21 22
|
f 8//34 7//34 20//34
|
||||||
f 21 5 22
|
f 7//35 16//35 20//35
|
||||||
f 24 23 11
|
f 9//36 26//36 39//36
|
||||||
f 24 17 23
|
f 9//37 5//37 26//37
|
||||||
f 17 6 23
|
f 5//38 19//38 26//38
|
||||||
f 26 25 7
|
f 12//39 22//39 27//39
|
||||||
f 26 14 25
|
f 12//40 11//40 22//40
|
||||||
f 14 2 25
|
f 11//41 4//41 22//41
|
||||||
f 28 27 8
|
f 15//42 23//42 30//42
|
||||||
f 28 18 27
|
f 15//43 14//43 23//43
|
||||||
f 18 3 27
|
f 14//44 10//44 23//44
|
||||||
f 30 29 9
|
f 18//45 24//45 33//45
|
||||||
f 30 20 29
|
f 18//46 17//46 24//46
|
||||||
f 20 4 29
|
f 17//47 13//47 24//47
|
||||||
f 32 31 10
|
f 21//48 25//48 36//48
|
||||||
f 32 22 31
|
f 21//49 20//49 25//49
|
||||||
f 22 5 31
|
f 20//50 16//50 25//50
|
||||||
f 25 33 7
|
f 22//51 28//51 27//51
|
||||||
f 25 24 33
|
f 22//52 9//52 28//52
|
||||||
f 24 11 33
|
f 9//53 39//53 28//53
|
||||||
f 27 34 8
|
f 23//54 31//54 30//54
|
||||||
f 27 26 34
|
f 23//55 12//55 31//55
|
||||||
f 26 7 34
|
f 12//56 27//56 31//56
|
||||||
f 29 35 9
|
f 24//57 34//57 33//57
|
||||||
f 29 28 35
|
f 24//58 15//58 34//58
|
||||||
f 28 8 35
|
f 15//59 30//59 34//59
|
||||||
f 31 36 10
|
f 25//60 37//60 36//60
|
||||||
f 31 30 36
|
f 25//61 18//61 37//61
|
||||||
f 30 9 36
|
f 18//62 33//62 37//62
|
||||||
f 23 37 11
|
f 26//63 40//63 39//63
|
||||||
f 23 32 37
|
f 26//64 21//64 40//64
|
||||||
f 32 10 37
|
f 21//65 36//65 40//65
|
||||||
f 39 38 12
|
f 29//66 41//66 42//66
|
||||||
f 39 33 38
|
f 29//67 28//67 41//67
|
||||||
f 33 11 38
|
f 28//68 39//68 41//68
|
||||||
f 40 39 12
|
f 32//69 29//69 42//69
|
||||||
f 40 34 39
|
f 32//70 31//70 29//70
|
||||||
f 34 7 39
|
f 31//71 27//71 29//71
|
||||||
f 41 40 12
|
f 35//72 32//72 42//72
|
||||||
f 41 35 40
|
f 35//73 34//73 32//73
|
||||||
f 35 8 40
|
f 34//74 30//74 32//74
|
||||||
f 42 41 12
|
f 38//75 35//75 42//75
|
||||||
f 42 36 41
|
f 38//76 37//76 35//76
|
||||||
f 36 9 41
|
f 37//77 33//77 35//77
|
||||||
f 38 42 12
|
f 41//78 38//78 42//78
|
||||||
f 38 37 42
|
f 41//79 40//79 38//79
|
||||||
f 37 10 42
|
f 40//80 36//80 38//80
|
||||||
|
|
|
@ -1,17 +1,43 @@
|
||||||
# Blender v2.72 (sub 0) OBJ File: ''
|
# Blender v2.80 (sub 75) OBJ File: ''
|
||||||
# www.blender.org
|
# 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
|
||||||
|
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
|
s off
|
||||||
f 5 6 2 1
|
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||||
f 6 7 3 2
|
f 4/5/2 3/6/2 7/7/2 8/8/2
|
||||||
f 7 8 4 3
|
f 8/8/3 7/7/3 5/9/3 6/10/3
|
||||||
f 8 5 1 4
|
f 6/10/4 2/11/4 4/12/4 8/13/4
|
||||||
f 1 2 3 4
|
f 2/14/5 1/15/5 3/16/5 4/17/5
|
||||||
f 8 7 6 5
|
f 6/18/6 5/19/6 1/20/6 2/11/6
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using namespace openglframework;
|
using namespace openglframework;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -112,6 +114,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
std::vector<uint> normalsIndices;
|
std::vector<uint> normalsIndices;
|
||||||
std::vector<uint> uvsIndices;
|
std::vector<uint> uvsIndices;
|
||||||
|
|
||||||
|
|
||||||
// ---------- Collect the data from the file ---------- //
|
// ---------- Collect the data from the file ---------- //
|
||||||
|
|
||||||
// For each line of the file
|
// For each line of the file
|
||||||
|
@ -142,7 +145,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
line = buffer;
|
line = buffer;
|
||||||
found1 = (int)line.find("/");
|
found1 = (int)line.find("/");
|
||||||
bool isFaceQuad = false;
|
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 the face definition is of the form "f v1 v2 v3 v4"
|
||||||
if(found1 == string::npos) {
|
if(found1 == string::npos) {
|
||||||
|
@ -150,11 +153,21 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
if (nbVertices == 4) isFaceQuad = true;
|
if (nbVertices == 4) isFaceQuad = true;
|
||||||
}
|
}
|
||||||
// If the face definition is of the form "f v1// v2// v3// v4//"
|
// 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);
|
int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4);
|
||||||
if (nbVertices == 4) isFaceQuad = true;
|
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
|
//get the part of the string until the second index
|
||||||
tmp = line.substr(found1+1);
|
tmp = line.substr(found1+1);
|
||||||
|
@ -166,6 +179,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
if(found2 == string::npos) {
|
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);
|
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;
|
if (n == 8) isFaceQuad = true;
|
||||||
|
|
||||||
uvsIndices.push_back(tId1-1);
|
uvsIndices.push_back(tId1-1);
|
||||||
uvsIndices.push_back(tId2-1);
|
uvsIndices.push_back(tId2-1);
|
||||||
uvsIndices.push_back(tId3-1);
|
uvsIndices.push_back(tId3-1);
|
||||||
|
@ -174,8 +188,11 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
else {
|
else {
|
||||||
tmp = line.substr(found1+1);
|
tmp = line.substr(found1+1);
|
||||||
found2 = (int)tmp.find("/");
|
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) {
|
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);
|
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;
|
if (n == 8) isFaceQuad = true;
|
||||||
|
@ -213,39 +230,84 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
// Destroy the current mesh
|
// Destroy the current mesh
|
||||||
meshToCreate.destroy();
|
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
|
// Mesh data
|
||||||
vector<std::vector<uint> > meshIndices;
|
vector<std::vector<uint> > meshIndices;
|
||||||
|
vector<Vector3> meshVertices;
|
||||||
vector<Vector3> meshNormals;
|
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;
|
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
|
// We cannot load mesh with several parts for the moment
|
||||||
uint meshPart = 0;
|
uint meshPart = 0;
|
||||||
|
|
||||||
|
const bool hasNormals = !normalsIndices.empty() && !normals.empty();
|
||||||
|
const bool hasUvs = !uvsIndices.empty() && !uvs.empty();
|
||||||
|
|
||||||
// Fill in the vertex indices
|
// Fill in the vertex indices
|
||||||
// We also triangulate each quad face
|
// We also triangulate each quad face
|
||||||
meshIndices.push_back(std::vector<uint>());
|
meshIndices.push_back(std::vector<uint>());
|
||||||
for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) {
|
for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) {
|
||||||
|
|
||||||
// Get the current vertex IDs
|
// 3 if the current vertices form a triangle and 4 if they form a quad
|
||||||
uint i1 = verticesIndices[i];
|
const int nbVertices = isQuad[j] ? 4 : 3;
|
||||||
uint i2 = verticesIndices[i+1];
|
|
||||||
uint i3 = verticesIndices[i+2];
|
|
||||||
|
|
||||||
|
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
|
// Add the vertex normal
|
||||||
if (!normalsIndices.empty() && !normals.empty()) {
|
if (hasNormals) {
|
||||||
meshNormals[i1] = normals[normalsIndices[i]];
|
meshNormals[i1] = normals[normalsIndices[i]];
|
||||||
meshNormals[i2] = normals[normalsIndices[i+1]];
|
meshNormals[i2] = normals[normalsIndices[i+1]];
|
||||||
meshNormals[i3] = normals[normalsIndices[i+2]];
|
meshNormals[i3] = normals[normalsIndices[i+2]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the vertex UV texture coordinates
|
// Add the vertex UV texture coordinates
|
||||||
if (!uvsIndices.empty() && !uvs.empty()) {
|
if (hasUvs) {
|
||||||
meshUVs[i1] = uvs[uvsIndices[i]];
|
meshUVs[i1] = uvs[uvsIndices[i]];
|
||||||
meshUVs[i2] = uvs[uvsIndices[i+1]];
|
meshUVs[i2] = uvs[uvsIndices[i+1]];
|
||||||
meshUVs[i3] = uvs[uvsIndices[i+2]];
|
meshUVs[i3] = uvs[uvsIndices[i+2]];
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// If the current vertex not in a quad (it is part of a triangle)
|
// If the current vertex not in a quad (it is part of a triangle)
|
||||||
if (!isQuad[j]) {
|
if (!isQuad[j]) {
|
||||||
|
@ -259,11 +321,10 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
}
|
}
|
||||||
else { // If the current vertex is in a quad
|
else { // If the current vertex is in a quad
|
||||||
|
|
||||||
Vector3 v1 = vertices[i1];
|
Vector3 v1 = meshVertices[i1];
|
||||||
Vector3 v2 = vertices[i2];
|
Vector3 v2 = meshVertices[i2];
|
||||||
Vector3 v3 = vertices[i3];
|
Vector3 v3 = meshVertices[i3];
|
||||||
uint i4 = verticesIndices[i+3];
|
Vector3 v4 = meshVertices[i4];
|
||||||
Vector3 v4 = vertices[i4];
|
|
||||||
|
|
||||||
Vector3 v13 = v3-v1;
|
Vector3 v13 = v3-v1;
|
||||||
Vector3 v12 = v2-v1;
|
Vector3 v12 = v2-v1;
|
||||||
|
@ -288,6 +349,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
meshIndices[meshPart].push_back(i4);
|
meshIndices[meshPart].push_back(i4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Add the vertex normal
|
// Add the vertex normal
|
||||||
if (!normalsIndices.empty() && !normals.empty()) {
|
if (!normalsIndices.empty() && !normals.empty()) {
|
||||||
meshNormals[i4] = normals[normalsIndices[i]];
|
meshNormals[i4] = normals[normalsIndices[i]];
|
||||||
|
@ -297,17 +359,18 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||||
if (!uvsIndices.empty() && !uvs.empty()) {
|
if (!uvsIndices.empty() && !uvs.empty()) {
|
||||||
meshUVs[i4] = uvs[uvsIndices[i]];
|
meshUVs[i4] = uvs[uvsIndices[i]];
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
i+=4;
|
i+=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(meshNormals.empty() || meshNormals.size() == vertices.size());
|
assert(meshNormals.empty() || meshNormals.size() == meshVertices.size());
|
||||||
assert(meshUVs.empty() || meshUVs.size() == vertices.size());
|
assert(meshUVs.empty() || meshUVs.size() == meshVertices.size());
|
||||||
|
|
||||||
// Set the data to the mesh
|
// Set the data to the mesh
|
||||||
meshToCreate.setIndices(meshIndices);
|
meshToCreate.setIndices(meshIndices);
|
||||||
meshToCreate.setVertices(vertices);
|
meshToCreate.setVertices(meshVertices);
|
||||||
meshToCreate.setNormals(meshNormals);
|
meshToCreate.setNormals(meshNormals);
|
||||||
meshToCreate.setUVs(meshUVs);
|
meshToCreate.setUVs(meshUVs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
#endif
|
||||||
|
|
|
@ -95,6 +95,11 @@ class Shader {
|
||||||
// to set it, an assert will occur)
|
// to set it, an assert will occur)
|
||||||
void setIntUniform(const std::string& variableName, int value, bool errorIfMissing = true) const;
|
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
|
// 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
|
// used in the shader, the compiler will remove it, then when you will try
|
||||||
// to set it, an assert will occur)
|
// 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"
|
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
|
||||||
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
|
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
throw std::logic_error("Error in Shader");
|
//throw std::logic_error("Error in Shader");
|
||||||
}
|
}
|
||||||
|
|
||||||
return location;
|
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
|
// 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
|
// used in the shader, the compiler will remove it, then when you will try
|
||||||
// to set it, an assert will occur)
|
// to set it, an assert will occur)
|
||||||
|
|
700
testbed/scenes/collisiondetection/CollisionDetectionScene.cpp
Executable file → Normal file
700
testbed/scenes/collisiondetection/CollisionDetectionScene.cpp
Executable file → Normal file
|
@ -1,350 +1,350 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "CollisionDetectionScene.h"
|
#include "CollisionDetectionScene.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include "collision/ContactManifold.h"
|
#include "collision/ContactManifold.h"
|
||||||
|
|
||||||
// Namespaces
|
// Namespaces
|
||||||
using namespace openglframework;
|
using namespace openglframework;
|
||||||
using namespace collisiondetectionscene;
|
using namespace collisiondetectionscene;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings)
|
CollisionDetectionScene::CollisionDetectionScene(const std::string& name, EngineSettings& settings)
|
||||||
: SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
|
: SceneDemo(name, settings, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
|
||||||
mContactManager(mPhongShader, mMeshFolderPath),
|
mContactManager(mPhongShader, mMeshFolderPath),
|
||||||
mAreNormalsDisplayed(false) {
|
mAreNormalsDisplayed(false) {
|
||||||
|
|
||||||
mSelectedShapeIndex = 0;
|
mSelectedShapeIndex = 0;
|
||||||
mIsContactPointsDisplayed = true;
|
mIsContactPointsDisplayed = true;
|
||||||
mIsWireframeEnabled = true;
|
mIsWireframeEnabled = true;
|
||||||
|
|
||||||
// Compute the radius and the center of the scene
|
// Compute the radius and the center of the scene
|
||||||
openglframework::Vector3 center(0, 0, 0);
|
openglframework::Vector3 center(0, 0, 0);
|
||||||
|
|
||||||
// Set the center of the scene
|
// Set the center of the scene
|
||||||
setScenePosition(center, SCENE_RADIUS);
|
setScenePosition(center, SCENE_RADIUS);
|
||||||
|
|
||||||
rp3d::WorldSettings worldSettings;
|
rp3d::WorldSettings worldSettings;
|
||||||
worldSettings.worldName = name;
|
worldSettings.worldName = name;
|
||||||
|
|
||||||
// Create the dynamics world for the physics simulation
|
// Create the dynamics world for the physics simulation
|
||||||
mPhysicsWorld = new rp3d::CollisionWorld(worldSettings);
|
mPhysicsWorld = new rp3d::CollisionWorld(worldSettings);
|
||||||
|
|
||||||
// ---------- Sphere 1 ---------- //
|
// ---------- Sphere 1 ---------- //
|
||||||
|
|
||||||
// Create a sphere and a corresponding collision body in the dynamics world
|
// Create a sphere and a corresponding collision body in the dynamics world
|
||||||
mSphere1 = new Sphere(4, mPhysicsWorld, mMeshFolderPath);
|
mSphere1 = new Sphere(4, mPhysicsWorld, mMeshFolderPath);
|
||||||
mAllShapes.push_back(mSphere1);
|
mAllShapes.push_back(mSphere1);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mSphere1->setColor(mGreyColorDemo);
|
mSphere1->setColor(mObjectColorDemo);
|
||||||
mSphere1->setSleepingColor(mRedColorDemo);
|
mSphere1->setSleepingColor(mSleepingColorDemo);
|
||||||
//mSphere1->setScaling(0.5f);
|
//mSphere1->setScaling(0.5f);
|
||||||
mPhysicsObjects.push_back(mSphere1);
|
mPhysicsObjects.push_back(mSphere1);
|
||||||
|
|
||||||
// ---------- Sphere 2 ---------- //
|
// ---------- Sphere 2 ---------- //
|
||||||
|
|
||||||
// Create a sphere and a corresponding collision body in the dynamics world
|
// Create a sphere and a corresponding collision body in the dynamics world
|
||||||
mSphere2 = new Sphere(2, mPhysicsWorld, mMeshFolderPath);
|
mSphere2 = new Sphere(2, mPhysicsWorld, mMeshFolderPath);
|
||||||
mAllShapes.push_back(mSphere2);
|
mAllShapes.push_back(mSphere2);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mSphere2->setColor(mGreyColorDemo);
|
mSphere2->setColor(mObjectColorDemo);
|
||||||
mSphere2->setSleepingColor(mRedColorDemo);
|
mSphere2->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mSphere2);
|
mPhysicsObjects.push_back(mSphere2);
|
||||||
|
|
||||||
|
|
||||||
// ---------- Capsule 1 ---------- //
|
// ---------- Capsule 1 ---------- //
|
||||||
|
|
||||||
// Create a cylinder and a corresponding collision body in the dynamics world
|
// Create a cylinder and a corresponding collision body in the dynamics world
|
||||||
mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
|
mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
|
||||||
mAllShapes.push_back(mCapsule1);
|
mAllShapes.push_back(mCapsule1);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mCapsule1->setColor(mGreyColorDemo);
|
mCapsule1->setColor(mObjectColorDemo);
|
||||||
mCapsule1->setSleepingColor(mRedColorDemo);
|
mCapsule1->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mCapsule1);
|
mPhysicsObjects.push_back(mCapsule1);
|
||||||
|
|
||||||
// ---------- Capsule 2 ---------- //
|
// ---------- Capsule 2 ---------- //
|
||||||
|
|
||||||
// Create a cylinder and a corresponding collision body in the dynamics world
|
// Create a cylinder and a corresponding collision body in the dynamics world
|
||||||
mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
|
mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
|
||||||
mAllShapes.push_back(mCapsule2);
|
mAllShapes.push_back(mCapsule2);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mCapsule2->setColor(mGreyColorDemo);
|
mCapsule2->setColor(mObjectColorDemo);
|
||||||
mCapsule2->setSleepingColor(mRedColorDemo);
|
mCapsule2->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mCapsule2);
|
mPhysicsObjects.push_back(mCapsule2);
|
||||||
|
|
||||||
// ---------- Concave Mesh ---------- //
|
// ---------- Concave Mesh ---------- //
|
||||||
|
|
||||||
// Create a convex mesh and a corresponding collision body in the dynamics world
|
// Create a convex mesh and a corresponding collision body in the dynamics world
|
||||||
mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj");
|
mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj");
|
||||||
mAllShapes.push_back(mConcaveMesh);
|
mAllShapes.push_back(mConcaveMesh);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mConcaveMesh->setColor(mGreyColorDemo);
|
mConcaveMesh->setColor(mObjectColorDemo);
|
||||||
mConcaveMesh->setSleepingColor(mRedColorDemo);
|
mConcaveMesh->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mConcaveMesh);
|
mPhysicsObjects.push_back(mConcaveMesh);
|
||||||
|
|
||||||
// ---------- Box 1 ---------- //
|
// ---------- Box 1 ---------- //
|
||||||
|
|
||||||
// Create a cylinder and a corresponding collision body in the dynamics world
|
// Create a cylinder and a corresponding collision body in the dynamics world
|
||||||
mBox1 = new Box(BOX_SIZE, mPhysicsWorld, mMeshFolderPath);
|
mBox1 = new Box(BOX_SIZE, mPhysicsWorld, mMeshFolderPath);
|
||||||
mAllShapes.push_back(mBox1);
|
mAllShapes.push_back(mBox1);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mBox1->setColor(mGreyColorDemo);
|
mBox1->setColor(mObjectColorDemo);
|
||||||
mBox1->setSleepingColor(mRedColorDemo);
|
mBox1->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mBox1);
|
mPhysicsObjects.push_back(mBox1);
|
||||||
|
|
||||||
// ---------- Box 2 ---------- //
|
// ---------- Box 2 ---------- //
|
||||||
|
|
||||||
// Create a cylinder and a corresponding collision body in the dynamics world
|
// Create a cylinder and a corresponding collision body in the dynamics world
|
||||||
mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsWorld, mMeshFolderPath);
|
mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsWorld, mMeshFolderPath);
|
||||||
mAllShapes.push_back(mBox2);
|
mAllShapes.push_back(mBox2);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mBox2->setColor(mGreyColorDemo);
|
mBox2->setColor(mObjectColorDemo);
|
||||||
mBox2->setSleepingColor(mRedColorDemo);
|
mBox2->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mBox2);
|
mPhysicsObjects.push_back(mBox2);
|
||||||
|
|
||||||
// ---------- Convex Mesh ---------- //
|
// ---------- Convex Mesh ---------- //
|
||||||
|
|
||||||
// Create a convex mesh and a corresponding collision body in the dynamics world
|
// Create a convex mesh and a corresponding collision body in the dynamics world
|
||||||
mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
|
mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
|
||||||
mAllShapes.push_back(mConvexMesh);
|
mAllShapes.push_back(mConvexMesh);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mConvexMesh->setColor(mGreyColorDemo);
|
mConvexMesh->setColor(mObjectColorDemo);
|
||||||
mConvexMesh->setSleepingColor(mRedColorDemo);
|
mConvexMesh->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mConvexMesh);
|
mPhysicsObjects.push_back(mConvexMesh);
|
||||||
|
|
||||||
// ---------- Heightfield ---------- //
|
// ---------- Heightfield ---------- //
|
||||||
|
|
||||||
// Create a convex mesh and a corresponding collision body in the dynamics world
|
// Create a convex mesh and a corresponding collision body in the dynamics world
|
||||||
mHeightField = new HeightField(mPhysicsWorld);
|
mHeightField = new HeightField(mPhysicsWorld);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mHeightField->setColor(mGreyColorDemo);
|
mHeightField->setColor(mObjectColorDemo);
|
||||||
mHeightField->setSleepingColor(mRedColorDemo);
|
mHeightField->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mHeightField);
|
mPhysicsObjects.push_back(mHeightField);
|
||||||
|
|
||||||
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
|
mAllShapes[mSelectedShapeIndex]->setColor(mObjectColorDemo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the scene
|
// Reset the scene
|
||||||
void CollisionDetectionScene::reset() {
|
void CollisionDetectionScene::reset() {
|
||||||
|
|
||||||
mSphere1->setTransform(rp3d::Transform(rp3d::Vector3(15, 5, 0), rp3d::Quaternion::identity()));
|
mSphere1->setTransform(rp3d::Transform(rp3d::Vector3(15, 5, 0), rp3d::Quaternion::identity()));
|
||||||
mSphere2->setTransform(rp3d::Transform(rp3d::Vector3(0, 6, 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()));
|
mCapsule1->setTransform(rp3d::Transform(rp3d::Vector3(-8, 7, 0), rp3d::Quaternion::identity()));
|
||||||
mCapsule2->setTransform(rp3d::Transform(rp3d::Vector3(11, -8, 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()));
|
mBox1->setTransform(rp3d::Transform(rp3d::Vector3(-4, -7, 0), rp3d::Quaternion::identity()));
|
||||||
mBox2->setTransform(rp3d::Transform(rp3d::Vector3(0, 9, 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()));
|
mConvexMesh->setTransform(rp3d::Transform(rp3d::Vector3(-5, 0, 0), rp3d::Quaternion::identity()));
|
||||||
mConcaveMesh->setTransform(rp3d::Transform(rp3d::Vector3(0, 15, 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()));
|
mHeightField->setTransform(rp3d::Transform(rp3d::Vector3(0, -22, 0), rp3d::Quaternion::identity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
CollisionDetectionScene::~CollisionDetectionScene() {
|
CollisionDetectionScene::~CollisionDetectionScene() {
|
||||||
|
|
||||||
// Destroy the box rigid body from the dynamics world
|
// Destroy the box rigid body from the dynamics world
|
||||||
//mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody());
|
//mPhysicsWorld->destroyCollisionBody(mBox->getCollisionBody());
|
||||||
//delete mBox;
|
//delete mBox;
|
||||||
|
|
||||||
// Destroy the spheres
|
// Destroy the spheres
|
||||||
mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mSphere1->getCollisionBody());
|
||||||
delete mSphere1;
|
delete mSphere1;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mSphere2->getCollisionBody());
|
||||||
delete mSphere2;
|
delete mSphere2;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mCapsule1->getCollisionBody());
|
||||||
delete mCapsule1;
|
delete mCapsule1;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mCapsule2->getCollisionBody());
|
||||||
delete mCapsule2;
|
delete mCapsule2;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mBox1->getCollisionBody());
|
||||||
delete mBox1;
|
delete mBox1;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mBox2->getCollisionBody());
|
||||||
delete mBox2;
|
delete mBox2;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mConvexMesh->getCollisionBody());
|
||||||
delete mConvexMesh;
|
delete mConvexMesh;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mConcaveMesh->getCollisionBody());
|
||||||
delete mConcaveMesh;
|
delete mConcaveMesh;
|
||||||
|
|
||||||
mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
|
mPhysicsWorld->destroyCollisionBody(mHeightField->getCollisionBody());
|
||||||
delete mHeightField;
|
delete mHeightField;
|
||||||
|
|
||||||
mContactManager.resetPoints();
|
mContactManager.resetPoints();
|
||||||
|
|
||||||
// Destroy the static data for the visual contact points
|
// Destroy the static data for the visual contact points
|
||||||
VisualContactPoint::destroyStaticData();
|
VisualContactPoint::destroyStaticData();
|
||||||
|
|
||||||
// Destroy the collision world
|
// Destroy the collision world
|
||||||
delete mPhysicsWorld;
|
delete mPhysicsWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take a step for the simulation
|
// Take a step for the simulation
|
||||||
void CollisionDetectionScene::update() {
|
void CollisionDetectionScene::update() {
|
||||||
|
|
||||||
mContactManager.resetPoints();
|
mContactManager.resetPoints();
|
||||||
|
|
||||||
mPhysicsWorld->testCollision(&mContactManager);
|
mPhysicsWorld->testCollision(&mContactManager);
|
||||||
|
|
||||||
SceneDemo::update();
|
SceneDemo::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionDetectionScene::selectNextShape() {
|
void CollisionDetectionScene::selectNextShape() {
|
||||||
|
|
||||||
uint previousIndex = mSelectedShapeIndex;
|
uint previousIndex = mSelectedShapeIndex;
|
||||||
mSelectedShapeIndex++;
|
mSelectedShapeIndex++;
|
||||||
if (mSelectedShapeIndex >= mAllShapes.size()) {
|
if (mSelectedShapeIndex >= mAllShapes.size()) {
|
||||||
mSelectedShapeIndex = 0;
|
mSelectedShapeIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAllShapes[previousIndex]->setColor(mGreyColorDemo);
|
mAllShapes[previousIndex]->setColor(mObjectColorDemo);
|
||||||
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
|
mAllShapes[mSelectedShapeIndex]->setColor(mSelectedObjectColorDemo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when a keyboard event occurs
|
// Called when a keyboard event occurs
|
||||||
bool CollisionDetectionScene::keyboardEvent(int key, int scancode, int action, int mods) {
|
bool CollisionDetectionScene::keyboardEvent(int key, int scancode, int action, int mods) {
|
||||||
|
|
||||||
// If the space key has been pressed
|
// If the space key has been pressed
|
||||||
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
|
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
|
||||||
selectNextShape();
|
selectNextShape();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float stepDist = 0.2f;
|
float stepDist = 0.2f;
|
||||||
float stepAngle = 15 * (3.14f / 180.0f);
|
float stepAngle = 15 * (3.14f / 180.0f);
|
||||||
|
|
||||||
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
|
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setPosition(transform.getPosition() + rp3d::Vector3(stepDist, 0, 0));
|
transform.setPosition(transform.getPosition() + rp3d::Vector3(stepDist, 0, 0));
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_LEFT && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setPosition(transform.getPosition() + rp3d::Vector3(-stepDist, 0, 0));
|
transform.setPosition(transform.getPosition() + rp3d::Vector3(-stepDist, 0, 0));
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_UP && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_UP && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, stepDist, 0));
|
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, stepDist, 0));
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_DOWN && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, -stepDist, 0));
|
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, -stepDist, 0));
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_Z && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_Z && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, stepDist));
|
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, stepDist));
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_H && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_H && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, -stepDist));
|
transform.setPosition(transform.getPosition() + rp3d::Vector3(0, 0, -stepDist));
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_A && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_A && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, stepAngle, 0) * transform.getOrientation());
|
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, stepAngle, 0) * transform.getOrientation());
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_D && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_D && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, -stepAngle, 0) * transform.getOrientation());
|
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, -stepAngle, 0) * transform.getOrientation());
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_W && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_W && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(stepAngle, 0, 0) * transform.getOrientation());
|
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(stepAngle, 0, 0) * transform.getOrientation());
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_S && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_S && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(-stepAngle, 0, 0) * transform.getOrientation());
|
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(-stepAngle, 0, 0) * transform.getOrientation());
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_F && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_F && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, stepAngle) * transform.getOrientation());
|
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, stepAngle) * transform.getOrientation());
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
else if (key == GLFW_KEY_G && action == GLFW_PRESS) {
|
else if (key == GLFW_KEY_G && action == GLFW_PRESS) {
|
||||||
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
rp3d::Transform transform = mAllShapes[mSelectedShapeIndex]->getTransform();
|
||||||
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, -stepAngle) * transform.getOrientation());
|
transform.setOrientation(rp3d::Quaternion::fromEulerAngles(0, 0, -stepAngle) * transform.getOrientation());
|
||||||
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
mAllShapes[mSelectedShapeIndex]->setTransform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method will be called for each reported contact point
|
// This method will be called for each reported contact point
|
||||||
void ContactManager::notifyContact(const CollisionCallbackInfo& collisionCallbackInfo) {
|
void ContactManager::notifyContact(const CollisionCallbackInfo& collisionCallbackInfo) {
|
||||||
|
|
||||||
// For each contact manifold
|
// For each contact manifold
|
||||||
rp3d::ContactManifoldListElement* manifoldElement = collisionCallbackInfo.contactManifoldElements;
|
rp3d::ContactManifoldListElement* manifoldElement = collisionCallbackInfo.contactManifoldElements;
|
||||||
while (manifoldElement != nullptr) {
|
while (manifoldElement != nullptr) {
|
||||||
|
|
||||||
// Get the contact manifold
|
// Get the contact manifold
|
||||||
rp3d::ContactManifold* contactManifold = manifoldElement->getContactManifold();
|
rp3d::ContactManifold* contactManifold = manifoldElement->getContactManifold();
|
||||||
|
|
||||||
// For each contact point
|
// For each contact point
|
||||||
rp3d::ContactPoint* contactPoint = contactManifold->getContactPoints();
|
rp3d::ContactPoint* contactPoint = contactManifold->getContactPoints();
|
||||||
while (contactPoint != nullptr) {
|
while (contactPoint != nullptr) {
|
||||||
|
|
||||||
// Contact normal
|
// Contact normal
|
||||||
rp3d::Vector3 normal = contactPoint->getNormal();
|
rp3d::Vector3 normal = contactPoint->getNormal();
|
||||||
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
|
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
rp3d::Vector3 point1 = contactPoint->getLocalPointOnShape1();
|
rp3d::Vector3 point1 = contactPoint->getLocalPointOnShape1();
|
||||||
point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1;
|
point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1;
|
||||||
|
|
||||||
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
|
openglframework::Vector3 position1(point1.x, point1.y, point1.z);
|
||||||
mContactPoints.push_back(ContactPoint(position1, contactNormal, openglframework::Color::red()));
|
mContactPoints.push_back(ContactPoint(position1, contactNormal, openglframework::Color::red()));
|
||||||
|
|
||||||
rp3d::Vector3 point2 = contactPoint->getLocalPointOnShape2();
|
rp3d::Vector3 point2 = contactPoint->getLocalPointOnShape2();
|
||||||
point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2;
|
point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2;
|
||||||
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
|
openglframework::Vector3 position2(point2.x, point2.y, point2.z);
|
||||||
mContactPoints.push_back(ContactPoint(position2, contactNormal, openglframework::Color::blue()));
|
mContactPoints.push_back(ContactPoint(position2, contactNormal, openglframework::Color::blue()));
|
||||||
|
|
||||||
contactPoint = contactPoint->getNext();
|
contactPoint = contactPoint->getNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
manifoldElement = manifoldElement->getNext();
|
manifoldElement = manifoldElement->getNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
||||||
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
|
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
|
dumbbell->setColor(mObjectColorDemo);
|
||||||
dumbbell->setSleepingColor(mRedColorDemo);
|
dumbbell->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
|
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
|
||||||
|
@ -76,8 +76,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
||||||
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
box->setColor(mDemoColors[i % mNbDemoColors]);
|
box->setColor(mObjectColorDemo);
|
||||||
box->setSleepingColor(mRedColorDemo);
|
box->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
||||||
|
@ -98,8 +98,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
||||||
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
|
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
sphere->setColor(mDemoColors[i % mNbDemoColors]);
|
sphere->setColor(mObjectColorDemo);
|
||||||
sphere->setSleepingColor(mRedColorDemo);
|
sphere->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
||||||
|
@ -120,8 +120,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
||||||
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
|
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
capsule->setColor(mDemoColors[i % mNbDemoColors]);
|
capsule->setColor(mObjectColorDemo);
|
||||||
capsule->setSleepingColor(mRedColorDemo);
|
capsule->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
||||||
|
@ -139,8 +139,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
||||||
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
|
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mesh->setColor(mDemoColors[i % mNbDemoColors]);
|
mesh->setColor(mObjectColorDemo);
|
||||||
mesh->setSleepingColor(mRedColorDemo);
|
mesh->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
||||||
|
@ -157,8 +157,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
||||||
mPhysicsObjects.push_back(mFloor);
|
mPhysicsObjects.push_back(mFloor);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mFloor->setColor(mGreyColorDemo);
|
mFloor->setColor(mFloorColorDemo);
|
||||||
mFloor->setSleepingColor(mGreyColorDemo);
|
mFloor->setSleepingColor(mFloorColorDemo);
|
||||||
|
|
||||||
// The floor must be a static rigid body
|
// The floor must be a static rigid body
|
||||||
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
||||||
|
|
|
@ -58,8 +58,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
||||||
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
|
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
|
dumbbell->setColor(mObjectColorDemo);
|
||||||
dumbbell->setSleepingColor(mRedColorDemo);
|
dumbbell->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
|
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
|
||||||
|
@ -77,8 +77,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
||||||
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
box->setColor(mDemoColors[i % mNbDemoColors]);
|
box->setColor(mObjectColorDemo);
|
||||||
box->setSleepingColor(mRedColorDemo);
|
box->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
||||||
|
@ -99,8 +99,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
||||||
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
|
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
sphere->setColor(mDemoColors[i % mNbDemoColors]);
|
sphere->setColor(mObjectColorDemo);
|
||||||
sphere->setSleepingColor(mRedColorDemo);
|
sphere->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
||||||
|
@ -121,8 +121,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
||||||
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
|
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
capsule->setColor(mDemoColors[i % mNbDemoColors]);
|
capsule->setColor(mObjectColorDemo);
|
||||||
capsule->setSleepingColor(mRedColorDemo);
|
capsule->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
||||||
|
@ -140,8 +140,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
||||||
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
|
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mesh->setColor(mDemoColors[i % mNbDemoColors]);
|
mesh->setColor(mObjectColorDemo);
|
||||||
mesh->setSleepingColor(mRedColorDemo);
|
mesh->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
||||||
|
@ -164,8 +164,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
||||||
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mConcaveMesh->setColor(mGreyColorDemo);
|
mConcaveMesh->setColor(mFloorColorDemo);
|
||||||
mConcaveMesh->setSleepingColor(mGreyColorDemo);
|
mConcaveMesh->setSleepingColor(mFloorColorDemo);
|
||||||
|
|
||||||
mPhysicsObjects.push_back(mConcaveMesh);
|
mPhysicsObjects.push_back(mConcaveMesh);
|
||||||
|
|
||||||
|
|
|
@ -1,139 +1,139 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "CubesScene.h"
|
#include "CubesScene.h"
|
||||||
|
|
||||||
// Namespaces
|
// Namespaces
|
||||||
using namespace openglframework;
|
using namespace openglframework;
|
||||||
using namespace cubesscene;
|
using namespace cubesscene;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
|
CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
|
||||||
: SceneDemo(name, settings, SCENE_RADIUS) {
|
: SceneDemo(name, settings, SCENE_RADIUS) {
|
||||||
|
|
||||||
// Compute the radius and the center of the scene
|
// Compute the radius and the center of the scene
|
||||||
openglframework::Vector3 center(0, 5, 0);
|
openglframework::Vector3 center(0, 5, 0);
|
||||||
|
|
||||||
// Set the center of the scene
|
// Set the center of the scene
|
||||||
setScenePosition(center, SCENE_RADIUS);
|
setScenePosition(center, SCENE_RADIUS);
|
||||||
|
|
||||||
// Gravity vector in the dynamics world
|
// Gravity vector in the dynamics world
|
||||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||||
|
|
||||||
rp3d::WorldSettings worldSettings;
|
rp3d::WorldSettings worldSettings;
|
||||||
worldSettings.worldName = name;
|
worldSettings.worldName = name;
|
||||||
|
|
||||||
// Create the dynamics world for the physics simulation
|
// Create the dynamics world for the physics simulation
|
||||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||||
|
|
||||||
// Create all the cubes of the scene
|
// Create all the cubes of the scene
|
||||||
for (int i=0; i<NB_CUBES; i++) {
|
for (int i=0; i<NB_CUBES; i++) {
|
||||||
|
|
||||||
// Create a cube and a corresponding rigid in the dynamics world
|
// Create a cube and a corresponding rigid in the dynamics world
|
||||||
Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
cube->setColor(mDemoColors[i % mNbDemoColors]);
|
cube->setColor(mObjectColorDemo);
|
||||||
cube->setSleepingColor(mRedColorDemo);
|
cube->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = cube->getRigidBody()->getMaterial();
|
rp3d::Material& material = cube->getRigidBody()->getMaterial();
|
||||||
material.setBounciness(rp3d::decimal(0.4));
|
material.setBounciness(rp3d::decimal(0.4));
|
||||||
|
|
||||||
// Add the box the list of box in the scene
|
// Add the box the list of box in the scene
|
||||||
mBoxes.push_back(cube);
|
mBoxes.push_back(cube);
|
||||||
mPhysicsObjects.push_back(cube);
|
mPhysicsObjects.push_back(cube);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------- FLOOR ----------------------- //
|
// ------------------------- FLOOR ----------------------- //
|
||||||
|
|
||||||
// Create the floor
|
// Create the floor
|
||||||
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
|
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
mFloor->setColor(mGreyColorDemo);
|
mFloor->setColor(mFloorColorDemo);
|
||||||
mFloor->setSleepingColor(mGreyColorDemo);
|
mFloor->setSleepingColor(mFloorColorDemo);
|
||||||
|
|
||||||
// The floor must be a static rigid body
|
// The floor must be a static rigid body
|
||||||
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
||||||
mPhysicsObjects.push_back(mFloor);
|
mPhysicsObjects.push_back(mFloor);
|
||||||
|
|
||||||
// Get the physics engine parameters
|
// Get the physics engine parameters
|
||||||
mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
|
mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled();
|
||||||
rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
|
rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity();
|
||||||
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
|
mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z);
|
||||||
mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
|
mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled();
|
||||||
mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
|
mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity();
|
||||||
mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
|
mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity();
|
||||||
mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
|
mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver();
|
||||||
mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
|
mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver();
|
||||||
mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
|
mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
CubesScene::~CubesScene() {
|
CubesScene::~CubesScene() {
|
||||||
|
|
||||||
// Destroy all the cubes of the scene
|
// Destroy all the cubes of the scene
|
||||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||||
|
|
||||||
// Destroy the corresponding rigid body from the dynamics world
|
// Destroy the corresponding rigid body from the dynamics world
|
||||||
getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
|
getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody());
|
||||||
|
|
||||||
// Destroy the cube
|
// Destroy the cube
|
||||||
delete (*it);
|
delete (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the rigid body of the floor
|
// Destroy the rigid body of the floor
|
||||||
getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody());
|
getDynamicsWorld()->destroyRigidBody(mFloor->getRigidBody());
|
||||||
|
|
||||||
// Destroy the floor
|
// Destroy the floor
|
||||||
delete mFloor;
|
delete mFloor;
|
||||||
|
|
||||||
// Destroy the dynamics world
|
// Destroy the dynamics world
|
||||||
delete getDynamicsWorld();
|
delete getDynamicsWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the scene
|
// Reset the scene
|
||||||
void CubesScene::reset() {
|
void CubesScene::reset() {
|
||||||
|
|
||||||
float radius = 2.0f;
|
float radius = 2.0f;
|
||||||
|
|
||||||
// Create all the cubes of the scene
|
// Create all the cubes of the scene
|
||||||
std::vector<Box*>::iterator it;
|
std::vector<Box*>::iterator it;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
for (it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||||
|
|
||||||
// Position of the cubes
|
// Position of the cubes
|
||||||
float angle = i * 30.0f;
|
float angle = i * 30.0f;
|
||||||
rp3d::Vector3 position(radius * std::cos(angle),
|
rp3d::Vector3 position(radius * std::cos(angle),
|
||||||
10 + i * (BOX_SIZE.y + 0.3f),
|
10 + i * (BOX_SIZE.y + 0.3f),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
(*it)->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
|
(*it)->setTransform(rp3d::Transform(position, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
|
mFloor->setTransform(rp3d::Transform(rp3d::Vector3::zero(), rp3d::Quaternion::identity()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
|
||||||
Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
cube->setColor(mDemoColors[i % mNbDemoColors]);
|
cube->setColor(mObjectColorDemo);
|
||||||
cube->setSleepingColor(mRedColorDemo);
|
cube->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = cube->getRigidBody()->getMaterial();
|
rp3d::Material& material = cube->getRigidBody()->getMaterial();
|
||||||
|
@ -75,8 +75,8 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
|
||||||
|
|
||||||
// Create the floor
|
// Create the floor
|
||||||
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
|
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
mFloor->setColor(mGreyColorDemo);
|
mFloor->setColor(mFloorColorDemo);
|
||||||
mFloor->setSleepingColor(mGreyColorDemo);
|
mFloor->setSleepingColor(mFloorColorDemo);
|
||||||
|
|
||||||
// The floor must be a static rigid body
|
// The floor must be a static rigid body
|
||||||
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
||||||
|
|
|
@ -57,8 +57,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
||||||
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
|
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
|
dumbbell->setColor(mObjectColorDemo);
|
||||||
dumbbell->setSleepingColor(mRedColorDemo);
|
dumbbell->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
|
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
|
||||||
|
@ -76,8 +76,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
||||||
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
box->setColor(mDemoColors[i % mNbDemoColors]);
|
box->setColor(mObjectColorDemo);
|
||||||
box->setSleepingColor(mRedColorDemo);
|
box->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
||||||
|
@ -98,8 +98,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
||||||
sphere->getRigidBody()->getMaterial().setRollingResistance(0.08f);
|
sphere->getRigidBody()->getMaterial().setRollingResistance(0.08f);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
sphere->setColor(mDemoColors[i % mNbDemoColors]);
|
sphere->setColor(mObjectColorDemo);
|
||||||
sphere->setSleepingColor(mRedColorDemo);
|
sphere->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
||||||
|
@ -120,8 +120,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
||||||
capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f);
|
capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
capsule->setColor(mDemoColors[i % mNbDemoColors]);
|
capsule->setColor(mObjectColorDemo);
|
||||||
capsule->setSleepingColor(mRedColorDemo);
|
capsule->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
||||||
|
@ -139,8 +139,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
||||||
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
|
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mesh->setColor(mDemoColors[i % mNbDemoColors]);
|
mesh->setColor(mObjectColorDemo);
|
||||||
mesh->setSleepingColor(mRedColorDemo);
|
mesh->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
||||||
|
@ -165,8 +165,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
||||||
mPhysicsObjects.push_back(mHeightField);
|
mPhysicsObjects.push_back(mHeightField);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mHeightField->setColor(mGreyColorDemo);
|
mHeightField->setColor(mFloorColorDemo);
|
||||||
mHeightField->setSleepingColor(mGreyColorDemo);
|
mHeightField->setSleepingColor(mFloorColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = mHeightField->getRigidBody()->getMaterial();
|
rp3d::Material& material = mHeightField->getRigidBody()->getMaterial();
|
||||||
|
|
|
@ -214,8 +214,8 @@ void JointsScene::createBallAndSocketJoints() {
|
||||||
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
|
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]);
|
mBallAndSocketJointChainBoxes[i]->setColor(mObjectColorDemo);
|
||||||
mBallAndSocketJointChainBoxes[i]->setSleepingColor(mRedColorDemo);
|
mBallAndSocketJointChainBoxes[i]->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// The fist box cannot move (static body)
|
// The fist box cannot move (static body)
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
@ -266,8 +266,8 @@ void JointsScene::createSliderJoint() {
|
||||||
mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
|
mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mSliderJointBottomBox->setColor(mBlueColorDemo);
|
mSliderJointBottomBox->setColor(mObjectColorDemo);
|
||||||
mSliderJointBottomBox->setSleepingColor(mRedColorDemo);
|
mSliderJointBottomBox->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// The fist box cannot move
|
// The fist box cannot move
|
||||||
mSliderJointBottomBox->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
mSliderJointBottomBox->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
||||||
|
@ -288,8 +288,8 @@ void JointsScene::createSliderJoint() {
|
||||||
mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
|
mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mSliderJointTopBox->setColor(mOrangeColorDemo);
|
mSliderJointTopBox->setColor(mObjectColorDemo);
|
||||||
mSliderJointTopBox->setSleepingColor(mRedColorDemo);
|
mSliderJointTopBox->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
|
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
|
||||||
|
@ -330,8 +330,8 @@ void JointsScene::createPropellerHingeJoint() {
|
||||||
mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
|
mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mPropellerBox->setColor(mYellowColorDemo);
|
mPropellerBox->setColor(mObjectColorDemo);
|
||||||
mPropellerBox->setSleepingColor(mRedColorDemo);
|
mPropellerBox->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
|
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
|
||||||
|
@ -371,8 +371,8 @@ void JointsScene::createFixedJoints() {
|
||||||
mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
|
mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mFixedJointBox1->setColor(mPinkColorDemo);
|
mFixedJointBox1->setColor(mObjectColorDemo);
|
||||||
mFixedJointBox1->setSleepingColor(mRedColorDemo);
|
mFixedJointBox1->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
|
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
|
||||||
|
@ -389,8 +389,8 @@ void JointsScene::createFixedJoints() {
|
||||||
mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
|
mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mFixedJointBox2->setColor(mBlueColorDemo);
|
mFixedJointBox2->setColor(mObjectColorDemo);
|
||||||
mFixedJointBox2->setSleepingColor(mRedColorDemo);
|
mFixedJointBox2->setSleepingColor(mSleepingColorDemo);
|
||||||
|
|
||||||
// Change the material properties of the rigid body
|
// Change the material properties of the rigid body
|
||||||
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
|
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
|
||||||
|
@ -429,8 +429,8 @@ void JointsScene::createFloor() {
|
||||||
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
|
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mFloor->setColor(mGreyColorDemo);
|
mFloor->setColor(mFloorColorDemo);
|
||||||
mFloor->setSleepingColor(mGreyColorDemo);
|
mFloor->setSleepingColor(mFloorColorDemo);
|
||||||
|
|
||||||
// The floor must be a static rigid body
|
// The floor must be a static rigid body
|
||||||
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);
|
||||||
|
|
|
@ -56,8 +56,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mDumbbell = new Dumbbell(mPhysicsWorld, mMeshFolderPath);
|
mDumbbell = new Dumbbell(mPhysicsWorld, mMeshFolderPath);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mDumbbell->setColor(mGreyColorDemo);
|
mDumbbell->setColor(mObjectColorDemo);
|
||||||
mDumbbell->setSleepingColor(mRedColorDemo);
|
mDumbbell->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mDumbbell);
|
mPhysicsObjects.push_back(mDumbbell);
|
||||||
|
|
||||||
// ---------- Box ---------- //
|
// ---------- Box ---------- //
|
||||||
|
@ -67,8 +67,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mBox->getCollisionBody()->setIsActive(false);
|
mBox->getCollisionBody()->setIsActive(false);
|
||||||
|
|
||||||
// Set the box color
|
// Set the box color
|
||||||
mBox->setColor(mGreyColorDemo);
|
mBox->setColor(mObjectColorDemo);
|
||||||
mBox->setSleepingColor(mRedColorDemo);
|
mBox->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mBox);
|
mPhysicsObjects.push_back(mBox);
|
||||||
|
|
||||||
// ---------- Sphere ---------- //
|
// ---------- Sphere ---------- //
|
||||||
|
@ -77,8 +77,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mSphere = new Sphere(SPHERE_RADIUS, mPhysicsWorld, mMeshFolderPath);
|
mSphere = new Sphere(SPHERE_RADIUS, mPhysicsWorld, mMeshFolderPath);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mSphere->setColor(mGreyColorDemo);
|
mSphere->setColor(mObjectColorDemo);
|
||||||
mSphere->setSleepingColor(mRedColorDemo);
|
mSphere->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mSphere);
|
mPhysicsObjects.push_back(mSphere);
|
||||||
|
|
||||||
// ---------- Capsule ---------- //
|
// ---------- Capsule ---------- //
|
||||||
|
@ -88,8 +88,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
|
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mCapsule->setColor(mGreyColorDemo);
|
mCapsule->setColor(mObjectColorDemo);
|
||||||
mCapsule->setSleepingColor(mRedColorDemo);
|
mCapsule->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mCapsule);
|
mPhysicsObjects.push_back(mCapsule);
|
||||||
|
|
||||||
// ---------- Convex Mesh ---------- //
|
// ---------- Convex Mesh ---------- //
|
||||||
|
@ -98,8 +98,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
|
mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mConvexMesh->setColor(mGreyColorDemo);
|
mConvexMesh->setColor(mObjectColorDemo);
|
||||||
mConvexMesh->setSleepingColor(mRedColorDemo);
|
mConvexMesh->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mConvexMesh);
|
mPhysicsObjects.push_back(mConvexMesh);
|
||||||
|
|
||||||
// ---------- Concave Mesh ---------- //
|
// ---------- Concave Mesh ---------- //
|
||||||
|
@ -108,8 +108,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj");
|
mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj");
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mConcaveMesh->setColor(mGreyColorDemo);
|
mConcaveMesh->setColor(mObjectColorDemo);
|
||||||
mConcaveMesh->setSleepingColor(mRedColorDemo);
|
mConcaveMesh->setSleepingColor(mSleepingColorDemo);
|
||||||
mPhysicsObjects.push_back(mConcaveMesh);
|
mPhysicsObjects.push_back(mConcaveMesh);
|
||||||
|
|
||||||
// ---------- Heightfield ---------- //
|
// ---------- Heightfield ---------- //
|
||||||
|
@ -118,8 +118,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
||||||
mHeightField = new HeightField(mPhysicsWorld);
|
mHeightField = new HeightField(mPhysicsWorld);
|
||||||
|
|
||||||
// Set the color
|
// Set the color
|
||||||
mHeightField->setColor(mGreyColorDemo);
|
mHeightField->setColor(mObjectColorDemo);
|
||||||
mHeightField->setSleepingColor(mRedColorDemo);
|
mHeightField->setSleepingColor(mObjectColorDemo);
|
||||||
mPhysicsObjects.push_back(mHeightField);
|
mPhysicsObjects.push_back(mHeightField);
|
||||||
|
|
||||||
// Create the lines that will be used for raycasting
|
// Create the lines that will be used for raycasting
|
||||||
|
|
|
@ -1,103 +1,115 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* OpenGL-Framework *
|
* OpenGL-Framework *
|
||||||
* Copyright (c) 2015 Daniel Chappuis *
|
* Copyright (c) 2015 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Uniform variables
|
// Uniform variables
|
||||||
uniform vec3 lightAmbientColor; // Lights ambient color
|
uniform vec3 lightAmbientColor; // Lights ambient color
|
||||||
uniform vec3 light0PosCameraSpace; // Camera-space position of the light
|
uniform vec3 light0PosCameraSpace; // Camera-space position of the light 0
|
||||||
uniform vec3 light0DiffuseColor; // Light 0 diffuse color
|
uniform vec3 light1PosCameraSpace; // Camera-space position of the light 1
|
||||||
uniform sampler2D textureSampler; // Texture
|
uniform vec3 light2PosCameraSpace; // Camera-space position of the light 2
|
||||||
uniform sampler2D shadowMapSampler; // Shadow map texture sampler
|
uniform vec3 light0DiffuseColor; // Light 0 diffuse color
|
||||||
uniform bool isTexture; // True if we need to use the texture
|
uniform vec3 light1DiffuseColor; // Light 1 diffuse color
|
||||||
uniform vec4 vertexColor; // Vertex color
|
uniform vec3 light2DiffuseColor; // Light 2 diffuse color
|
||||||
uniform bool isShadowEnabled; // True if shadow mapping is enabled
|
uniform sampler2D textureSampler; // Texture
|
||||||
uniform vec2 shadowMapDimension; // Shadow map dimension
|
uniform sampler2D shadowMapSampler[3]; // Shadow map texture sampler
|
||||||
|
uniform bool isTexture; // True if we need to use the texture
|
||||||
// In variables
|
uniform vec4 vertexColor; // Vertex color
|
||||||
in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
|
uniform bool isShadowEnabled; // True if shadow mapping is enabled
|
||||||
in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
|
uniform vec2 shadowMapDimension; // Shadow map dimension
|
||||||
in vec2 texCoords; // Texture coordinates
|
|
||||||
in vec4 shadowMapCoords; // Shadow map texture coords
|
// In variables
|
||||||
|
in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
|
||||||
// Out variable
|
in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
|
||||||
out vec4 color; // Output color
|
in vec2 texCoords; // Texture coordinates
|
||||||
|
in vec4 shadowMapCoords[3]; // Shadow map texture coords
|
||||||
// Texture for PCF Shadow mapping
|
|
||||||
float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset)
|
// Out variable
|
||||||
{
|
out vec4 color; // Output color
|
||||||
vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension;
|
|
||||||
return texture(map, texCoords.xy + offset * shadowMapScale).r;
|
// Texture for PCF Shadow mapping
|
||||||
}
|
float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset)
|
||||||
|
{
|
||||||
void main() {
|
vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension;
|
||||||
|
return texture(map, texCoords.xy + offset * shadowMapScale).r;
|
||||||
// Compute the ambient term
|
}
|
||||||
vec3 ambient = lightAmbientColor;
|
|
||||||
|
void main() {
|
||||||
// Get the texture color
|
|
||||||
vec3 textureColor = vertexColor.rgb;
|
// Compute the ambient term
|
||||||
if (isTexture) textureColor = texture(textureSampler, texCoords).rgb;
|
vec3 ambient = lightAmbientColor;
|
||||||
|
|
||||||
// Compute the surface normal vector
|
// Get the texture color
|
||||||
vec3 N = normalize(vertexNormalCameraSpace);
|
vec3 textureColor = vertexColor.rgb;
|
||||||
|
if (isTexture) textureColor = texture(textureSampler, texCoords).rgb;
|
||||||
// Compute the diffuse term of light 0
|
|
||||||
vec3 L0 = normalize(light0PosCameraSpace - vertexPosCameraSpace);
|
// Compute the surface normal vector
|
||||||
float diffuseFactor = max(dot(N, L0), 0.0);
|
vec3 N = normalize(vertexNormalCameraSpace);
|
||||||
vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor;
|
|
||||||
|
color = vec4(ambient, 1);
|
||||||
// Compute shadow factor
|
|
||||||
float shadow = 1.0;
|
vec3 lightPosCameraSpace[3];
|
||||||
if (isShadowEnabled) {
|
lightPosCameraSpace[0] = light0PosCameraSpace;
|
||||||
shadow = 0.0;
|
lightPosCameraSpace[1] = light1PosCameraSpace;
|
||||||
float bias = 0.0003;
|
lightPosCameraSpace[2] = light2PosCameraSpace;
|
||||||
float shadowBias = -0.000;
|
vec3 lightDiffuseColor[3];
|
||||||
vec4 shadowMapUV = shadowMapCoords;
|
lightDiffuseColor[0] = light0DiffuseColor;
|
||||||
shadowMapUV.z -= shadowBias;
|
lightDiffuseColor[1] = light1DiffuseColor;
|
||||||
vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w;
|
lightDiffuseColor[2] = light2DiffuseColor;
|
||||||
|
|
||||||
// PCF Shadow Mapping
|
// For each light source
|
||||||
for (float i=-1; i<=1; i++) {
|
for (int l=0; l < 3; l++) {
|
||||||
for (float j=-1; j<=1; j++) {
|
|
||||||
float distInShadowMap = textureLookupPCF(shadowMapSampler, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
|
// Compute the diffuse term of light 0
|
||||||
if (shadowMapCoords.w > 0) {
|
vec3 L0 = normalize(lightPosCameraSpace[l] - vertexPosCameraSpace);
|
||||||
shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
|
float diffuseFactor = max(dot(N, L0), 0.0);
|
||||||
}
|
vec3 diffuse = lightDiffuseColor[l] * diffuseFactor * textureColor;
|
||||||
}
|
|
||||||
}
|
// Compute shadow factor
|
||||||
shadow /= 9.0;
|
float shadow = 1.0;
|
||||||
|
if (isShadowEnabled) {
|
||||||
/*
|
shadow = 0.0;
|
||||||
float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias;
|
float bias = 0.0003;
|
||||||
if (shadowMapCoords.w > 0) {
|
float shadowBias = -0.000;
|
||||||
shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
|
vec4 shadowMapUV = shadowMapCoords[l];
|
||||||
}
|
shadowMapUV.z -= shadowBias;
|
||||||
*/
|
vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w;
|
||||||
}
|
|
||||||
|
// PCF Shadow Mapping
|
||||||
// Compute the final color
|
for (float i=-1; i<=1; i++) {
|
||||||
color = vec4(ambient + shadow * diffuse, 1.0);
|
for (float j=-1; j<=1; j++) {
|
||||||
}
|
float distInShadowMap = textureLookupPCF(shadowMapSampler[l], shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,64 +1,78 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* OpenGL-Framework *
|
* OpenGL-Framework *
|
||||||
* Copyright (c) 2015 Daniel Chappuis *
|
* Copyright (c) 2015 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Uniform variables
|
// Uniform variables
|
||||||
uniform mat4 localToWorldMatrix; // Local-space to world-space matrix
|
uniform mat4 localToWorldMatrix; // Local-space to world-space matrix
|
||||||
uniform mat4 worldToCameraMatrix; // World-space to camera-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 worldToLight0CameraMatrix; // World-space to light0 camera-space matrix (for shadow mapping)
|
||||||
uniform mat4 projectionMatrix; // Projection matrix
|
uniform mat4 worldToLight1CameraMatrix; // World-space to light1 camera-space matrix (for shadow mapping)
|
||||||
uniform mat3 normalMatrix; // Normal matrix
|
uniform mat4 worldToLight2CameraMatrix; // World-space to light2 camera-space matrix (for shadow mapping)
|
||||||
uniform mat4 shadowMapProjectionMatrix; // Shadow map projection matrix
|
uniform mat4 projectionMatrix; // Projection matrix
|
||||||
|
uniform mat3 normalMatrix; // Normal matrix
|
||||||
// In variables
|
uniform mat4 shadowMapLight0ProjectionMatrix; // Shadow map projection matrix for light 0
|
||||||
in vec4 vertexPosition;
|
uniform mat4 shadowMapLight1ProjectionMatrix; // Shadow map projection matrix for light 1
|
||||||
in vec3 vertexNormal;
|
uniform mat4 shadowMapLight2ProjectionMatrix; // Shadow map projection matrix for light 2
|
||||||
in vec2 textureCoords;
|
|
||||||
|
// In variables
|
||||||
// Out variables
|
in vec4 vertexPosition;
|
||||||
out vec3 vertexPosCameraSpace; // Camera-space position of the vertex
|
in vec3 vertexNormal;
|
||||||
out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
|
in vec2 textureCoords;
|
||||||
out vec2 texCoords; // Texture coordinates
|
|
||||||
out vec4 shadowMapCoords; // Shadow map texture coords
|
// Out variables
|
||||||
|
out vec3 vertexPosCameraSpace; // Camera-space position of the vertex
|
||||||
void main() {
|
out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
|
||||||
|
out vec2 texCoords; // Texture coordinates
|
||||||
// Compute the vertex position
|
out vec4 shadowMapCoords[3]; // Shadow map texture coords
|
||||||
vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition;
|
|
||||||
vertexPosCameraSpace = positionCameraSpace.xyz;
|
void main() {
|
||||||
|
|
||||||
// Compute the world surface normal
|
// Compute the vertex position
|
||||||
vertexNormalCameraSpace = normalMatrix * vertexNormal;
|
vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition;
|
||||||
|
vertexPosCameraSpace = positionCameraSpace.xyz;
|
||||||
// Get the texture coordinates
|
|
||||||
texCoords = textureCoords;
|
// Compute the world surface normal
|
||||||
|
vertexNormalCameraSpace = normalMatrix * vertexNormal;
|
||||||
// Compute the texture coords of the vertex in the shadow map
|
|
||||||
shadowMapCoords = shadowMapProjectionMatrix * worldToLight0CameraMatrix * localToWorldMatrix * vertexPosition;
|
// Get the texture coordinates
|
||||||
|
texCoords = textureCoords;
|
||||||
// Compute the clip-space vertex coordinates
|
|
||||||
gl_Position = projectionMatrix * positionCameraSpace;
|
// 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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,49 +1,64 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "TestbedApplication.h"
|
#include "TestbedApplication.h"
|
||||||
#include "nanogui/nanogui.h"
|
#include "nanogui/nanogui.h"
|
||||||
|
|
||||||
using namespace nanogui;
|
using namespace nanogui;
|
||||||
|
|
||||||
// Main function
|
// Main function
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
nanogui::init();
|
nanogui::init();
|
||||||
|
|
||||||
{
|
{
|
||||||
// Create and start the testbed application
|
bool isFullscreen = false;
|
||||||
bool isFullscreen = false;
|
|
||||||
nanogui::ref<TestbedApplication> application = new TestbedApplication(isFullscreen);
|
// Get the primary monitor
|
||||||
application->setVisible(true);
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||||
nanogui::mainloop();
|
|
||||||
}
|
// Window size
|
||||||
|
int windowWidth = mode->width;
|
||||||
nanogui::shutdown();
|
int windowHeight = mode->height;
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,460 +1,522 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "SceneDemo.h"
|
#include "SceneDemo.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include "AABB.h"
|
#include "AABB.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include "collision/ContactManifold.h"
|
#include "collision/ContactManifold.h"
|
||||||
|
|
||||||
using namespace openglframework;
|
using namespace openglframework;
|
||||||
|
|
||||||
int SceneDemo::shadowMapTextureLevel = 0;
|
int SceneDemo::shadowMapTextureLevel = 0;
|
||||||
openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0f);
|
openglframework::Color SceneDemo::mObjectColorDemo = Color(0.76f, 0.67f, 0.47f, 1.0f);
|
||||||
openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9f, 0.88f, 0.145f, 1.0f);
|
openglframework::Color SceneDemo::mFloorColorDemo = Color(0.47f, 0.48f, 0.49f, 1.0f);
|
||||||
openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66f, 0.95f, 1.0f);
|
openglframework::Color SceneDemo::mSleepingColorDemo = Color(1.0f, 0.25f, 0.25f, 1.0f);
|
||||||
openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9f, 0.35f, 0, 1.0f);
|
openglframework::Color SceneDemo::mSelectedObjectColorDemo = Color(0.09f, 0.59f, 0.88f, 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);
|
// Constructor
|
||||||
int SceneDemo::mNbDemoColors = 4;
|
SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled)
|
||||||
openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo,
|
: Scene(name, settings, isShadowMappingEnabled), mIsShadowMappingInitialized(false),
|
||||||
SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo};
|
mDepthShader("shaders/depth.vert", "shaders/depth.frag"),
|
||||||
|
mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
|
||||||
// Constructor
|
mColorShader("shaders/color.vert", "shaders/color.frag"),
|
||||||
SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled)
|
mQuadShader("shaders/quad.vert", "shaders/quad.frag"),
|
||||||
: Scene(name, settings, isShadowMappingEnabled), mIsShadowMappingInitialized(false),
|
mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/"),
|
||||||
mDepthShader("shaders/depth.vert", "shaders/depth.frag"),
|
mPhysicsWorld(nullptr) {
|
||||||
mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
|
|
||||||
mColorShader("shaders/color.vert", "shaders/color.frag"),
|
shadowMapTextureLevel++;
|
||||||
mQuadShader("shaders/quad.vert", "shaders/quad.frag"),
|
|
||||||
mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/"),
|
// Move the lights
|
||||||
mPhysicsWorld(nullptr) {
|
float lightsRadius = 30.0f;
|
||||||
|
float lightsHeight = 20.0f;
|
||||||
shadowMapTextureLevel++;
|
mLight0.translateWorld(Vector3(0 * lightsRadius, lightsHeight, 1 * lightsRadius));
|
||||||
|
mLight1.translateWorld(Vector3(0.95f * lightsRadius, lightsHeight, -0.3f * lightsRadius));
|
||||||
// Move the light0
|
mLight2.translateWorld(Vector3(-0.58f * lightsRadius, lightsHeight, -0.81f * lightsRadius));
|
||||||
mLight0.translateWorld(Vector3(-2, 35, 40));
|
|
||||||
|
// Set the lights colors
|
||||||
// Camera at light0 postion for the shadow map
|
mLight0.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
|
||||||
mShadowMapLightCamera.translateWorld(mLight0.getOrigin());
|
mLight1.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
|
||||||
mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 4.0f);
|
mLight2.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
|
||||||
mShadowMapLightCamera.rotateWorld(Vector3(0, 1, 0), PI / 8.0f);
|
|
||||||
|
mShadowMapLightCameras[0].translateWorld(mLight0.getOrigin());
|
||||||
mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
|
mShadowMapLightCameras[0].rotateLocal(Vector3(1, 0, 0), -PI / 4.0f);
|
||||||
mShadowMapLightCamera.setFieldOfView(80.0f);
|
|
||||||
mShadowMapLightCamera.setSceneRadius(100);
|
mShadowMapLightCameras[1].translateWorld(mLight1.getOrigin());
|
||||||
|
mShadowMapLightCameras[1].rotateLocal(Vector3(0, 1, 0), -5.0f * PI/3.7f);
|
||||||
mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5,
|
mShadowMapLightCameras[1].rotateLocal(Vector3(1, 0, 0), -PI/4.0f);
|
||||||
0.0, 0.5, 0.0, 0.5,
|
|
||||||
0.0, 0.0, 0.5, 0.5,
|
mShadowMapLightCameras[2].translateWorld(mLight2.getOrigin());
|
||||||
0.0, 0.0, 0.0, 1.0);
|
mShadowMapLightCameras[2].rotateLocal(Vector3(0, 1, 0), 5 * PI/4.0f);
|
||||||
|
mShadowMapLightCameras[2].rotateLocal(Vector3(1, 0 , 0), -PI/4.0f);
|
||||||
// Create the Shadow map FBO and texture
|
|
||||||
if (mIsShadowMappingEnabled) {
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
createShadowMapFBOAndTexture();
|
mShadowMapLightCameras[i].setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
|
||||||
}
|
mShadowMapLightCameras[i].setFieldOfView(100.0f);
|
||||||
|
mShadowMapLightCameras[i].setSceneRadius(100);
|
||||||
createQuadVBO();
|
}
|
||||||
|
|
||||||
// Init rendering for the AABBs
|
mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5,
|
||||||
AABB::init();
|
0.0, 0.5, 0.0, 0.5,
|
||||||
|
0.0, 0.0, 0.5, 0.5,
|
||||||
VisualContactPoint::createStaticData(mMeshFolderPath);
|
0.0, 0.0, 0.0, 1.0);
|
||||||
}
|
|
||||||
|
// Create the Shadow map FBO and texture
|
||||||
// Destructor
|
if (mIsShadowMappingEnabled) {
|
||||||
SceneDemo::~SceneDemo() {
|
createShadowMapFBOAndTexture();
|
||||||
|
}
|
||||||
mShadowMapTexture.destroy();
|
|
||||||
mFBOShadowMap.destroy();
|
createQuadVBO();
|
||||||
mVBOQuad.destroy();
|
|
||||||
|
// Init rendering for the AABBs
|
||||||
mDepthShader.destroy();
|
AABB::init();
|
||||||
mPhongShader.destroy();
|
|
||||||
mQuadShader.destroy();
|
VisualContactPoint::createStaticData(mMeshFolderPath);
|
||||||
mColorShader.destroy();
|
}
|
||||||
|
|
||||||
// Destroy the contact points
|
// Destructor
|
||||||
removeAllContactPoints();
|
SceneDemo::~SceneDemo() {
|
||||||
|
|
||||||
// Destroy rendering data for the AABB
|
|
||||||
AABB::destroy();
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
|
mShadowMapTexture[i].destroy();
|
||||||
VisualContactPoint::destroyStaticData();
|
mFBOShadowMap[i].destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the scene
|
mVBOQuad.destroy();
|
||||||
void SceneDemo::update() {
|
|
||||||
|
mDepthShader.destroy();
|
||||||
// Update the contact points
|
mPhongShader.destroy();
|
||||||
updateContactPoints();
|
mQuadShader.destroy();
|
||||||
|
mColorShader.destroy();
|
||||||
// Update the position and orientation of the physics objects
|
|
||||||
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
// Destroy the contact points
|
||||||
|
removeAllContactPoints();
|
||||||
// Update the transform used for the rendering
|
|
||||||
(*it)->updateTransform(mInterpolationFactor);
|
// Destroy rendering data for the AABB
|
||||||
}
|
AABB::destroy();
|
||||||
}
|
|
||||||
|
VisualContactPoint::destroyStaticData();
|
||||||
// Update the physics world (take a simulation step)
|
}
|
||||||
// Can be called several times per frame
|
|
||||||
void SceneDemo::updatePhysics() {
|
// Update the scene
|
||||||
|
void SceneDemo::update() {
|
||||||
if (getDynamicsWorld() != nullptr) {
|
|
||||||
|
// Update the contact points
|
||||||
// Take a simulation step
|
updateContactPoints();
|
||||||
getDynamicsWorld()->update(mEngineSettings.timeStep);
|
|
||||||
}
|
// Update the position and orientation of the physics objects
|
||||||
}
|
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
||||||
|
|
||||||
// Render the scene (in multiple passes for shadow mapping)
|
// Update the transform used for the rendering
|
||||||
void SceneDemo::render() {
|
(*it)->updateTransform(mInterpolationFactor);
|
||||||
|
}
|
||||||
const Color& diffCol = mLight0.getDiffuseColor();
|
}
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
// Update the physics world (take a simulation step)
|
||||||
glEnable(GL_CULL_FACE);
|
// Can be called several times per frame
|
||||||
|
void SceneDemo::updatePhysics() {
|
||||||
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
|
|
||||||
|
if (getDynamicsWorld() != nullptr) {
|
||||||
const Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix();
|
|
||||||
const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse();
|
// Take a simulation step
|
||||||
|
getDynamicsWorld()->update(mEngineSettings.timeStep);
|
||||||
// If Shadow Mapping is enabled
|
}
|
||||||
if (mIsShadowMappingEnabled) {
|
}
|
||||||
|
|
||||||
// Culling switching, rendering only backface, this is done to avoid self-shadowing
|
// Render the scene (in multiple passes for shadow mapping)
|
||||||
glCullFace(GL_BACK);
|
void SceneDemo::render() {
|
||||||
|
|
||||||
mFBOShadowMap.bind();
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
// Bind the shader
|
|
||||||
mDepthShader.bind();
|
Matrix4 shadowMapProjMatrix[NB_SHADOW_MAPS];
|
||||||
|
openglframework::Matrix4 worldToLightCameraMatrix[NB_SHADOW_MAPS];
|
||||||
// Set the variables of the shader
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix);
|
|
||||||
|
shadowMapProjMatrix[i] = mShadowMapLightCameras[i].getProjectionMatrix();
|
||||||
// Set the viewport to render into the shadow map texture
|
worldToLightCameraMatrix[i] = mShadowMapLightCameras[i].getTransformMatrix().getInverse();
|
||||||
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
|
}
|
||||||
|
|
||||||
// Clear previous frame values
|
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
// If Shadow Mapping is enabled
|
||||||
// Disable color rendering, we only want to write to the Z-Buffer
|
if (mIsShadowMappingEnabled) {
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
||||||
|
// Culling switching, rendering only backface, this is done to avoid self-shadowing
|
||||||
// Render the objects of the scene
|
glCullFace(GL_BACK);
|
||||||
renderSinglePass(mDepthShader, worldToLightCameraMatrix);
|
|
||||||
|
// For each shadow map
|
||||||
// Unbind the shader
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
mDepthShader.unbind();
|
|
||||||
|
mFBOShadowMap[i].bind();
|
||||||
mFBOShadowMap.unbind();
|
|
||||||
|
// Bind the shader
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
mDepthShader.bind();
|
||||||
}
|
|
||||||
|
// Set the variables of the shader
|
||||||
// ---------- Render the scene for final rendering (second pass) ----------- //
|
mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix[i]);
|
||||||
|
|
||||||
glCullFace(GL_BACK);
|
// Set the viewport to render into the shadow map texture
|
||||||
|
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
|
||||||
// Get the world-space to camera-space matrix
|
|
||||||
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
|
// Clear previous frame values
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
mPhongShader.bind();
|
|
||||||
|
// Disable color rendering, we only want to write to the Z-Buffer
|
||||||
if (mIsShadowMappingEnabled) mShadowMapTexture.bind();
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
const GLuint textureUnit = 0;
|
|
||||||
|
// Render the objects of the scene
|
||||||
// Set the variables of the phong shader
|
renderSinglePass(mDepthShader, worldToLightCameraMatrix[i]);
|
||||||
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
|
|
||||||
mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix);
|
// Unbind the shader
|
||||||
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix);
|
mDepthShader.unbind();
|
||||||
mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin());
|
|
||||||
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.4f, 0.4f, 0.4f));
|
mFBOShadowMap[i].unbind();
|
||||||
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
|
}
|
||||||
mPhongShader.setIntUniform("shadowMapSampler", textureUnit);
|
|
||||||
mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT));
|
}
|
||||||
mPhongShader.unbind();
|
|
||||||
|
// ---------- Render the scene for final rendering (second pass) ----------- //
|
||||||
// Set the variables of the color shader
|
|
||||||
mColorShader.bind();
|
glCullFace(GL_BACK);
|
||||||
mColorShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
|
|
||||||
mColorShader.unbind();
|
// Get the world-space to camera-space matrix
|
||||||
|
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
|
||||||
// Set the viewport to render the scene
|
|
||||||
glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight);
|
mPhongShader.bind();
|
||||||
|
|
||||||
//Enabling color write (previously disabled for light POV z-buffer rendering)
|
// Is shadow mapping is enabled
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
GLint textureUnits[NB_SHADOW_MAPS];
|
||||||
|
if (mIsShadowMappingEnabled) {
|
||||||
// Clear previous frame values
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
|
mShadowMapTexture[i].bind();
|
||||||
// Render the objects of the scene
|
}
|
||||||
renderSinglePass(mPhongShader, worldToCameraMatrix);
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
|
textureUnits[i] = mShadowMapTexture[i].getUnit();
|
||||||
// Render the contact points
|
}
|
||||||
if (mIsContactPointsDisplayed) {
|
}
|
||||||
renderContactPoints(mPhongShader, worldToCameraMatrix);
|
|
||||||
}
|
// Set the variables of the phong shader
|
||||||
|
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
|
||||||
// Render the AABBs
|
mPhongShader.setMatrix4x4Uniform("shadowMapLight0ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[0]);
|
||||||
if (mIsAABBsDisplayed) {
|
mPhongShader.setMatrix4x4Uniform("shadowMapLight1ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[1]);
|
||||||
renderAABBs(worldToCameraMatrix);
|
mPhongShader.setMatrix4x4Uniform("shadowMapLight2ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[2]);
|
||||||
}
|
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix[0]);
|
||||||
|
mPhongShader.setMatrix4x4Uniform("worldToLight1CameraMatrix", worldToLightCameraMatrix[1]);
|
||||||
if (mIsShadowMappingEnabled) mShadowMapTexture.unbind();
|
mPhongShader.setMatrix4x4Uniform("worldToLight2CameraMatrix", worldToLightCameraMatrix[2]);
|
||||||
mPhongShader.unbind();
|
mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin());
|
||||||
|
mPhongShader.setVector3Uniform("light1PosCameraSpace", worldToCameraMatrix * mLight1.getOrigin());
|
||||||
//drawTextureQuad();
|
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));
|
||||||
// Render the scene in a single pass
|
mPhongShader.setVector3Uniform("light1DiffuseColor", Vector3(mLight1.getDiffuseColor().r, mLight1.getDiffuseColor().g, mLight1.getDiffuseColor().b));
|
||||||
void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
|
mPhongShader.setVector3Uniform("light2DiffuseColor", Vector3(mLight2.getDiffuseColor().r, mLight2.getDiffuseColor().g, mLight2.getDiffuseColor().b));
|
||||||
|
mPhongShader.setIntArrayUniform("shadowMapSampler", textureUnits, NB_SHADOW_MAPS);
|
||||||
if (mIsWireframeEnabled) {
|
mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT));
|
||||||
}
|
mPhongShader.unbind();
|
||||||
|
|
||||||
// Bind the shader
|
// Set the variables of the color shader
|
||||||
shader.bind();
|
mColorShader.bind();
|
||||||
|
mColorShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
|
||||||
// Render all the physics objects of the scene
|
mColorShader.unbind();
|
||||||
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
|
||||||
(*it)->render(mIsWireframeEnabled ? mColorShader : shader, worldToCameraMatrix);
|
// Set the viewport to render the scene
|
||||||
}
|
glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight);
|
||||||
|
|
||||||
// Unbind the shader
|
//Enabling color write (previously disabled for light POV z-buffer rendering)
|
||||||
shader.unbind();
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
|
||||||
if (mIsWireframeEnabled) {
|
// Clear previous frame values
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
|
||||||
}
|
// Render the objects of the scene
|
||||||
|
renderSinglePass(mPhongShader, worldToCameraMatrix);
|
||||||
// Create the Shadow map FBO and texture
|
|
||||||
void SceneDemo::createShadowMapFBOAndTexture() {
|
// Render the contact points
|
||||||
|
if (mIsContactPointsDisplayed) {
|
||||||
// Create the texture for the depth values
|
renderContactPoints(mPhongShader, worldToCameraMatrix);
|
||||||
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);
|
|
||||||
|
// Render the AABBs
|
||||||
// Create the FBO for the shadow map
|
if (mIsAABBsDisplayed) {
|
||||||
mFBOShadowMap.create(0, 0, false);
|
renderAABBs(worldToCameraMatrix);
|
||||||
mFBOShadowMap.bind();
|
}
|
||||||
|
|
||||||
// Tell OpenGL that we won't bind a color texture with the currently binded FBO
|
// Is shadow mapping is enabled
|
||||||
glDrawBuffer(GL_NONE);
|
if (mIsShadowMappingEnabled) {
|
||||||
glReadBuffer(GL_NONE);
|
|
||||||
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT, mShadowMapTexture.getID());
|
mShadowMapTexture[i].unbind();
|
||||||
mFBOShadowMap.unbind();
|
}
|
||||||
|
}
|
||||||
mIsShadowMappingInitialized = true;
|
|
||||||
}
|
mPhongShader.unbind();
|
||||||
|
|
||||||
// Used for debugging shadow maps
|
//drawTextureQuad();
|
||||||
void SceneDemo::createQuadVBO() {
|
}
|
||||||
|
|
||||||
mVAOQuad.create();
|
// Render the scene in a single pass
|
||||||
mVAOQuad.bind();
|
void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
|
||||||
|
|
||||||
static const GLfloat quadVertexData[] = {
|
if (mIsWireframeEnabled) {
|
||||||
-1.0f, -1.0f, 0.0f,
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
1.0f, -1.0f, 0.0f,
|
}
|
||||||
-1.0f, 1.0f, 0.0f,
|
|
||||||
-1.0f, 1.0f, 0.0f,
|
// Bind the shader
|
||||||
1.0f, -1.0f, 0.0f,
|
shader.bind();
|
||||||
1.0f, 1.0f, 0.0f,
|
|
||||||
};
|
// Render all the physics objects of the scene
|
||||||
|
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
||||||
mVBOQuad.create();
|
(*it)->render(mIsWireframeEnabled ? mColorShader : shader, worldToCameraMatrix);
|
||||||
mVBOQuad.bind();
|
}
|
||||||
mVBOQuad.copyDataIntoVBO(sizeof(quadVertexData), quadVertexData, GL_STATIC_DRAW);
|
|
||||||
mVBOQuad.unbind();
|
// Unbind the shader
|
||||||
|
shader.unbind();
|
||||||
mVAOQuad.unbind();
|
|
||||||
}
|
if (mIsWireframeEnabled) {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
void SceneDemo::drawTextureQuad() {
|
}
|
||||||
|
}
|
||||||
glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight);
|
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
// Create the Shadow map FBO and texture
|
||||||
|
void SceneDemo::createShadowMapFBOAndTexture() {
|
||||||
// Clear previous frame values
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
// For each shadow map
|
||||||
|
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
|
||||||
const GLuint textureUnit = 0;
|
|
||||||
|
// Create the texture for the depth values
|
||||||
mVAOQuad.bind();
|
mShadowMapTexture[i].create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT,
|
||||||
mQuadShader.bind();
|
GL_UNSIGNED_BYTE, GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, NULL);
|
||||||
mShadowMapTexture.bind();
|
|
||||||
mQuadShader.setIntUniform("textureSampler", textureUnit);
|
mShadowMapTexture[i].setUnit(i);
|
||||||
mVBOQuad.bind();
|
|
||||||
|
// Make sure that texture lookups outside the texture coords range will not
|
||||||
GLint vertexPositionLoc = mQuadShader.getAttribLocation("vertexPosition");
|
// treated as beeing in shadow
|
||||||
glEnableVertexAttribArray(vertexPositionLoc);
|
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture[i].getID());
|
||||||
|
GLfloat border[] = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
glVertexAttribPointer(
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
|
||||||
vertexPositionLoc, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
3, // size
|
|
||||||
GL_FLOAT, // type
|
// Create the FBO for the shadow map
|
||||||
GL_FALSE, // normalized?
|
mFBOShadowMap[i].create(0, 0, false);
|
||||||
0, // stride
|
mFBOShadowMap[i].bind();
|
||||||
(void*)0 // array buffer offset
|
|
||||||
);
|
// Tell OpenGL that we won't bind a color texture with the currently binded FBO
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
// Draw the triangles !
|
glReadBuffer(GL_NONE);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
|
|
||||||
|
mFBOShadowMap[i].attachTexture(GL_DEPTH_ATTACHMENT, mShadowMapTexture[i].getID());
|
||||||
glDisableVertexAttribArray(vertexPositionLoc);
|
mFBOShadowMap[i].unbind();
|
||||||
|
}
|
||||||
mVBOQuad.unbind();
|
|
||||||
mShadowMapTexture.unbind();
|
mIsShadowMappingInitialized = true;
|
||||||
mQuadShader.unbind();
|
}
|
||||||
mVAOQuad.unbind();
|
|
||||||
}
|
// Used for debugging shadow maps
|
||||||
|
void SceneDemo::createQuadVBO() {
|
||||||
// Gather and create contact points
|
|
||||||
void SceneDemo::updateContactPoints() {
|
mVAOQuad.create();
|
||||||
|
mVAOQuad.bind();
|
||||||
// Remove the previous contact points
|
|
||||||
removeAllContactPoints();
|
static const GLfloat quadVertexData[] = {
|
||||||
|
-1.0f, -1.0f, 0.0f,
|
||||||
if (mIsContactPointsDisplayed) {
|
1.0f, -1.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, 0.0f,
|
||||||
// Get the current contact points of the scene
|
-1.0f, 1.0f, 0.0f,
|
||||||
std::vector<ContactPoint> contactPoints = getContactPoints();
|
1.0f, -1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, 0.0f,
|
||||||
// For each contact point
|
};
|
||||||
std::vector<ContactPoint>::const_iterator it;
|
|
||||||
for (it = contactPoints.begin(); it != contactPoints.end(); ++it) {
|
mVBOQuad.create();
|
||||||
|
mVBOQuad.bind();
|
||||||
// Create a visual contact point for rendering
|
mVBOQuad.copyDataIntoVBO(sizeof(quadVertexData), quadVertexData, GL_STATIC_DRAW);
|
||||||
VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath, it->point + it->normal, it->color);
|
mVBOQuad.unbind();
|
||||||
mContactPoints.push_back(point);
|
|
||||||
}
|
mVAOQuad.unbind();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
void SceneDemo::drawTextureQuad() {
|
||||||
// Render the contact points
|
|
||||||
void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
|
glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight);
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
// Render all the contact points
|
|
||||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
// Clear previous frame values
|
||||||
it != mContactPoints.end(); ++it) {
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
(*it)->render(mColorShader, worldToCameraMatrix);
|
|
||||||
}
|
|
||||||
}
|
const int SHADOW_MAP_TEXTURE_TO_DRAW = 0;
|
||||||
|
const GLuint textureUnit = SHADOW_MAP_TEXTURE_TO_DRAW;
|
||||||
// Render the AABBs
|
|
||||||
void SceneDemo::renderAABBs(const openglframework::Matrix4& worldToCameraMatrix) {
|
mVAOQuad.bind();
|
||||||
|
mQuadShader.bind();
|
||||||
// For each physics object of the scene
|
mShadowMapTexture[SHADOW_MAP_TEXTURE_TO_DRAW].bind();
|
||||||
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
mQuadShader.setIntUniform("textureSampler", textureUnit);
|
||||||
|
mVBOQuad.bind();
|
||||||
// For each proxy shape of the object
|
|
||||||
rp3d::ProxyShape* proxyShape = (*it)->getCollisionBody()->getProxyShapesList();
|
GLint vertexPositionLoc = mQuadShader.getAttribLocation("vertexPosition");
|
||||||
while (proxyShape != nullptr) {
|
glEnableVertexAttribArray(vertexPositionLoc);
|
||||||
|
|
||||||
// Get the broad-phase AABB corresponding to the proxy shape
|
glVertexAttribPointer(
|
||||||
rp3d::AABB aabb = mPhysicsWorld->getWorldAABB(proxyShape);
|
vertexPositionLoc, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
||||||
|
3, // size
|
||||||
openglframework::Vector3 aabbCenter(aabb.getCenter().x, aabb.getCenter().y, aabb.getCenter().z);
|
GL_FLOAT, // type
|
||||||
openglframework::Vector3 aabbMin(aabb.getMin().x, aabb.getMin().y, aabb.getMin().z);
|
GL_FALSE, // normalized?
|
||||||
openglframework::Vector3 aabbMax(aabb.getMax().x, aabb.getMax().y, aabb.getMax().z);
|
0, // stride
|
||||||
|
(void*)0 // array buffer offset
|
||||||
// Render the AABB
|
);
|
||||||
AABB::render(aabbCenter, aabbMax - aabbMin, Color::green(), mColorShader, worldToCameraMatrix);
|
|
||||||
|
// Draw the triangles !
|
||||||
proxyShape = proxyShape->getNext();
|
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
|
||||||
}
|
|
||||||
}
|
glDisableVertexAttribArray(vertexPositionLoc);
|
||||||
}
|
|
||||||
|
mVBOQuad.unbind();
|
||||||
void SceneDemo::removeAllContactPoints() {
|
mShadowMapTexture[SHADOW_MAP_TEXTURE_TO_DRAW].unbind();
|
||||||
|
mQuadShader.unbind();
|
||||||
// Destroy all the visual contact points
|
mVAOQuad.unbind();
|
||||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
}
|
||||||
it != mContactPoints.end(); ++it) {
|
|
||||||
delete (*it);
|
// Gather and create contact points
|
||||||
}
|
void SceneDemo::updateContactPoints() {
|
||||||
mContactPoints.clear();
|
|
||||||
}
|
// Remove the previous contact points
|
||||||
|
removeAllContactPoints();
|
||||||
// Return all the contact points of the scene
|
|
||||||
std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsWorld* world) {
|
if (mIsContactPointsDisplayed) {
|
||||||
|
|
||||||
std::vector<ContactPoint> contactPoints;
|
// Get the current contact points of the scene
|
||||||
|
std::vector<ContactPoint> contactPoints = getContactPoints();
|
||||||
// Get the list of contact manifolds from the world
|
|
||||||
rp3d::List<const rp3d::ContactManifold*> manifolds = world->getContactsList();
|
// For each contact point
|
||||||
|
std::vector<ContactPoint>::const_iterator it;
|
||||||
// For each contact manifold
|
for (it = contactPoints.begin(); it != contactPoints.end(); ++it) {
|
||||||
rp3d::List<const rp3d::ContactManifold*>::Iterator it;
|
|
||||||
for (it = manifolds.begin(); it != manifolds.end(); ++it) {
|
// Create a visual contact point for rendering
|
||||||
|
VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath, it->point + it->normal, it->color);
|
||||||
const rp3d::ContactManifold* manifold = *it;
|
mContactPoints.push_back(point);
|
||||||
|
}
|
||||||
// For each contact point of the manifold
|
}
|
||||||
rp3d::ContactPoint* contactPoint = manifold->getContactPoints();
|
}
|
||||||
while (contactPoint != nullptr) {
|
|
||||||
|
// Render the contact points
|
||||||
rp3d::Vector3 point = manifold->getShape1()->getLocalToWorldTransform() * contactPoint->getLocalPointOnShape1();
|
void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
|
||||||
rp3d::Vector3 normalWorld = contactPoint->getNormal();
|
|
||||||
openglframework::Vector3 normal = openglframework::Vector3(normalWorld.x, normalWorld.y, normalWorld.z);
|
// Render all the contact points
|
||||||
ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z), normal, openglframework::Color::red());
|
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||||
contactPoints.push_back(contact);
|
it != mContactPoints.end(); ++it) {
|
||||||
|
(*it)->render(mColorShader, worldToCameraMatrix);
|
||||||
contactPoint = contactPoint->getNext();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// Render the AABBs
|
||||||
|
void SceneDemo::renderAABBs(const openglframework::Matrix4& worldToCameraMatrix) {
|
||||||
return contactPoints;
|
|
||||||
}
|
// For each physics object of the scene
|
||||||
|
for (std::vector<PhysicsObject*>::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) {
|
||||||
// Update the engine settings
|
|
||||||
void SceneDemo::updateEngineSettings() {
|
// For each proxy shape of the object
|
||||||
|
rp3d::ProxyShape* proxyShape = (*it)->getCollisionBody()->getProxyShapesList();
|
||||||
if (getDynamicsWorld() != nullptr) {
|
while (proxyShape != nullptr) {
|
||||||
|
|
||||||
// Update the physics engine parameters
|
// Get the broad-phase AABB corresponding to the proxy shape
|
||||||
getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
rp3d::AABB aabb = mPhysicsWorld->getWorldAABB(proxyShape);
|
||||||
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
|
||||||
mEngineSettings.gravity.z);
|
openglframework::Vector3 aabbCenter(aabb.getCenter().x, aabb.getCenter().y, aabb.getCenter().z);
|
||||||
getDynamicsWorld()->setGravity(gravity);
|
openglframework::Vector3 aabbMin(aabb.getMin().x, aabb.getMin().y, aabb.getMin().z);
|
||||||
getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled);
|
openglframework::Vector3 aabbMax(aabb.getMax().x, aabb.getMax().y, aabb.getMax().z);
|
||||||
getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
|
||||||
getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
// Render the AABB
|
||||||
getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
AABB::render(aabbCenter, aabbMax - aabbMin, Color::green(), mColorShader, worldToCameraMatrix);
|
||||||
getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
|
||||||
getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
proxyShape = proxyShape->getNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneDemo::removeAllContactPoints() {
|
||||||
|
|
||||||
|
// Destroy all the visual contact points
|
||||||
|
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||||
|
it != mContactPoints.end(); ++it) {
|
||||||
|
delete (*it);
|
||||||
|
}
|
||||||
|
mContactPoints.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all the contact points of the scene
|
||||||
|
std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsWorld* world) {
|
||||||
|
|
||||||
|
std::vector<ContactPoint> contactPoints;
|
||||||
|
|
||||||
|
// Get the list of contact manifolds from the world
|
||||||
|
rp3d::List<const rp3d::ContactManifold*> manifolds = world->getContactsList();
|
||||||
|
|
||||||
|
// For each contact manifold
|
||||||
|
rp3d::List<const rp3d::ContactManifold*>::Iterator it;
|
||||||
|
for (it = manifolds.begin(); it != manifolds.end(); ++it) {
|
||||||
|
|
||||||
|
const rp3d::ContactManifold* manifold = *it;
|
||||||
|
|
||||||
|
// For each contact point of the manifold
|
||||||
|
rp3d::ContactPoint* contactPoint = manifold->getContactPoints();
|
||||||
|
while (contactPoint != nullptr) {
|
||||||
|
|
||||||
|
rp3d::Vector3 point = manifold->getShape1()->getLocalToWorldTransform() * contactPoint->getLocalPointOnShape1();
|
||||||
|
rp3d::Vector3 normalWorld = contactPoint->getNormal();
|
||||||
|
openglframework::Vector3 normal = openglframework::Vector3(normalWorld.x, normalWorld.y, normalWorld.z);
|
||||||
|
ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z), normal, openglframework::Color::red());
|
||||||
|
contactPoints.push_back(contact);
|
||||||
|
|
||||||
|
contactPoint = contactPoint->getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return contactPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the engine settings
|
||||||
|
void SceneDemo::updateEngineSettings() {
|
||||||
|
|
||||||
|
if (getDynamicsWorld() != nullptr) {
|
||||||
|
|
||||||
|
// Update the physics engine parameters
|
||||||
|
getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
||||||
|
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
||||||
|
mEngineSettings.gravity.z);
|
||||||
|
getDynamicsWorld()->setGravity(gravity);
|
||||||
|
getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled);
|
||||||
|
getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
||||||
|
getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
||||||
|
getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
||||||
|
getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
||||||
|
getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,189 +1,195 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#ifndef SCENEDEMO_H
|
#ifndef SCENEDEMO_H
|
||||||
#define SCENEDEMO_H
|
#define SCENEDEMO_H
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "VisualContactPoint.h"
|
#include "VisualContactPoint.h"
|
||||||
#include "reactphysics3d.h"
|
#include "reactphysics3d.h"
|
||||||
#include "PhysicsObject.h"
|
#include "PhysicsObject.h"
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const int SHADOWMAP_WIDTH = 2048;
|
const int SHADOWMAP_WIDTH = 2048;
|
||||||
const int SHADOWMAP_HEIGHT = 2048;
|
const int SHADOWMAP_HEIGHT = 2048;
|
||||||
|
|
||||||
// Class SceneDemo
|
// Class SceneDemo
|
||||||
// Abstract class that represents a 3D scene for the ReactPhysics3D examples.
|
// Abstract class that represents a 3D scene for the ReactPhysics3D examples.
|
||||||
// This scene has a single light source with shadow mapping.
|
// This scene has a single light source with shadow mapping.
|
||||||
class SceneDemo : public Scene {
|
class SceneDemo : public Scene {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Constants -------------------- //
|
||||||
|
|
||||||
/// Light 0
|
static constexpr int NB_SHADOW_MAPS = 3;
|
||||||
openglframework::Light mLight0;
|
|
||||||
|
// -------------------- Attributes -------------------- //
|
||||||
/// True if the shadows FBO, textures have been created
|
|
||||||
bool mIsShadowMappingInitialized;
|
/// Light 0
|
||||||
|
openglframework::Light mLight0;
|
||||||
/// FBO for the shadow map
|
|
||||||
openglframework::FrameBufferObject mFBOShadowMap;
|
/// Light 1
|
||||||
|
openglframework::Light mLight1;
|
||||||
/// Shadow map texture
|
|
||||||
openglframework::Texture2D mShadowMapTexture;
|
/// Light 2
|
||||||
|
openglframework::Light mLight2;
|
||||||
static int shadowMapTextureLevel;
|
|
||||||
|
/// True if the shadows FBO, textures have been created
|
||||||
/// All the visual contact points
|
bool mIsShadowMappingInitialized;
|
||||||
std::vector<VisualContactPoint*> mContactPoints;
|
|
||||||
|
/// Array of FBO for the shadow maps
|
||||||
/// Shadow map bias matrix
|
openglframework::FrameBufferObject mFBOShadowMap[NB_SHADOW_MAPS];
|
||||||
openglframework::Matrix4 mShadowMapBiasMatrix;
|
|
||||||
|
/// Shadow map texture
|
||||||
/// Camera at light0 position for the shadow map
|
openglframework::Texture2D mShadowMapTexture[NB_SHADOW_MAPS];
|
||||||
openglframework::Camera mShadowMapLightCamera;
|
|
||||||
|
static int shadowMapTextureLevel;
|
||||||
/// Depth shader to render the shadow map
|
|
||||||
openglframework::Shader mDepthShader;
|
/// All the visual contact points
|
||||||
|
std::vector<VisualContactPoint*> mContactPoints;
|
||||||
/// Phong shader
|
|
||||||
openglframework::Shader mPhongShader;
|
/// Shadow map bias matrix
|
||||||
|
openglframework::Matrix4 mShadowMapBiasMatrix;
|
||||||
/// Constant color shader
|
|
||||||
openglframework::Shader mColorShader;
|
/// Cameras at lights position for the shadow maps
|
||||||
|
openglframework::Camera mShadowMapLightCameras[NB_SHADOW_MAPS];
|
||||||
// TODO : Delete this
|
|
||||||
openglframework::Shader mQuadShader;
|
/// Depth shader to render the shadow map
|
||||||
|
openglframework::Shader mDepthShader;
|
||||||
// TODO : Delete this
|
|
||||||
openglframework::VertexArrayObject mVAOQuad;
|
/// Phong shader
|
||||||
|
openglframework::Shader mPhongShader;
|
||||||
openglframework::VertexBufferObject mVBOQuad;
|
|
||||||
|
/// Constant color shader
|
||||||
static openglframework::Color mGreyColorDemo;
|
openglframework::Shader mColorShader;
|
||||||
static openglframework::Color mYellowColorDemo;
|
|
||||||
static openglframework::Color mBlueColorDemo;
|
// TODO : Delete this
|
||||||
static openglframework::Color mOrangeColorDemo;
|
openglframework::Shader mQuadShader;
|
||||||
static openglframework::Color mPinkColorDemo;
|
|
||||||
static openglframework::Color mRedColorDemo;
|
// TODO : Delete this
|
||||||
static openglframework::Color mDemoColors[];
|
openglframework::VertexArrayObject mVAOQuad;
|
||||||
static int mNbDemoColors;
|
|
||||||
|
openglframework::VertexBufferObject mVBOQuad;
|
||||||
std::string mMeshFolderPath;
|
|
||||||
|
static openglframework::Color mObjectColorDemo;
|
||||||
std::vector<PhysicsObject*> mPhysicsObjects;
|
static openglframework::Color mFloorColorDemo;
|
||||||
|
static openglframework::Color mSleepingColorDemo;
|
||||||
rp3d::CollisionWorld* mPhysicsWorld;
|
static openglframework::Color mSelectedObjectColorDemo;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
std::string mMeshFolderPath;
|
||||||
|
|
||||||
// Create the Shadow map FBO and texture
|
std::vector<PhysicsObject*> mPhysicsObjects;
|
||||||
void createShadowMapFBOAndTexture();
|
|
||||||
|
rp3d::CollisionWorld* mPhysicsWorld;
|
||||||
// Used for debugging shadow maps
|
|
||||||
void createQuadVBO();
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// TODO : Delete this
|
// Create the Shadow map FBO and texture
|
||||||
void drawTextureQuad();
|
void createShadowMapFBOAndTexture();
|
||||||
|
|
||||||
// Update the contact points
|
// Used for debugging shadow maps
|
||||||
void updateContactPoints();
|
void createQuadVBO();
|
||||||
|
|
||||||
// Render the contact points
|
// TODO : Delete this
|
||||||
void renderContactPoints(openglframework::Shader& shader,
|
void drawTextureQuad();
|
||||||
const openglframework::Matrix4& worldToCameraMatrix);
|
|
||||||
|
// Update the contact points
|
||||||
|
void updateContactPoints();
|
||||||
/// Render the AABBs
|
|
||||||
void renderAABBs(const openglframework::Matrix4& worldToCameraMatrix);
|
// Render the contact points
|
||||||
|
void renderContactPoints(openglframework::Shader& shader,
|
||||||
/// Remove all contact points
|
const openglframework::Matrix4& worldToCameraMatrix);
|
||||||
void removeAllContactPoints();
|
|
||||||
|
|
||||||
/// Return a reference to the dynamics world
|
/// Render the AABBs
|
||||||
rp3d::DynamicsWorld* getDynamicsWorld();
|
void renderAABBs(const openglframework::Matrix4& worldToCameraMatrix);
|
||||||
|
|
||||||
/// Return a reference to the dynamics world
|
/// Remove all contact points
|
||||||
const rp3d::DynamicsWorld* getDynamicsWorld() const;
|
void removeAllContactPoints();
|
||||||
|
|
||||||
public:
|
/// Return a reference to the dynamics world
|
||||||
|
rp3d::DynamicsWorld* getDynamicsWorld();
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
/// Return a reference to the dynamics world
|
||||||
/// Constructor
|
const rp3d::DynamicsWorld* getDynamicsWorld() const;
|
||||||
SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled = true);
|
|
||||||
|
public:
|
||||||
/// Destructor
|
|
||||||
virtual ~SceneDemo() override;
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Update the scene
|
/// Constructor
|
||||||
virtual void update() override;
|
SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled = true);
|
||||||
|
|
||||||
/// Update the physics world (take a simulation step)
|
/// Destructor
|
||||||
/// Can be called several times per frame
|
virtual ~SceneDemo() override;
|
||||||
virtual void updatePhysics() override;
|
|
||||||
|
/// Update the scene
|
||||||
/// Render the scene (possibly in multiple passes for shadow mapping)
|
virtual void update() override;
|
||||||
virtual void render() override;
|
|
||||||
|
/// Update the physics world (take a simulation step)
|
||||||
/// Update the engine settings
|
/// Can be called several times per frame
|
||||||
virtual void updateEngineSettings() override;
|
virtual void updatePhysics() override;
|
||||||
|
|
||||||
/// Render the scene in a single pass
|
/// Render the scene (possibly in multiple passes for shadow mapping)
|
||||||
virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
virtual void render() override;
|
||||||
|
|
||||||
/// Enabled/Disable the shadow mapping
|
/// Update the engine settings
|
||||||
virtual void setIsShadowMappingEnabled(bool isShadowMappingEnabled) override;
|
virtual void updateEngineSettings() override;
|
||||||
|
|
||||||
/// Return all the contact points of the scene
|
/// Render the scene in a single pass
|
||||||
std::vector<ContactPoint> computeContactPointsOfWorld(reactphysics3d::DynamicsWorld *world);
|
virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||||
};
|
|
||||||
|
/// Enabled/Disable the shadow mapping
|
||||||
// Enabled/Disable the shadow mapping
|
virtual void setIsShadowMappingEnabled(bool isShadowMappingEnabled) override;
|
||||||
inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
|
|
||||||
|
/// Return all the contact points of the scene
|
||||||
Scene::setIsShadowMappingEnabled(isShadowMappingEnabled);
|
std::vector<ContactPoint> computeContactPointsOfWorld(reactphysics3d::DynamicsWorld *world);
|
||||||
|
};
|
||||||
if (mIsShadowMappingEnabled && !mIsShadowMappingInitialized) {
|
|
||||||
createShadowMapFBOAndTexture();
|
// Enabled/Disable the shadow mapping
|
||||||
}
|
inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
|
||||||
}
|
|
||||||
|
Scene::setIsShadowMappingEnabled(isShadowMappingEnabled);
|
||||||
// Return a reference to the dynamics world
|
|
||||||
inline rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() {
|
if (mIsShadowMappingEnabled && !mIsShadowMappingInitialized) {
|
||||||
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
|
createShadowMapFBOAndTexture();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Return a reference to the dynamics world
|
|
||||||
inline const rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() const {
|
// Return a reference to the dynamics world
|
||||||
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
|
inline rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() {
|
||||||
}
|
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
|
||||||
|
}
|
||||||
#endif
|
|
||||||
|
// Return a reference to the dynamics world
|
||||||
|
inline const rp3d::DynamicsWorld* SceneDemo::getDynamicsWorld() const {
|
||||||
|
return dynamic_cast<rp3d::DynamicsWorld*>(mPhysicsWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,393 +1,393 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "TestbedApplication.h"
|
#include "TestbedApplication.h"
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "cubes/CubesScene.h"
|
#include "cubes/CubesScene.h"
|
||||||
#include "collisiondetection/CollisionDetectionScene.h"
|
#include "collisiondetection/CollisionDetectionScene.h"
|
||||||
#include "joints/JointsScene.h"
|
#include "joints/JointsScene.h"
|
||||||
#include "collisionshapes/CollisionShapesScene.h"
|
#include "collisionshapes/CollisionShapesScene.h"
|
||||||
#include "heightfield/HeightFieldScene.h"
|
#include "heightfield/HeightFieldScene.h"
|
||||||
#include "raycast/RaycastScene.h"
|
#include "raycast/RaycastScene.h"
|
||||||
#include "concavemesh/ConcaveMeshScene.h"
|
#include "concavemesh/ConcaveMeshScene.h"
|
||||||
#include "cubestack/CubeStackScene.h"
|
#include "cubestack/CubeStackScene.h"
|
||||||
|
|
||||||
using namespace openglframework;
|
using namespace openglframework;
|
||||||
using namespace jointsscene;
|
using namespace jointsscene;
|
||||||
using namespace cubesscene;
|
using namespace cubesscene;
|
||||||
using namespace raycastscene;
|
using namespace raycastscene;
|
||||||
using namespace collisionshapesscene;
|
using namespace collisionshapesscene;
|
||||||
using namespace trianglemeshscene;
|
using namespace trianglemeshscene;
|
||||||
using namespace heightfieldscene;
|
using namespace heightfieldscene;
|
||||||
using namespace collisiondetectionscene;
|
using namespace collisiondetectionscene;
|
||||||
using namespace cubestackscene;
|
using namespace cubestackscene;
|
||||||
|
|
||||||
// Initialization of static variables
|
// Initialization of static variables
|
||||||
const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f;
|
const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
TestbedApplication::TestbedApplication(bool isFullscreen)
|
TestbedApplication::TestbedApplication(bool isFullscreen, int windowWidth, int windowHeight)
|
||||||
: Screen(Vector2i(1280, 800), "Testbed ReactPhysics3D", true, isFullscreen, 8, 8, 24, 8, 8),
|
: Screen(Vector2i(windowWidth, windowHeight), "Testbed ReactPhysics3D", true, isFullscreen, 8, 8, 24, 8, 8),
|
||||||
mIsInitialized(false), mGui(this), mCurrentScene(nullptr),
|
mIsInitialized(false), mGui(this), mCurrentScene(nullptr),
|
||||||
mEngineSettings(EngineSettings::defaultSettings()),
|
mEngineSettings(EngineSettings::defaultSettings()),
|
||||||
mFPS(0), mNbFrames(0), mPreviousTime(0),
|
mFPS(0), mNbFrames(0), mPreviousTime(0),
|
||||||
mLastTimeComputedFPS(0), mFrameTime(0), mPhysicsTime(0),
|
mLastTimeComputedFPS(0), mFrameTime(0), mPhysicsTime(0),
|
||||||
mWidth(1280), mHeight(720),
|
mWidth(windowWidth), mHeight(windowHeight),
|
||||||
mSinglePhysicsStepEnabled(false), mSinglePhysicsStepDone(false),
|
mSinglePhysicsStepEnabled(false), mSinglePhysicsStepDone(false),
|
||||||
mWindowToFramebufferRatio(Vector2(1, 1)), mIsShadowMappingEnabled(true),
|
mWindowToFramebufferRatio(Vector2(1, 1)), mIsShadowMappingEnabled(true),
|
||||||
mIsContactPointsDisplayed(false), mIsAABBsDisplayed(false), mIsWireframeEnabled(false),
|
mIsContactPointsDisplayed(false), mIsAABBsDisplayed(false), mIsWireframeEnabled(false),
|
||||||
mIsVSyncEnabled(true) {
|
mIsVSyncEnabled(true) {
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
resizeEvent(Vector2i(0, 0));
|
resizeEvent(Vector2i(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
TestbedApplication::~TestbedApplication() {
|
TestbedApplication::~TestbedApplication() {
|
||||||
|
|
||||||
// Destroy all the scenes
|
// Destroy all the scenes
|
||||||
destroyScenes();
|
destroyScenes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the viewer
|
// Initialize the viewer
|
||||||
void TestbedApplication::init() {
|
void TestbedApplication::init() {
|
||||||
|
|
||||||
// Create all the scenes
|
// Create all the scenes
|
||||||
createScenes();
|
createScenes();
|
||||||
|
|
||||||
// Initialize the GUI
|
// Initialize the GUI
|
||||||
mGui.init();
|
mGui.init();
|
||||||
|
|
||||||
mTimer.start();
|
mTimer.start();
|
||||||
|
|
||||||
mIsInitialized = true;
|
mIsInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create all the scenes
|
// Create all the scenes
|
||||||
void TestbedApplication::createScenes() {
|
void TestbedApplication::createScenes() {
|
||||||
|
|
||||||
// Cubes scene
|
// Cubes scene
|
||||||
CubesScene* cubeScene = new CubesScene("Cubes", mEngineSettings);
|
CubesScene* cubeScene = new CubesScene("Cubes", mEngineSettings);
|
||||||
mScenes.push_back(cubeScene);
|
mScenes.push_back(cubeScene);
|
||||||
|
|
||||||
// Cube Stack scene
|
// Cube Stack scene
|
||||||
CubeStackScene* cubeStackScene = new CubeStackScene("Cube Stack", mEngineSettings);
|
CubeStackScene* cubeStackScene = new CubeStackScene("Cube Stack", mEngineSettings);
|
||||||
mScenes.push_back(cubeStackScene);
|
mScenes.push_back(cubeStackScene);
|
||||||
|
|
||||||
// Joints scene
|
// Joints scene
|
||||||
JointsScene* jointsScene = new JointsScene("Joints", mEngineSettings);
|
JointsScene* jointsScene = new JointsScene("Joints", mEngineSettings);
|
||||||
mScenes.push_back(jointsScene);
|
mScenes.push_back(jointsScene);
|
||||||
|
|
||||||
// Collision shapes scene
|
// Collision shapes scene
|
||||||
CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes", mEngineSettings);
|
CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes", mEngineSettings);
|
||||||
mScenes.push_back(collisionShapesScene);
|
mScenes.push_back(collisionShapesScene);
|
||||||
|
|
||||||
// Heightfield shape scene
|
// Heightfield shape scene
|
||||||
HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield", mEngineSettings);
|
HeightFieldScene* heightFieldScene = new HeightFieldScene("Heightfield", mEngineSettings);
|
||||||
mScenes.push_back(heightFieldScene);
|
mScenes.push_back(heightFieldScene);
|
||||||
|
|
||||||
// Raycast scene
|
// Raycast scene
|
||||||
RaycastScene* raycastScene = new RaycastScene("Raycast", mEngineSettings);
|
RaycastScene* raycastScene = new RaycastScene("Raycast", mEngineSettings);
|
||||||
mScenes.push_back(raycastScene);
|
mScenes.push_back(raycastScene);
|
||||||
|
|
||||||
// Collision Detection scene
|
// Collision Detection scene
|
||||||
CollisionDetectionScene* collisionDetectionScene = new CollisionDetectionScene("Collision Detection", mEngineSettings);
|
CollisionDetectionScene* collisionDetectionScene = new CollisionDetectionScene("Collision Detection", mEngineSettings);
|
||||||
mScenes.push_back(collisionDetectionScene);
|
mScenes.push_back(collisionDetectionScene);
|
||||||
|
|
||||||
// Concave Mesh scene
|
// Concave Mesh scene
|
||||||
ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh", mEngineSettings);
|
ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh", mEngineSettings);
|
||||||
mScenes.push_back(concaveMeshScene);
|
mScenes.push_back(concaveMeshScene);
|
||||||
|
|
||||||
assert(mScenes.size() > 0);
|
assert(mScenes.size() > 0);
|
||||||
|
|
||||||
const int firstSceneIndex = 0;
|
const int firstSceneIndex = 0;
|
||||||
|
|
||||||
switchScene(mScenes[firstSceneIndex]);
|
switchScene(mScenes[firstSceneIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all the scenes
|
// Remove all the scenes
|
||||||
void TestbedApplication::destroyScenes() {
|
void TestbedApplication::destroyScenes() {
|
||||||
|
|
||||||
for (uint i=0; i<mScenes.size(); i++) {
|
for (uint i=0; i<mScenes.size(); i++) {
|
||||||
delete mScenes[i];
|
delete mScenes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentScene = NULL;
|
mCurrentScene = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestbedApplication::updateSinglePhysicsStep() {
|
void TestbedApplication::updateSinglePhysicsStep() {
|
||||||
|
|
||||||
assert(!mTimer.isRunning());
|
assert(!mTimer.isRunning());
|
||||||
|
|
||||||
mCurrentScene->updatePhysics();
|
mCurrentScene->updatePhysics();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the physics of the current scene
|
// Update the physics of the current scene
|
||||||
void TestbedApplication::updatePhysics() {
|
void TestbedApplication::updatePhysics() {
|
||||||
|
|
||||||
// Update the elapsed time
|
// Update the elapsed time
|
||||||
mEngineSettings.elapsedTime = mTimer.getPhysicsTime();
|
mEngineSettings.elapsedTime = mTimer.getPhysicsTime();
|
||||||
|
|
||||||
if (mTimer.isRunning()) {
|
if (mTimer.isRunning()) {
|
||||||
|
|
||||||
// Compute the time since the last update() call and update the timer
|
// Compute the time since the last update() call and update the timer
|
||||||
mTimer.update();
|
mTimer.update();
|
||||||
|
|
||||||
// While the time accumulator is not empty
|
// While the time accumulator is not empty
|
||||||
while(mTimer.isPossibleToTakeStep(mEngineSettings.timeStep)) {
|
while(mTimer.isPossibleToTakeStep(mEngineSettings.timeStep)) {
|
||||||
|
|
||||||
// Take a physics simulation step
|
// Take a physics simulation step
|
||||||
mCurrentScene->updatePhysics();
|
mCurrentScene->updatePhysics();
|
||||||
|
|
||||||
// Update the timer
|
// Update the timer
|
||||||
mTimer.nextStep(mEngineSettings.timeStep);
|
mTimer.nextStep(mEngineSettings.timeStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestbedApplication::update() {
|
void TestbedApplication::update() {
|
||||||
|
|
||||||
double currentTime = glfwGetTime();
|
double currentTime = glfwGetTime();
|
||||||
|
|
||||||
// Update the physics
|
// Update the physics
|
||||||
if (mSinglePhysicsStepEnabled && !mSinglePhysicsStepDone) {
|
if (mSinglePhysicsStepEnabled && !mSinglePhysicsStepDone) {
|
||||||
updateSinglePhysicsStep();
|
updateSinglePhysicsStep();
|
||||||
mSinglePhysicsStepDone = true;
|
mSinglePhysicsStepDone = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
updatePhysics();
|
updatePhysics();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the physics update time
|
// Compute the physics update time
|
||||||
mPhysicsTime = glfwGetTime() - currentTime;
|
mPhysicsTime = glfwGetTime() - currentTime;
|
||||||
|
|
||||||
// Compute the interpolation factor
|
// Compute the interpolation factor
|
||||||
float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep);
|
float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep);
|
||||||
assert(factor >= 0.0f && factor <= 1.0f);
|
assert(factor >= 0.0f && factor <= 1.0f);
|
||||||
|
|
||||||
// Notify the scene about the interpolation factor
|
// Notify the scene about the interpolation factor
|
||||||
mCurrentScene->setInterpolationFactor(factor);
|
mCurrentScene->setInterpolationFactor(factor);
|
||||||
|
|
||||||
// Enable/Disable shadow mapping
|
// Enable/Disable shadow mapping
|
||||||
mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled);
|
mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled);
|
||||||
|
|
||||||
// Display/Hide contact points
|
// Display/Hide contact points
|
||||||
mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed);
|
mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed);
|
||||||
|
|
||||||
// Display/Hide the AABBs
|
// Display/Hide the AABBs
|
||||||
mCurrentScene->setIsAABBsDisplayed(mIsAABBsDisplayed);
|
mCurrentScene->setIsAABBsDisplayed(mIsAABBsDisplayed);
|
||||||
|
|
||||||
// Enable/Disable wireframe mode
|
// Enable/Disable wireframe mode
|
||||||
mCurrentScene->setIsWireframeEnabled(mIsWireframeEnabled);
|
mCurrentScene->setIsWireframeEnabled(mIsWireframeEnabled);
|
||||||
|
|
||||||
// Update the scene
|
// Update the scene
|
||||||
mCurrentScene->update();
|
mCurrentScene->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestbedApplication::drawContents() {
|
void TestbedApplication::drawContents() {
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
int bufferWidth, bufferHeight;
|
int bufferWidth, bufferHeight;
|
||||||
glfwMakeContextCurrent(mGLFWWindow);
|
glfwMakeContextCurrent(mGLFWWindow);
|
||||||
glfwGetFramebufferSize(mGLFWWindow, &bufferWidth, &bufferHeight);
|
glfwGetFramebufferSize(mGLFWWindow, &bufferWidth, &bufferHeight);
|
||||||
|
|
||||||
// Set the viewport of the scene
|
// Set the viewport of the scene
|
||||||
mCurrentScene->setViewport(0, 0, bufferWidth, bufferHeight);
|
mCurrentScene->setViewport(0, 0, bufferWidth, bufferHeight);
|
||||||
|
|
||||||
// Render the scene
|
// Render the scene
|
||||||
mCurrentScene->render();
|
mCurrentScene->render();
|
||||||
|
|
||||||
// Check the OpenGL errors
|
// Check the OpenGL errors
|
||||||
checkOpenGLErrors();
|
checkOpenGLErrors();
|
||||||
|
|
||||||
mGui.update();
|
mGui.update();
|
||||||
|
|
||||||
// Compute the current framerate
|
// Compute the current framerate
|
||||||
computeFPS();
|
computeFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Window resize event handler
|
/// Window resize event handler
|
||||||
bool TestbedApplication::resizeEvent(const Vector2i& size) {
|
bool TestbedApplication::resizeEvent(const Vector2i& size) {
|
||||||
|
|
||||||
if (!mIsInitialized) return false;
|
if (!mIsInitialized) return false;
|
||||||
|
|
||||||
// Get the framebuffer dimension
|
// Get the framebuffer dimension
|
||||||
int width, height;
|
int width, height;
|
||||||
glfwGetFramebufferSize(mGLFWWindow, &width, &height);
|
glfwGetFramebufferSize(mGLFWWindow, &width, &height);
|
||||||
|
|
||||||
// Resize the camera viewport
|
// Resize the camera viewport
|
||||||
mCurrentScene->reshape(width, height);
|
mCurrentScene->reshape(width, height);
|
||||||
|
|
||||||
// Update the window size of the scene
|
// Update the window size of the scene
|
||||||
int windowWidth, windowHeight;
|
int windowWidth, windowHeight;
|
||||||
glfwGetWindowSize(mGLFWWindow, &windowWidth, &windowHeight);
|
glfwGetWindowSize(mGLFWWindow, &windowWidth, &windowHeight);
|
||||||
mCurrentScene->setWindowDimension(windowWidth, windowHeight);
|
mCurrentScene->setWindowDimension(windowWidth, windowHeight);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the current scene
|
// Change the current scene
|
||||||
void TestbedApplication::switchScene(Scene* newScene) {
|
void TestbedApplication::switchScene(Scene* newScene) {
|
||||||
|
|
||||||
if (newScene == mCurrentScene) return;
|
if (newScene == mCurrentScene) return;
|
||||||
|
|
||||||
mCurrentScene = newScene;
|
mCurrentScene = newScene;
|
||||||
|
|
||||||
// Reset the scene
|
// Reset the scene
|
||||||
mCurrentScene->reset();
|
mCurrentScene->reset();
|
||||||
|
|
||||||
mCurrentScene->updateEngineSettings();
|
mCurrentScene->updateEngineSettings();
|
||||||
|
|
||||||
resizeEvent(Vector2i(0, 0));
|
resizeEvent(Vector2i(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify that the engine settings have changed
|
// Notify that the engine settings have changed
|
||||||
void TestbedApplication::notifyEngineSetttingsChanged() {
|
void TestbedApplication::notifyEngineSetttingsChanged() {
|
||||||
mCurrentScene->updateEngineSettings();
|
mCurrentScene->updateEngineSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the OpenGL errors
|
// Check the OpenGL errors
|
||||||
void TestbedApplication::checkOpenGLErrorsInternal(const char* file, int line) {
|
void TestbedApplication::checkOpenGLErrorsInternal(const char* file, int line) {
|
||||||
GLenum glError;
|
GLenum glError;
|
||||||
|
|
||||||
// Get the OpenGL errors
|
// Get the OpenGL errors
|
||||||
glError = glGetError();
|
glError = glGetError();
|
||||||
|
|
||||||
// While there are errors
|
// While there are errors
|
||||||
while (glError != GL_NO_ERROR) {
|
while (glError != GL_NO_ERROR) {
|
||||||
|
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|
||||||
switch(glError) {
|
switch(glError) {
|
||||||
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
|
case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
|
||||||
case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
|
case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
|
||||||
case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
|
case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
|
||||||
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
|
case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
|
||||||
case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break;
|
case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "OpenGL Error #" << error.c_str() << " - " << file << ": " << line << std::endl;
|
std::cerr << "OpenGL Error #" << error.c_str() << " - " << file << ": " << line << std::endl;
|
||||||
|
|
||||||
// Get the next error
|
// Get the next error
|
||||||
glError = glGetError();
|
glError = glGetError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Compute the FPS
|
// Compute the FPS
|
||||||
void TestbedApplication::computeFPS() {
|
void TestbedApplication::computeFPS() {
|
||||||
|
|
||||||
// Note : By default the nanogui library is using glfwWaitEvents() to process
|
// Note : By default the nanogui library is using glfwWaitEvents() to process
|
||||||
// events and sleep to target a framerate of 50 ms (using a thread
|
// events and sleep to target a framerate of 50 ms (using a thread
|
||||||
// sleeping). However, for games we prefer to use glfwPollEvents()
|
// sleeping). However, for games we prefer to use glfwPollEvents()
|
||||||
// instead and remove the update. Therefore the file common.cpp of the
|
// instead and remove the update. Therefore the file common.cpp of the
|
||||||
// nanogui library has been modified to have a faster framerate
|
// nanogui library has been modified to have a faster framerate
|
||||||
|
|
||||||
mNbFrames++;
|
mNbFrames++;
|
||||||
|
|
||||||
// Get the number of seconds since start
|
// Get the number of seconds since start
|
||||||
mCurrentTime = glfwGetTime();
|
mCurrentTime = glfwGetTime();
|
||||||
|
|
||||||
// Calculate time passed
|
// Calculate time passed
|
||||||
mFrameTime = mCurrentTime - mPreviousTime;
|
mFrameTime = mCurrentTime - mPreviousTime;
|
||||||
double timeInterval = (mCurrentTime - mLastTimeComputedFPS) * 1000.0;
|
double timeInterval = (mCurrentTime - mLastTimeComputedFPS) * 1000.0;
|
||||||
|
|
||||||
// Update the FPS counter each second
|
// Update the FPS counter each second
|
||||||
if(timeInterval > 1000) {
|
if(timeInterval > 1000) {
|
||||||
|
|
||||||
// calculate the number of frames per second
|
// calculate the number of frames per second
|
||||||
mFPS = static_cast<double>(mNbFrames) / timeInterval;
|
mFPS = static_cast<double>(mNbFrames) / timeInterval;
|
||||||
mFPS *= 1000.0;
|
mFPS *= 1000.0;
|
||||||
|
|
||||||
// Reset frame count
|
// Reset frame count
|
||||||
mNbFrames = 0;
|
mNbFrames = 0;
|
||||||
|
|
||||||
mLastTimeComputedFPS = mCurrentTime;
|
mLastTimeComputedFPS = mCurrentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set time
|
// Set time
|
||||||
mPreviousTime = mCurrentTime;
|
mPreviousTime = mCurrentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestbedApplication::keyboardEvent(int key, int scancode, int action, int modifiers) {
|
bool TestbedApplication::keyboardEvent(int key, int scancode, int action, int modifiers) {
|
||||||
|
|
||||||
if (Screen::keyboardEvent(key, scancode, action, modifiers)) {
|
if (Screen::keyboardEvent(key, scancode, action, modifiers)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close application on escape key
|
// Close application on escape key
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||||
glfwSetWindowShouldClose(mGLFWWindow, GL_TRUE);
|
glfwSetWindowShouldClose(mGLFWWindow, GL_TRUE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mCurrentScene->keyboardEvent(key, scancode, action, modifiers);
|
return mCurrentScene->keyboardEvent(key, scancode, action, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a mouse button event (default implementation: propagate to children)
|
// Handle a mouse button event (default implementation: propagate to children)
|
||||||
bool TestbedApplication::mouseButtonEvent(const Vector2i &p, int button, bool down, int modifiers) {
|
bool TestbedApplication::mouseButtonEvent(const Vector2i &p, int button, bool down, int modifiers) {
|
||||||
|
|
||||||
if (Screen::mouseButtonEvent(p, button, down, modifiers)) {
|
if (Screen::mouseButtonEvent(p, button, down, modifiers)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the mouse cursor position
|
// Get the mouse cursor position
|
||||||
double x, y;
|
double x, y;
|
||||||
glfwGetCursorPos(mGLFWWindow, &x, &y);
|
glfwGetCursorPos(mGLFWWindow, &x, &y);
|
||||||
|
|
||||||
return mCurrentScene->mouseButtonEvent(button, down, modifiers, x, y);
|
return mCurrentScene->mouseButtonEvent(button, down, modifiers, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a mouse motion event (default implementation: propagate to children)
|
// Handle a mouse motion event (default implementation: propagate to children)
|
||||||
bool TestbedApplication::mouseMotionEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers) {
|
bool TestbedApplication::mouseMotionEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers) {
|
||||||
|
|
||||||
if (Screen::mouseMotionEvent(p, rel, button, modifiers)) {
|
if (Screen::mouseMotionEvent(p, rel, button, modifiers)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int leftButtonState = glfwGetMouseButton(mGLFWWindow, GLFW_MOUSE_BUTTON_LEFT);
|
int leftButtonState = glfwGetMouseButton(mGLFWWindow, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
int rightButtonState = glfwGetMouseButton(mGLFWWindow, GLFW_MOUSE_BUTTON_RIGHT);
|
int rightButtonState = glfwGetMouseButton(mGLFWWindow, GLFW_MOUSE_BUTTON_RIGHT);
|
||||||
int middleButtonState = glfwGetMouseButton(mGLFWWindow, GLFW_MOUSE_BUTTON_MIDDLE);
|
int middleButtonState = glfwGetMouseButton(mGLFWWindow, GLFW_MOUSE_BUTTON_MIDDLE);
|
||||||
int altKeyState = glfwGetKey(mGLFWWindow, GLFW_KEY_LEFT_ALT);
|
int altKeyState = glfwGetKey(mGLFWWindow, GLFW_KEY_LEFT_ALT);
|
||||||
|
|
||||||
return mCurrentScene->mouseMotionEvent(p[0], p[1], leftButtonState, rightButtonState,
|
return mCurrentScene->mouseMotionEvent(p[0], p[1], leftButtonState, rightButtonState,
|
||||||
middleButtonState, altKeyState);
|
middleButtonState, altKeyState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a mouse scroll event (default implementation: propagate to children)
|
// Handle a mouse scroll event (default implementation: propagate to children)
|
||||||
bool TestbedApplication::scrollEvent(const Vector2i &p, const Vector2f &rel) {
|
bool TestbedApplication::scrollEvent(const Vector2i &p, const Vector2f &rel) {
|
||||||
|
|
||||||
if (Screen::scrollEvent(p, rel)) {
|
if (Screen::scrollEvent(p, rel)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mCurrentScene->scrollingEvent(rel[0], rel[1], SCROLL_SENSITIVITY);
|
return mCurrentScene->scrollingEvent(rel[0], rel[1], SCROLL_SENSITIVITY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,260 +1,260 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
*********************************************************************************
|
*********************************************************************************
|
||||||
* *
|
* *
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
* 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 *
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
* use of this software. *
|
* use of this software. *
|
||||||
* *
|
* *
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
* freely, subject to the following restrictions: *
|
* freely, subject to the following restrictions: *
|
||||||
* *
|
* *
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
* 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 *
|
* that you wrote the original software. If you use this software in a *
|
||||||
* product, an acknowledgment in the product documentation would be *
|
* product, an acknowledgment in the product documentation would be *
|
||||||
* appreciated but is not required. *
|
* appreciated but is not required. *
|
||||||
* *
|
* *
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
* misrepresented as being the original software. *
|
* misrepresented as being the original software. *
|
||||||
* *
|
* *
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#ifndef TESTBED_APPLICATION_H
|
#ifndef TESTBED_APPLICATION_H
|
||||||
#define TESTBED_APPLICATION_H
|
#define TESTBED_APPLICATION_H
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "openglframework.h"
|
#include "openglframework.h"
|
||||||
#include "Gui.h"
|
#include "Gui.h"
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
using namespace nanogui;
|
using namespace nanogui;
|
||||||
|
|
||||||
// Macro for OpenGL errors
|
// Macro for OpenGL errors
|
||||||
#define checkOpenGLErrors() checkOpenGLErrorsInternal(__FILE__,__LINE__)
|
#define checkOpenGLErrors() checkOpenGLErrorsInternal(__FILE__,__LINE__)
|
||||||
|
|
||||||
/// Class TestbedApplication
|
/// Class TestbedApplication
|
||||||
class TestbedApplication : public Screen {
|
class TestbedApplication : public Screen {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Constants -------------------- //
|
// -------------------- Constants -------------------- //
|
||||||
|
|
||||||
static const float SCROLL_SENSITIVITY;
|
static const float SCROLL_SENSITIVITY;
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
bool mIsInitialized;
|
bool mIsInitialized;
|
||||||
|
|
||||||
Gui mGui;
|
Gui mGui;
|
||||||
|
|
||||||
/// Timer
|
/// Timer
|
||||||
Timer mTimer;
|
Timer mTimer;
|
||||||
|
|
||||||
/// List of 3D scenes
|
/// List of 3D scenes
|
||||||
std::vector<Scene*> mScenes;
|
std::vector<Scene*> mScenes;
|
||||||
|
|
||||||
/// Current 3D scene
|
/// Current 3D scene
|
||||||
Scene* mCurrentScene;
|
Scene* mCurrentScene;
|
||||||
|
|
||||||
/// Physics engine settings
|
/// Physics engine settings
|
||||||
EngineSettings mEngineSettings;
|
EngineSettings mEngineSettings;
|
||||||
|
|
||||||
/// Current number of frames per seconds
|
/// Current number of frames per seconds
|
||||||
double mFPS;
|
double mFPS;
|
||||||
|
|
||||||
/// Number of frames during the last second
|
/// Number of frames during the last second
|
||||||
int mNbFrames;
|
int mNbFrames;
|
||||||
|
|
||||||
/// Current time for fps computation (in seconds)
|
/// Current time for fps computation (in seconds)
|
||||||
double mCurrentTime;
|
double mCurrentTime;
|
||||||
|
|
||||||
/// Previous time for fps computation (in seconds)
|
/// Previous time for fps computation (in seconds)
|
||||||
double mPreviousTime;
|
double mPreviousTime;
|
||||||
|
|
||||||
/// Last time the FPS have been computed
|
/// Last time the FPS have been computed
|
||||||
double mLastTimeComputedFPS;
|
double mLastTimeComputedFPS;
|
||||||
|
|
||||||
/// Update time (in seconds)
|
/// Update time (in seconds)
|
||||||
double mFrameTime;
|
double mFrameTime;
|
||||||
|
|
||||||
/// Physics update time (in seconds)
|
/// Physics update time (in seconds)
|
||||||
double mPhysicsTime;
|
double mPhysicsTime;
|
||||||
|
|
||||||
/// Width and height of the window
|
/// Width and height of the window
|
||||||
int mWidth, mHeight;
|
int mWidth, mHeight;
|
||||||
|
|
||||||
/// True if the next simulation update is a single physics step
|
/// True if the next simulation update is a single physics step
|
||||||
bool mSinglePhysicsStepEnabled;
|
bool mSinglePhysicsStepEnabled;
|
||||||
|
|
||||||
/// True if the single physics step has been taken already
|
/// True if the single physics step has been taken already
|
||||||
bool mSinglePhysicsStepDone;
|
bool mSinglePhysicsStepDone;
|
||||||
|
|
||||||
openglframework::Vector2 mWindowToFramebufferRatio;
|
openglframework::Vector2 mWindowToFramebufferRatio;
|
||||||
|
|
||||||
/// True if shadow mapping is enabled
|
/// True if shadow mapping is enabled
|
||||||
bool mIsShadowMappingEnabled;
|
bool mIsShadowMappingEnabled;
|
||||||
|
|
||||||
/// True if contact points are displayed
|
/// True if contact points are displayed
|
||||||
bool mIsContactPointsDisplayed;
|
bool mIsContactPointsDisplayed;
|
||||||
|
|
||||||
/// True if the AABBs of physics objects are displayed
|
/// True if the AABBs of physics objects are displayed
|
||||||
bool mIsAABBsDisplayed;
|
bool mIsAABBsDisplayed;
|
||||||
|
|
||||||
/// True if the wireframe rendering is enabled
|
/// True if the wireframe rendering is enabled
|
||||||
bool mIsWireframeEnabled;
|
bool mIsWireframeEnabled;
|
||||||
|
|
||||||
/// True if vsync is enabled
|
/// True if vsync is enabled
|
||||||
bool mIsVSyncEnabled;
|
bool mIsVSyncEnabled;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Private copy-constructor (for the singleton class)
|
/// Private copy-constructor (for the singleton class)
|
||||||
TestbedApplication(TestbedApplication const&);
|
TestbedApplication(TestbedApplication const&);
|
||||||
|
|
||||||
/// Private assignment operator (for the singleton class)
|
/// Private assignment operator (for the singleton class)
|
||||||
void operator=(TestbedApplication const&);
|
void operator=(TestbedApplication const&);
|
||||||
|
|
||||||
/// Update the physics of the current scene
|
/// Update the physics of the current scene
|
||||||
void updatePhysics();
|
void updatePhysics();
|
||||||
|
|
||||||
/// Update
|
/// Update
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
/// Update the simulation by taking a single physics step
|
/// Update the simulation by taking a single physics step
|
||||||
void updateSinglePhysicsStep();
|
void updateSinglePhysicsStep();
|
||||||
|
|
||||||
/// Check the OpenGL errors
|
/// Check the OpenGL errors
|
||||||
static void checkOpenGLErrorsInternal(const char* file, int line);
|
static void checkOpenGLErrorsInternal(const char* file, int line);
|
||||||
|
|
||||||
/// Compute the FPS
|
/// Compute the FPS
|
||||||
void computeFPS();
|
void computeFPS();
|
||||||
|
|
||||||
/// Initialize all the scenes
|
/// Initialize all the scenes
|
||||||
void createScenes();
|
void createScenes();
|
||||||
|
|
||||||
/// Remove all the scenes
|
/// Remove all the scenes
|
||||||
void destroyScenes();
|
void destroyScenes();
|
||||||
|
|
||||||
/// Return the list of the scenes
|
/// Return the list of the scenes
|
||||||
std::vector<Scene*> getScenes();
|
std::vector<Scene*> getScenes();
|
||||||
|
|
||||||
/// Start/stop the simulation
|
/// Start/stop the simulation
|
||||||
void togglePlayPauseSimulation();
|
void togglePlayPauseSimulation();
|
||||||
|
|
||||||
/// Play the simulation
|
/// Play the simulation
|
||||||
void playSimulation();
|
void playSimulation();
|
||||||
|
|
||||||
/// Pause the simulation
|
/// Pause the simulation
|
||||||
void pauseSimulation();
|
void pauseSimulation();
|
||||||
|
|
||||||
/// Restart the simulation
|
/// Restart the simulation
|
||||||
void restartSimulation();
|
void restartSimulation();
|
||||||
|
|
||||||
/// Set the variable to know if we need to take a single physics step
|
/// Set the variable to know if we need to take a single physics step
|
||||||
void toggleTakeSinglePhysicsStep();
|
void toggleTakeSinglePhysicsStep();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Private constructor (for the singleton class)
|
/// Private constructor (for the singleton class)
|
||||||
TestbedApplication(bool isFullscreen);
|
TestbedApplication(bool isFullscreen, int windowWidth, int windowHeight);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~TestbedApplication() override;
|
virtual ~TestbedApplication() override;
|
||||||
|
|
||||||
/// Render the content of the application
|
/// Render the content of the application
|
||||||
virtual void drawContents() override;
|
virtual void drawContents() override;
|
||||||
|
|
||||||
/// Window resize event handler
|
/// Window resize event handler
|
||||||
virtual bool resizeEvent(const Vector2i& size) override;
|
virtual bool resizeEvent(const Vector2i& size) override;
|
||||||
|
|
||||||
/// Default keyboard event handler
|
/// Default keyboard event handler
|
||||||
virtual bool keyboardEvent(int key, int scancode, int action, int modifiers) override;
|
virtual bool keyboardEvent(int key, int scancode, int action, int modifiers) override;
|
||||||
|
|
||||||
/// Handle a mouse button event (default implementation: propagate to children)
|
/// Handle a mouse button event (default implementation: propagate to children)
|
||||||
virtual bool mouseButtonEvent(const Vector2i &p, int button, bool down, int modifiers) override;
|
virtual bool mouseButtonEvent(const Vector2i &p, int button, bool down, int modifiers) override;
|
||||||
|
|
||||||
/// Handle a mouse motion event (default implementation: propagate to children)
|
/// Handle a mouse motion event (default implementation: propagate to children)
|
||||||
virtual bool mouseMotionEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers) override;
|
virtual bool mouseMotionEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers) override;
|
||||||
|
|
||||||
/// Handle a mouse scroll event (default implementation: propagate to children)
|
/// Handle a mouse scroll event (default implementation: propagate to children)
|
||||||
virtual bool scrollEvent(const Vector2i &p, const Vector2f &rel) override;
|
virtual bool scrollEvent(const Vector2i &p, const Vector2f &rel) override;
|
||||||
|
|
||||||
/// Initialize the application
|
/// Initialize the application
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
/// Change the current scene
|
/// Change the current scene
|
||||||
void switchScene(Scene* newScene);
|
void switchScene(Scene* newScene);
|
||||||
|
|
||||||
/// Enable/Disable Vertical synchronization
|
/// Enable/Disable Vertical synchronization
|
||||||
void enableVSync(bool enable);
|
void enableVSync(bool enable);
|
||||||
|
|
||||||
/// Notify that the engine settings have changed
|
/// Notify that the engine settings have changed
|
||||||
void notifyEngineSetttingsChanged();
|
void notifyEngineSetttingsChanged();
|
||||||
|
|
||||||
// -------------------- Friendship -------------------- //
|
// -------------------- Friendship -------------------- //
|
||||||
|
|
||||||
friend class Gui;
|
friend class Gui;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return the list of the scenes
|
// Return the list of the scenes
|
||||||
inline std::vector<Scene*> TestbedApplication::getScenes() {
|
inline std::vector<Scene*> TestbedApplication::getScenes() {
|
||||||
return mScenes;
|
return mScenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle play/pause for the simulation
|
// Toggle play/pause for the simulation
|
||||||
inline void TestbedApplication::togglePlayPauseSimulation() {
|
inline void TestbedApplication::togglePlayPauseSimulation() {
|
||||||
|
|
||||||
if (mTimer.isRunning()) {
|
if (mTimer.isRunning()) {
|
||||||
mTimer.stop();
|
mTimer.stop();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mTimer.start();
|
mTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play the simulation
|
// Play the simulation
|
||||||
inline void TestbedApplication::playSimulation() {
|
inline void TestbedApplication::playSimulation() {
|
||||||
if (!mTimer.isRunning()) mTimer.start();
|
if (!mTimer.isRunning()) mTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause the simulation
|
// Pause the simulation
|
||||||
inline void TestbedApplication::pauseSimulation() {
|
inline void TestbedApplication::pauseSimulation() {
|
||||||
if (mTimer.isRunning()) mTimer.stop();
|
if (mTimer.isRunning()) mTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restart the simulation
|
// Restart the simulation
|
||||||
inline void TestbedApplication::restartSimulation() {
|
inline void TestbedApplication::restartSimulation() {
|
||||||
mCurrentScene->reset();
|
mCurrentScene->reset();
|
||||||
mTimer.start();
|
mTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take a single step of simulation
|
// Take a single step of simulation
|
||||||
inline void TestbedApplication::toggleTakeSinglePhysicsStep() {
|
inline void TestbedApplication::toggleTakeSinglePhysicsStep() {
|
||||||
mSinglePhysicsStepEnabled = true;
|
mSinglePhysicsStepEnabled = true;
|
||||||
mSinglePhysicsStepDone = false;
|
mSinglePhysicsStepDone = false;
|
||||||
|
|
||||||
if (mTimer.isRunning()) {
|
if (mTimer.isRunning()) {
|
||||||
mSinglePhysicsStepEnabled = false;
|
mSinglePhysicsStepEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable/Disable Vertical synchronization
|
// Enable/Disable Vertical synchronization
|
||||||
inline void TestbedApplication::enableVSync(bool enable) {
|
inline void TestbedApplication::enableVSync(bool enable) {
|
||||||
mIsVSyncEnabled = enable;
|
mIsVSyncEnabled = enable;
|
||||||
if (mIsVSyncEnabled) {
|
if (mIsVSyncEnabled) {
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user