Merge branch 'develop'
148
CMakeLists.txt
|
@ -4,36 +4,148 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
|||
# Project configuration
|
||||
PROJECT(REACTPHYSICS3D)
|
||||
|
||||
# Default build type
|
||||
SET(CMAKE_BUILD_TYPE "Debug")
|
||||
|
||||
# Where to build the library
|
||||
SET(LIBRARY_OUTPUT_PATH lib/)
|
||||
SET(LIBRARY_OUTPUT_PATH "lib")
|
||||
|
||||
# Where to build the executables
|
||||
SET(OUR_EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin")
|
||||
|
||||
# Options
|
||||
OPTION(COMPILE_EXAMPLES "Select this if you want to build the examples" OFF)
|
||||
OPTION(COMPILE_TESTS "Select this if you want to build the tests" OFF)
|
||||
|
||||
OPTION(PROFILING_ENABLED "Select this if you want to compile with enabled profiling" OFF)
|
||||
OPTION(DOUBLE_PRECISION_ENABLED "Select this if you want to compile using double precision floating
|
||||
values" OFF)
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES(src)
|
||||
|
||||
# Library configuration
|
||||
file (
|
||||
GLOB_RECURSE
|
||||
source_files
|
||||
src/*
|
||||
IF(PROFILING_ENABLED)
|
||||
ADD_DEFINITIONS(-DIS_PROFILING_ACTIVE)
|
||||
ENDIF(PROFILING_ENABLED)
|
||||
|
||||
IF(DOUBLE_PRECISION_ENABLED)
|
||||
ADD_DEFINITIONS(-DIS_DOUBLE_PRECISION_ENABLED)
|
||||
ENDIF(DOUBLE_PRECISION_ENABLED)
|
||||
|
||||
# Source files
|
||||
SET (REACTPHYSICS3D_SOURCES
|
||||
"src/configuration.h"
|
||||
"src/decimal.h"
|
||||
"src/reactphysics3d.h"
|
||||
"src/body/Body.h"
|
||||
"src/body/Body.cpp"
|
||||
"src/body/CollisionBody.h"
|
||||
"src/body/CollisionBody.cpp"
|
||||
"src/body/RigidBody.h"
|
||||
"src/body/RigidBody.cpp"
|
||||
"src/collision/broadphase/BroadPhaseAlgorithm.h"
|
||||
"src/collision/broadphase/BroadPhaseAlgorithm.cpp"
|
||||
"src/collision/broadphase/NoBroadPhaseAlgorithm.h"
|
||||
"src/collision/broadphase/NoBroadPhaseAlgorithm.cpp"
|
||||
"src/collision/broadphase/PairManager.h"
|
||||
"src/collision/broadphase/PairManager.cpp"
|
||||
"src/collision/broadphase/SweepAndPruneAlgorithm.h"
|
||||
"src/collision/broadphase/SweepAndPruneAlgorithm.cpp"
|
||||
"src/collision/narrowphase/EPA/EdgeEPA.h"
|
||||
"src/collision/narrowphase/EPA/EdgeEPA.cpp"
|
||||
"src/collision/narrowphase/EPA/EPAAlgorithm.h"
|
||||
"src/collision/narrowphase/EPA/EPAAlgorithm.cpp"
|
||||
"src/collision/narrowphase/EPA/TriangleEPA.h"
|
||||
"src/collision/narrowphase/EPA/TriangleEPA.cpp"
|
||||
"src/collision/narrowphase/EPA/TrianglesStore.h"
|
||||
"src/collision/narrowphase/EPA/TrianglesStore.cpp"
|
||||
"src/collision/narrowphase/GJK/Simplex.h"
|
||||
"src/collision/narrowphase/GJK/Simplex.cpp"
|
||||
"src/collision/narrowphase/GJK/GJKAlgorithm.h"
|
||||
"src/collision/narrowphase/GJK/GJKAlgorithm.cpp"
|
||||
"src/collision/narrowphase/NarrowPhaseAlgorithm.h"
|
||||
"src/collision/narrowphase/NarrowPhaseAlgorithm.cpp"
|
||||
"src/collision/narrowphase/SphereVsSphereAlgorithm.h"
|
||||
"src/collision/narrowphase/SphereVsSphereAlgorithm.cpp"
|
||||
"src/collision/shapes/AABB.h"
|
||||
"src/collision/shapes/AABB.cpp"
|
||||
"src/collision/shapes/BoxShape.h"
|
||||
"src/collision/shapes/BoxShape.cpp"
|
||||
"src/collision/shapes/CapsuleShape.h"
|
||||
"src/collision/shapes/CapsuleShape.cpp"
|
||||
"src/collision/shapes/CollisionShape.h"
|
||||
"src/collision/shapes/CollisionShape.cpp"
|
||||
"src/collision/shapes/ConeShape.h"
|
||||
"src/collision/shapes/ConeShape.cpp"
|
||||
"src/collision/shapes/ConvexMeshShape.h"
|
||||
"src/collision/shapes/ConvexMeshShape.cpp"
|
||||
"src/collision/shapes/CylinderShape.h"
|
||||
"src/collision/shapes/CylinderShape.cpp"
|
||||
"src/collision/shapes/SphereShape.h"
|
||||
"src/collision/shapes/SphereShape.cpp"
|
||||
"src/collision/BroadPhasePair.h"
|
||||
"src/collision/BroadPhasePair.cpp"
|
||||
"src/collision/CollisionDetection.h"
|
||||
"src/collision/CollisionDetection.cpp"
|
||||
"src/constraint/BallAndSocketJoint.h"
|
||||
"src/constraint/BallAndSocketJoint.cpp"
|
||||
"src/constraint/ContactPoint.h"
|
||||
"src/constraint/ContactPoint.cpp"
|
||||
"src/constraint/FixedJoint.h"
|
||||
"src/constraint/FixedJoint.cpp"
|
||||
"src/constraint/HingeJoint.h"
|
||||
"src/constraint/HingeJoint.cpp"
|
||||
"src/constraint/Joint.h"
|
||||
"src/constraint/Joint.cpp"
|
||||
"src/constraint/SliderJoint.h"
|
||||
"src/constraint/SliderJoint.cpp"
|
||||
"src/engine/CollisionWorld.h"
|
||||
"src/engine/CollisionWorld.cpp"
|
||||
"src/engine/ConstraintSolver.h"
|
||||
"src/engine/ConstraintSolver.cpp"
|
||||
"src/engine/ContactManifold.h"
|
||||
"src/engine/ContactManifold.cpp"
|
||||
"src/engine/ContactSolver.h"
|
||||
"src/engine/ContactSolver.cpp"
|
||||
"src/engine/DynamicsWorld.h"
|
||||
"src/engine/DynamicsWorld.cpp"
|
||||
"src/engine/EventListener.h"
|
||||
"src/engine/Impulse.h"
|
||||
"src/engine/Island.h"
|
||||
"src/engine/Island.cpp"
|
||||
"src/engine/Material.h"
|
||||
"src/engine/Material.cpp"
|
||||
"src/engine/OverlappingPair.h"
|
||||
"src/engine/OverlappingPair.cpp"
|
||||
"src/engine/Profiler.h"
|
||||
"src/engine/Profiler.cpp"
|
||||
"src/engine/Timer.h"
|
||||
"src/engine/Timer.cpp"
|
||||
"src/mathematics/mathematics.h"
|
||||
"src/mathematics/mathematics_functions.h"
|
||||
"src/mathematics/Matrix2x2.h"
|
||||
"src/mathematics/Matrix2x2.cpp"
|
||||
"src/mathematics/Matrix3x3.h"
|
||||
"src/mathematics/Matrix3x3.cpp"
|
||||
"src/mathematics/Quaternion.h"
|
||||
"src/mathematics/Quaternion.cpp"
|
||||
"src/mathematics/Transform.h"
|
||||
"src/mathematics/Transform.cpp"
|
||||
"src/mathematics/Vector2.h"
|
||||
"src/mathematics/Vector2.cpp"
|
||||
"src/mathematics/Vector3.h"
|
||||
"src/mathematics/Vector3.cpp"
|
||||
"src/memory/MemoryAllocator.h"
|
||||
"src/memory/MemoryAllocator.cpp"
|
||||
)
|
||||
|
||||
# Require the reactphysics3d code to be compiled in a static library
|
||||
ADD_LIBRARY (
|
||||
reactphysics3d
|
||||
STATIC
|
||||
${source_files}
|
||||
)
|
||||
# Create the library
|
||||
ADD_LIBRARY (reactphysics3d STATIC ${REACTPHYSICS3D_SOURCES})
|
||||
|
||||
# If we need to compile the examples
|
||||
IF (COMPILE_EXAMPLES)
|
||||
add_subdirectory(examples/fallingcubes)
|
||||
ENDIF (COMPILE_EXAMPLES)
|
||||
IF(COMPILE_EXAMPLES)
|
||||
add_subdirectory(examples/)
|
||||
ENDIF(COMPILE_EXAMPLES)
|
||||
|
||||
# If we need to compile the tests
|
||||
IF (COMPILE_TESTS)
|
||||
IF(COMPILE_TESTS)
|
||||
add_subdirectory(test/)
|
||||
ENDIF (COMPILE_TESTS)
|
||||
ENDIF(COMPILE_TESTS)
|
||||
|
|
32
cmake/FindFreeglut.cmake
Normal file
|
@ -0,0 +1,32 @@
|
|||
# This module is used to try to find the Freeglut library and include files
|
||||
|
||||
IF(WIN32)
|
||||
FIND_PATH(FREEGLUT_INCLUDE_DIR NAMES GL/freeglut.h)
|
||||
FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut freeglut_static)
|
||||
PATHS ${OPENGL_LIBRARY_DIR})
|
||||
ELSE(WIN32)
|
||||
|
||||
IF(APPLE)
|
||||
# Do nothing, we do not want to use freeglut on Mac OS X
|
||||
ELSE(APPLE)
|
||||
FIND_PATH(FREEGLUT_INCLUDE_DIR GL/freeglut.h /usr/include/GL
|
||||
/usr/openwin/share/include
|
||||
/usr/openwin/include
|
||||
/opt/graphics/OpenGL/include
|
||||
/opt/graphics/OpenGL/contrib/libglut)
|
||||
|
||||
FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut freeglut_static PATHS /usr/openwin/lib)
|
||||
FIND_LIBRARY(Xi_LIBRARY Xi /usr/openwin/lib)
|
||||
FIND_LIBRARY(Xmu_LIBRARY Xmu /usr/openwin/lib)
|
||||
ENDIF(APPLE)
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEGLUT REQUIRED_VARS FREEGLUT_LIBRARY FREEGLUT_INCLUDE_DIR)
|
||||
|
||||
IF(FREEGLUT_FOUND)
|
||||
SET(FREEGLUT_LIBRARIES ${FREEGLUT_LIBRARY} ${Xi_LIBRARY} ${Xmu_LIBRARY})
|
||||
SET(FREEGLUT_LIBRARY ${FREEGLUT_LIBRARIES})
|
||||
ENDIF(FREEGLUT_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(FREEGLUT_INCLUDE_DIR FREEGLUT_LIBRARY Xi_LIBRARY Xmu_LIBRARY)
|
65
cmake/FindGLEW.cmake
Normal file
|
@ -0,0 +1,65 @@
|
|||
#
|
||||
# Try to find GLEW library and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# GLEW_FOUND
|
||||
# GLEW_INCLUDE_PATH
|
||||
# GLEW_LIBRARY
|
||||
#
|
||||
|
||||
IF (WIN32)
|
||||
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||
$ENV{PROGRAMFILES}/GLEW/include
|
||||
${GLEW_ROOT_DIR}/include
|
||||
DOC "The directory where GL/glew.h resides")
|
||||
|
||||
IF (NV_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES glew64 glew64s
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/GLEW/lib
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
|
||||
DOC "The GLEW library (64-bit)"
|
||||
)
|
||||
ELSE(NV_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES glew GLEW glew32 glew32s
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/GLEW/lib
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
|
||||
DOC "The GLEW library"
|
||||
)
|
||||
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
ELSE (WIN32)
|
||||
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/sw/include
|
||||
/opt/local/include
|
||||
${GLEW_ROOT_DIR}/include
|
||||
DOC "The directory where GL/glew.h resides")
|
||||
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES GLEW glew
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
${GLEW_ROOT_DIR}/lib
|
||||
DOC "The GLEW library")
|
||||
ENDIF (WIN32)
|
||||
|
||||
SET(GLEW_FOUND "NO")
|
||||
IF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY)
|
||||
SET(GLEW_LIBRARIES ${GLEW_LIBRARY})
|
||||
SET(GLEW_FOUND "YES")
|
||||
ENDIF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY)
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_PATH)
|
|
@ -32,7 +32,7 @@ PROJECT_NAME = "ReactPhysics3D"
|
|||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = "0.3.0"
|
||||
PROJECT_NUMBER = "0.4.0"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer
|
||||
|
|
0
documentation/API/ReactPhysics3DLogo.png
Executable file → Normal file
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
documentation/UserManual/ReactPhysics3D-UserManual.pdf
Normal file
1144
documentation/UserManual/ReactPhysics3D-UserManual.tex
Executable file → Normal file
0
documentation/UserManual/images/ReactPhysics3DLogo.png
Executable file → Normal file
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
documentation/UserManual/images/boxshape.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
documentation/UserManual/images/capsuleshape.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
documentation/UserManual/images/coneshape.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
documentation/UserManual/images/convexshape.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
documentation/UserManual/images/cylindershape.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
documentation/UserManual/images/sphereshape.png
Normal file
After Width: | Height: | Size: 11 KiB |
2
documentation/UserManual/title.tex
Executable file → Normal file
|
@ -10,7 +10,7 @@
|
|||
\vskip 1.3cm
|
||||
{\Huge \@title\par}%
|
||||
\vskip 0.3cm
|
||||
{\Large Version: 0.3.0\par}%
|
||||
{\Large Version: 0.4.0\par}%
|
||||
\vskip 0.3cm
|
||||
{\Large \@author\par}%
|
||||
\vskip 2cm
|
||||
|
|
15
examples/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Minimum cmake version required
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
# Set a variable for the directory of the opengl-framework
|
||||
SET(OPENGLFRAMEWORK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common/opengl-framework")
|
||||
|
||||
# If we will use FREEGLUT
|
||||
IF(NOT APPLE)
|
||||
ADD_DEFINITIONS(-DUSE_FREEGLUT)
|
||||
ENDIF()
|
||||
|
||||
ADD_SUBDIRECTORY(common/)
|
||||
ADD_SUBDIRECTORY(cubes/)
|
||||
ADD_SUBDIRECTORY(joints/)
|
||||
ADD_SUBDIRECTORY(collisionshapes/)
|
41
examples/collisionshapes/CMakeLists.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Minimum cmake version required
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(CollisionShapes)
|
||||
|
||||
# Where to build the executables
|
||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/collisionshapes")
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
# Copy the shaders used for the demo into the build directory
|
||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
||||
|
||||
# Copy the meshes used for the demo into the build directory
|
||||
FILE(COPY "../common/meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/")
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/")
|
||||
|
||||
# Source files
|
||||
SET(COLLISION_SHAPES_SOURCES
|
||||
CollisionShapes.cpp
|
||||
Scene.cpp
|
||||
Scene.h
|
||||
"../common/VisualContactPoint.cpp"
|
||||
"../common/ConvexMesh.cpp"
|
||||
"../common/Capsule.cpp"
|
||||
"../common/Sphere.cpp"
|
||||
"../common/Cylinder.cpp"
|
||||
"../common/Cone.cpp"
|
||||
"../common/Box.cpp"
|
||||
"../common/Viewer.cpp"
|
||||
)
|
||||
|
||||
# Create the executable
|
||||
ADD_EXECUTABLE(collisionshapes ${COLLISION_SHAPES_SOURCES})
|
||||
|
||||
# Link with libraries
|
||||
TARGET_LINK_LIBRARIES(collisionshapes reactphysics3d openglframework)
|
158
examples/collisionshapes/CollisionShapes.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
#include "Viewer.h"
|
||||
|
||||
// Declarations
|
||||
void simulate();
|
||||
void display();
|
||||
void finish();
|
||||
void reshape(int width, int height);
|
||||
void mouseButton(int button, int state, int x, int y);
|
||||
void mouseMotion(int x, int y);
|
||||
void keyboard(unsigned char key, int x, int y);
|
||||
void init();
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Global variables
|
||||
Viewer* viewer;
|
||||
Scene* scene;
|
||||
|
||||
// Main function
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// Create and initialize the Viewer
|
||||
viewer = new Viewer();
|
||||
Vector2 windowsSize = Vector2(800, 600);
|
||||
Vector2 windowsPosition = Vector2(100, 100);
|
||||
bool initOK = viewer->init(argc, argv, "ReactPhysics3D Examples - Collision Shapes",
|
||||
windowsSize, windowsPosition);
|
||||
if (!initOK) return 1;
|
||||
|
||||
// Create the scene
|
||||
scene = new Scene(viewer);
|
||||
|
||||
init();
|
||||
|
||||
// Glut Idle function that is continuously called
|
||||
glutIdleFunc(simulate);
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutMouseFunc(mouseButton);
|
||||
glutMotionFunc(mouseMotion);
|
||||
glutKeyboardFunc(keyboard);
|
||||
#ifdef USE_FREEGLUT
|
||||
glutCloseFunc(finish);
|
||||
#else
|
||||
atexit(finish);
|
||||
#endif
|
||||
|
||||
// Glut main looop
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Simulate function
|
||||
void simulate() {
|
||||
|
||||
// Physics simulation
|
||||
scene->simulate();
|
||||
|
||||
viewer->computeFPS();
|
||||
|
||||
// Ask GLUT to render the scene
|
||||
glutPostRedisplay ();
|
||||
}
|
||||
|
||||
// Initialization
|
||||
void init() {
|
||||
|
||||
// Define the background color (black)
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Reshape function
|
||||
void reshape(int newWidth, int newHeight) {
|
||||
viewer->reshape(newWidth, newHeight);
|
||||
}
|
||||
|
||||
// Called when a mouse button event occurs
|
||||
void mouseButton(int button, int state, int x, int y) {
|
||||
viewer->mouseButtonEvent(button, state, x, y);
|
||||
}
|
||||
|
||||
// Called when a mouse motion event occurs
|
||||
void mouseMotion(int x, int y) {
|
||||
viewer->mouseMotionEvent(x, y);
|
||||
}
|
||||
|
||||
// Called when the user hits a special key on the keyboard
|
||||
void keyboard(unsigned char key, int x, int y) {
|
||||
switch(key) {
|
||||
|
||||
// Escape key
|
||||
case 27:
|
||||
#ifdef USE_FREEGLUT
|
||||
glutLeaveMainLoop();
|
||||
#endif
|
||||
break;
|
||||
|
||||
// Space bar
|
||||
case 32:
|
||||
scene->pauseContinueSimulation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// End of the application
|
||||
void finish() {
|
||||
|
||||
// Destroy the viewer and the scene
|
||||
delete viewer;
|
||||
delete scene;
|
||||
}
|
||||
|
||||
// Display the scene
|
||||
void display() {
|
||||
|
||||
// Render the scene
|
||||
scene->render();
|
||||
|
||||
// Display the FPS
|
||||
viewer->displayGUI();
|
||||
|
||||
// Swap the buffers
|
||||
glutSwapBuffers();
|
||||
|
||||
// Check the OpenGL errors
|
||||
GlutViewer::checkOpenGLErrors();
|
||||
}
|
||||
|
||||
|
451
examples/collisionshapes/Scene.cpp
Normal file
|
@ -0,0 +1,451 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
|
||||
mPhongShader("shaders/phong.vert",
|
||||
"shaders/phong.frag"), mIsRunning(false) {
|
||||
|
||||
// Move the light 0
|
||||
mLight0.translateWorld(Vector3(50, 50, 50));
|
||||
|
||||
// Compute the radius and the center of the scene
|
||||
float radiusScene = 10.0f;
|
||||
openglframework::Vector3 center(0, 5, 0);
|
||||
|
||||
// Set the center of the scene
|
||||
mViewer->setScenePosition(center, radiusScene);
|
||||
|
||||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
// Time step for the physics simulation
|
||||
rp3d::decimal timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
||||
// Create the static data for the visual contact points
|
||||
VisualContactPoint::createStaticData();
|
||||
|
||||
float radius = 3.0f;
|
||||
|
||||
// Create all the boxes of the scene
|
||||
for (int i=0; i<NB_BOXES; i++) {
|
||||
|
||||
// Position
|
||||
float angle = i * 30.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
60 + i * (BOX_SIZE.y + 0.8f),
|
||||
radius * sin(angle));
|
||||
|
||||
// Create a sphere and a corresponding rigid in the dynamics world
|
||||
Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The sphere is a moving rigid body
|
||||
box->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = box->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Add the sphere the list of sphere in the scene
|
||||
mBoxes.push_back(box);
|
||||
}
|
||||
|
||||
// Create all the spheres of the scene
|
||||
for (int i=0; i<NB_SPHERES; i++) {
|
||||
|
||||
// Position
|
||||
float angle = i * 35.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
50 + i * (SPHERE_RADIUS + 0.8f),
|
||||
radius * sin(angle));
|
||||
|
||||
// Create a sphere and a corresponding rigid in the dynamics world
|
||||
Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The sphere is a moving rigid body
|
||||
sphere->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Add the sphere the list of sphere in the scene
|
||||
mSpheres.push_back(sphere);
|
||||
}
|
||||
|
||||
// Create all the cones of the scene
|
||||
for (int i=0; i<NB_CONES; i++) {
|
||||
|
||||
// Position
|
||||
float angle = i * 50.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
35 + i * (CONE_HEIGHT + 0.3f),
|
||||
radius * sin(angle));
|
||||
|
||||
// Create a cone and a corresponding rigid in the dynamics world
|
||||
Cone* cone = new Cone(CONE_RADIUS, CONE_HEIGHT, position , CONE_MASS, mDynamicsWorld);
|
||||
|
||||
// The cone is a moving rigid body
|
||||
cone->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = cone->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Add the cone the list of sphere in the scene
|
||||
mCones.push_back(cone);
|
||||
}
|
||||
|
||||
// Create all the cylinders of the scene
|
||||
for (int i=0; i<NB_CYLINDERS; i++) {
|
||||
|
||||
// Position
|
||||
float angle = i * 35.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
25 + i * (CYLINDER_HEIGHT + 0.3f),
|
||||
radius * sin(angle));
|
||||
|
||||
// Create a cylinder and a corresponding rigid in the dynamics world
|
||||
Cylinder* cylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position ,
|
||||
CYLINDER_MASS, mDynamicsWorld);
|
||||
|
||||
// The cylinder is a moving rigid body
|
||||
cylinder->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = cylinder->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Add the cylinder the list of sphere in the scene
|
||||
mCylinders.push_back(cylinder);
|
||||
}
|
||||
|
||||
// Create all the capsules of the scene
|
||||
for (int i=0; i<NB_CAPSULES; i++) {
|
||||
|
||||
// Position
|
||||
float angle = i * 45.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
15 + i * (CAPSULE_HEIGHT + 0.3f),
|
||||
radius * sin(angle));
|
||||
|
||||
// Create a cylinder and a corresponding rigid in the dynamics world
|
||||
Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position ,
|
||||
CAPSULE_MASS, mDynamicsWorld);
|
||||
|
||||
// The cylinder is a moving rigid body
|
||||
capsule->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Add the cylinder the list of sphere in the scene
|
||||
mCapsules.push_back(capsule);
|
||||
}
|
||||
|
||||
// Create all the convex meshes of the scene
|
||||
for (int i=0; i<NB_MESHES; i++) {
|
||||
|
||||
// Position
|
||||
float angle = i * 30.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
5 + i * (CAPSULE_HEIGHT + 0.3f),
|
||||
radius * sin(angle));
|
||||
|
||||
// Create a convex mesh and a corresponding rigid in the dynamics world
|
||||
ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld);
|
||||
|
||||
// The mesh is a moving rigid body
|
||||
mesh->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Add the mesh the list of sphere in the scene
|
||||
mConvexMeshes.push_back(mesh);
|
||||
}
|
||||
|
||||
// Create the floor
|
||||
openglframework::Vector3 floorPosition(0, 0, 0);
|
||||
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
|
||||
|
||||
// The floor must be a non-moving rigid body
|
||||
mFloor->getRigidBody()->enableMotion(false);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.2));
|
||||
|
||||
// Start the simulation
|
||||
startSimulation();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Scene::~Scene() {
|
||||
|
||||
// Stop the physics simulation
|
||||
stopSimulation();
|
||||
|
||||
// Destroy the shader
|
||||
mPhongShader.destroy();
|
||||
|
||||
// Destroy all the boxes of the scene
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the box
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy all the sphere of the scene
|
||||
for (std::vector<Sphere*>::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the sphere
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy all the cones of the scene
|
||||
for (std::vector<Cone*>::iterator it = mCones.begin(); it != mCones.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the sphere
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy all the cylinders of the scene
|
||||
for (std::vector<Cylinder*>::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the sphere
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy all the capsules of the scene
|
||||
for (std::vector<Capsule*>::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the sphere
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy all the convex meshes of the scene
|
||||
for (std::vector<ConvexMesh*>::iterator it = mConvexMeshes.begin();
|
||||
it != mConvexMeshes.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the convex mesh
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy all the visual contact points
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||
it != mContactPoints.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy the static data for the visual contact points
|
||||
VisualContactPoint::destroyStaticData();
|
||||
|
||||
// Destroy the rigid body of the floor
|
||||
mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody());
|
||||
|
||||
// Destroy the floor
|
||||
delete mFloor;
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void Scene::simulate() {
|
||||
|
||||
// If the physics simulation is running
|
||||
if (mIsRunning) {
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
// Update the position and orientation of the sphere
|
||||
for (std::vector<Sphere*>::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
// Update the position and orientation of the cones
|
||||
for (std::vector<Cone*>::iterator it = mCones.begin(); it != mCones.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
// Update the position and orientation of the cylinders
|
||||
for (std::vector<Cylinder*>::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
// Update the position and orientation of the capsules
|
||||
for (std::vector<Capsule*>::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
// Update the position and orientation of the convex meshes
|
||||
for (std::vector<ConvexMesh*>::iterator it = mConvexMeshes.begin();
|
||||
it != mConvexMeshes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
// Destroy all the visual contact points
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||
it != mContactPoints.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
mContactPoints.clear();
|
||||
|
||||
// Generate the new visual contact points
|
||||
const std::vector<rp3d::ContactManifold*>& manifolds = mDynamicsWorld->getContactManifolds();
|
||||
for (std::vector<rp3d::ContactManifold*>::const_iterator it = manifolds.begin();
|
||||
it != manifolds.end(); ++it) {
|
||||
for (unsigned int i=0; i<(*it)->getNbContactPoints(); i++) {
|
||||
rp3d::ContactPoint* point = (*it)->getContactPoint(i);
|
||||
|
||||
const rp3d::Vector3 pos = point->getWorldPointOnBody1();
|
||||
openglframework::Vector3 position(pos.x, pos.y, pos.z);
|
||||
VisualContactPoint* visualPoint = new VisualContactPoint(position);
|
||||
mContactPoints.push_back(visualPoint);
|
||||
}
|
||||
}
|
||||
|
||||
mFloor->updateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
// Render the scene
|
||||
void Scene::render() {
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Get the world-space to camera-space matrix
|
||||
const Camera& camera = mViewer->getCamera();
|
||||
const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse();
|
||||
|
||||
// Bind the shader
|
||||
mPhongShader.bind();
|
||||
|
||||
// Set the variables of the shader
|
||||
mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix());
|
||||
mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin());
|
||||
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
|
||||
const Color& diffColLight0 = mLight0.getDiffuseColor();
|
||||
const Color& specColLight0 = mLight0.getSpecularColor();
|
||||
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffColLight0.r, diffColLight0.g, diffColLight0.b));
|
||||
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specColLight0.r, specColLight0.g, specColLight0.b));
|
||||
mPhongShader.setFloatUniform("shininess", 200.0f);
|
||||
|
||||
// Render all the boxes of the scene
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render all the sphere of the scene
|
||||
for (std::vector<Sphere*>::iterator it = mSpheres.begin(); it != mSpheres.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render all the cones of the scene
|
||||
for (std::vector<Cone*>::iterator it = mCones.begin(); it != mCones.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render all the cylinders of the scene
|
||||
for (std::vector<Cylinder*>::iterator it = mCylinders.begin(); it != mCylinders.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render all the capsules of the scene
|
||||
for (std::vector<Capsule*>::iterator it = mCapsules.begin(); it != mCapsules.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render all the convex meshes of the scene
|
||||
for (std::vector<ConvexMesh*>::iterator it = mConvexMeshes.begin();
|
||||
it != mConvexMeshes.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render all the visual contact points
|
||||
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
|
||||
it != mContactPoints.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render the floor
|
||||
mFloor->render(mPhongShader, worldToCameraMatrix);
|
||||
|
||||
// Unbind the shader
|
||||
mPhongShader.unbind();
|
||||
}
|
153
examples/collisionshapes/Scene.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "Sphere.h"
|
||||
#include "Box.h"
|
||||
#include "Cone.h"
|
||||
#include "Cylinder.h"
|
||||
#include "Capsule.h"
|
||||
#include "ConvexMesh.h"
|
||||
#include "VisualContactPoint.h"
|
||||
|
||||
// Constants
|
||||
const int NB_BOXES = 3;
|
||||
const int NB_SPHERES = 3;
|
||||
const int NB_CONES = 3;
|
||||
const int NB_CYLINDERS = 3;
|
||||
const int NB_CAPSULES = 3;
|
||||
const int NB_MESHES = 3;
|
||||
const openglframework::Vector3 BOX_SIZE(2, 2, 2);
|
||||
const float SPHERE_RADIUS = 1.5f;
|
||||
const float CONE_RADIUS = 2.0f;
|
||||
const float CONE_HEIGHT = 3.0f;
|
||||
const float CYLINDER_RADIUS = 1.0f;
|
||||
const float CYLINDER_HEIGHT = 5.0f;
|
||||
const float CAPSULE_RADIUS = 1.0f;
|
||||
const float CAPSULE_HEIGHT = 1.0f;
|
||||
const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters
|
||||
const float BOX_MASS = 1.0f;
|
||||
const float CONE_MASS = 1.0f;
|
||||
const float CYLINDER_MASS = 1.0f;
|
||||
const float CAPSULE_MASS = 1.0f;
|
||||
const float MESH_MASS = 1.0f;
|
||||
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
|
||||
|
||||
// Class Scene
|
||||
class Scene {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Pointer to the viewer
|
||||
openglframework::GlutViewer* mViewer;
|
||||
|
||||
/// Light 0
|
||||
openglframework::Light mLight0;
|
||||
|
||||
/// Phong shader
|
||||
openglframework::Shader mPhongShader;
|
||||
|
||||
/// All the spheres of the scene
|
||||
std::vector<Box*> mBoxes;
|
||||
|
||||
std::vector<Sphere*> mSpheres;
|
||||
|
||||
std::vector<Cone*> mCones;
|
||||
|
||||
std::vector<Cylinder*> mCylinders;
|
||||
|
||||
std::vector<Capsule*> mCapsules;
|
||||
|
||||
/// All the convex meshes of the scene
|
||||
std::vector<ConvexMesh*> mConvexMeshes;
|
||||
|
||||
/// All the visual contact points
|
||||
std::vector<VisualContactPoint*> mContactPoints;
|
||||
|
||||
/// Box for the floor
|
||||
Box* mFloor;
|
||||
|
||||
/// Dynamics world used for the physics simulation
|
||||
rp3d::DynamicsWorld* mDynamicsWorld;
|
||||
|
||||
/// True if the physics simulation is running
|
||||
bool mIsRunning;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Scene(openglframework::GlutViewer* viewer);
|
||||
|
||||
/// Destructor
|
||||
~Scene();
|
||||
|
||||
/// Take a step for the simulation
|
||||
void simulate();
|
||||
|
||||
/// Stop the simulation
|
||||
void stopSimulation();
|
||||
|
||||
/// Start the simulation
|
||||
void startSimulation();
|
||||
|
||||
/// Pause or continue simulation
|
||||
void pauseContinueSimulation();
|
||||
|
||||
/// Render the scene
|
||||
void render();
|
||||
};
|
||||
|
||||
// Stop the simulation
|
||||
inline void Scene::stopSimulation() {
|
||||
mDynamicsWorld->stop();
|
||||
mIsRunning = false;
|
||||
}
|
||||
|
||||
// Start the simulation
|
||||
inline void Scene::startSimulation() {
|
||||
mDynamicsWorld->start();
|
||||
mIsRunning = true;
|
||||
}
|
||||
|
||||
// Pause or continue simulation
|
||||
inline void Scene::pauseContinueSimulation() {
|
||||
if (mIsRunning) {
|
||||
stopSimulation();
|
||||
}
|
||||
else {
|
||||
startSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
192
examples/common/Box.cpp
Normal file
|
@ -0,0 +1,192 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Box.h"
|
||||
|
||||
// Macros
|
||||
#define MEMBER_OFFSET(s,m) ((char *)NULL + (offsetof(s,m)))
|
||||
|
||||
// Initialize static variables
|
||||
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
|
||||
openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||
bool Box::areVBOsCreated = false;
|
||||
VertexData Box::mCubeVertices[8] = {
|
||||
{openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)},
|
||||
{openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)}
|
||||
};
|
||||
GLuint Box::mCubeIndices[36] = { 0, 1, 2,
|
||||
2, 3, 0,
|
||||
7, 4, 5,
|
||||
5, 6, 7,
|
||||
6, 5, 2,
|
||||
2, 1, 6,
|
||||
7, 0, 3,
|
||||
3, 4, 7,
|
||||
7, 6, 1,
|
||||
1, 0, 7,
|
||||
3, 2, 5,
|
||||
5, 4, 3};
|
||||
|
||||
// Constructor
|
||||
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
|
||||
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
|
||||
|
||||
// Initialize the size of the box
|
||||
mSize[0] = size.x * 0.5f;
|
||||
mSize[1] = size.y * 0.5f;
|
||||
mSize[2] = size.z * 0.5f;
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0,
|
||||
0, mSize[1], 0, 0,
|
||||
0, 0, mSize[2], 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
// Initialize the position where the cube will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (box shape)
|
||||
// ReactPhysics3D will clone this object to create an internal one. Therefore,
|
||||
// it is OK if this object is destroyed right after calling Dynamics::createRigidBody()
|
||||
const rp3d::BoxShape collisionShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2]));
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
collisionShape.computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the cube in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, collisionShape);
|
||||
|
||||
// If the Vertex Buffer object has not been created yet
|
||||
if (!areVBOsCreated) {
|
||||
// Create the Vertex Buffer
|
||||
createVBO();
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Box::~Box() {
|
||||
|
||||
}
|
||||
|
||||
// Render the cube at the correct position and with the correct orientation
|
||||
void Box::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
// Set the vertex color
|
||||
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
|
||||
shader.setVector4Uniform("vertexColor", color);
|
||||
|
||||
// Bind the vertices VBO
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Enable the vertex, normal and color arrays
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
// Set the arrays pointers
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position));
|
||||
glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal));
|
||||
glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color));
|
||||
|
||||
// Bind the indices VBO
|
||||
mVBOIndices.bind();
|
||||
|
||||
// Draw the geometry of the box
|
||||
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL);
|
||||
|
||||
// Unbind the VBOs
|
||||
mVBOVertices.unbind();
|
||||
mVBOIndices.unbind();
|
||||
|
||||
// Disable the arrays
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the box
|
||||
void Box::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Compute the transform used for rendering the box
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
// Apply the scaling matrix to have the correct box dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
}
|
||||
|
||||
// Create the Vertex Buffer Objects used to render to box with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices) to render all the boxes
|
||||
/// in the simulation.
|
||||
void Box::createVBO() {
|
||||
|
||||
// Create the VBOs
|
||||
mVBOVertices.create();
|
||||
mVBOIndices.create();
|
||||
|
||||
// Copy the data into the VBOs
|
||||
mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
|
||||
mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW);
|
||||
|
||||
areVBOsCreated = true;
|
||||
}
|
119
examples/common/Box.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef BOX_H
|
||||
#define BOX_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// Structure VertexData
|
||||
struct VertexData {
|
||||
|
||||
/// Vertex position
|
||||
openglframework::Vector3 position;
|
||||
|
||||
/// Vertex normal
|
||||
openglframework::Vector3 normal;
|
||||
|
||||
// Vertex color
|
||||
openglframework::Color color;
|
||||
};
|
||||
|
||||
// Class Box
|
||||
class Box : public openglframework::Object3D {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Size of each side of the box
|
||||
float mSize[3];
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the box
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
/// Scaling matrix (applied to a cube to obtain the correct box dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Vertex Buffer Object for the vertices data used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBOVertices;
|
||||
|
||||
/// Vertex Buffer Object for the indices used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBOIndices;
|
||||
|
||||
/// Vertex data for each vertex of the cube (used to render the box)
|
||||
static VertexData mCubeVertices[8];
|
||||
|
||||
/// Indices of the cube (used to render the box)
|
||||
static GLuint mCubeIndices[36];
|
||||
|
||||
/// True if the VBOs have already been created
|
||||
static bool areVBOsCreated;
|
||||
|
||||
/// Main color of the box
|
||||
openglframework::Color mColor;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Create a Vertex Buffer Object to render to box with OpenGL
|
||||
static void createVBO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Box(const openglframework::Vector3& size, const openglframework::Vector3& position,
|
||||
float mass, rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~Box();
|
||||
|
||||
/// Return a pointer to the rigid body of the box
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the box
|
||||
void updateTransform();
|
||||
|
||||
/// Render the cube at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
/// Set the color of the box
|
||||
void setColor(const openglframework::Color& color);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* Box::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
// Set the color of the box
|
||||
inline void Box::setColor(const openglframework::Color& color) {
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
#endif
|
4
examples/common/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Minimum cmake version required
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
ADD_SUBDIRECTORY(opengl-framework/)
|
136
examples/common/Capsule.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Capsule.h"
|
||||
|
||||
|
||||
// Constructor
|
||||
Capsule::Capsule(float radius, float height, const openglframework::Vector3 &position,
|
||||
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Mesh(), mRadius(radius), mHeight(height) {
|
||||
|
||||
// Load the mesh from a file
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile("meshes/capsule.obj", *this);
|
||||
|
||||
// Calculate the normals of the mesh
|
||||
calculateNormals();
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0,
|
||||
0, (mHeight + 2.0f * mRadius) / 3.0f, 0,0,
|
||||
0, 0, mRadius, 0,
|
||||
0, 0, 0, 1.0f);
|
||||
|
||||
// Initialize the position where the sphere will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (sphere shape)
|
||||
// ReactPhysics3D will clone this object to create an internal one. Therefore,
|
||||
// it is OK if this object is destroyed right after calling Dynamics::createRigidBody()
|
||||
const rp3d::CapsuleShape collisionShape(mRadius, mHeight);
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
collisionShape.computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, collisionShape);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Capsule::~Capsule() {
|
||||
|
||||
// Destroy the mesh
|
||||
destroy();
|
||||
}
|
||||
|
||||
// Render the sphere at the correct position and with the correct orientation
|
||||
void Capsule::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Capsule::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
}
|
81
examples/common/Capsule.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CAPSULE_H
|
||||
#define CAPSULE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// Class Sphere
|
||||
class Capsule : public openglframework::Mesh {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Radius of the capsule
|
||||
float mRadius;
|
||||
|
||||
/// Height of the capsule
|
||||
float mHeight;
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the sphere
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Capsule(float radius, float height, const openglframework::Vector3& position,
|
||||
float mass, rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~Capsule();
|
||||
|
||||
/// Return a pointer to the rigid body of the sphere
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
|
||||
/// Render the sphere at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the sphere
|
||||
inline rp3d::RigidBody* Capsule::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
#endif
|
136
examples/common/Cone.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Cone.h"
|
||||
|
||||
|
||||
// Constructor
|
||||
Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
|
||||
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Mesh(), mRadius(radius), mHeight(height) {
|
||||
|
||||
// Load the mesh from a file
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile("meshes/cone.obj", *this);
|
||||
|
||||
// Calculate the normals of the mesh
|
||||
calculateNormals();
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0,
|
||||
0, mHeight, 0, 0,
|
||||
0, 0, mRadius, 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
// Initialize the position where the cone will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (cone shape)
|
||||
// ReactPhysics3D will clone this object to create an internal one. Therefore,
|
||||
// it is OK if this object is destroyed right after calling Dynamics::createRigidBody()
|
||||
const rp3d::ConeShape collisionShape(mRadius, mHeight);
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
collisionShape.computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the cone in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, collisionShape);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Cone::~Cone() {
|
||||
|
||||
// Destroy the mesh
|
||||
destroy();
|
||||
}
|
||||
|
||||
// Render the cone at the correct position and with the correct orientation
|
||||
void Cone::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the cone
|
||||
void Cone::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Compute the transform used for rendering the cone
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
// Apply the scaling matrix to have the correct cone dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
}
|
81
examples/common/Cone.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CONE_H
|
||||
#define CONE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// Class Cone
|
||||
class Cone : public openglframework::Mesh {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Radius of the cone
|
||||
float mRadius;
|
||||
|
||||
/// Height of the cone
|
||||
float mHeight;
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the cone
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
/// Scaling matrix (applied to a sphere to obtain the correct cone dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Cone(float radius, float height, const openglframework::Vector3& position,
|
||||
float mass, rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~Cone();
|
||||
|
||||
/// Return a pointer to the rigid body of the cone
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the cone
|
||||
void updateTransform();
|
||||
|
||||
/// Render the cone at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the cone
|
||||
inline rp3d::RigidBody* Cone::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
#endif
|
149
examples/common/ConvexMesh.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "ConvexMesh.h"
|
||||
|
||||
|
||||
// Constructor
|
||||
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
|
||||
reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Mesh() {
|
||||
|
||||
// Load the mesh from a file
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile("meshes/convexmesh.obj", *this);
|
||||
|
||||
// Calculate the normals of the mesh
|
||||
calculateNormals();
|
||||
|
||||
// Initialize the position where the sphere will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (convex mesh shape)
|
||||
// ReactPhysics3D will clone this object to create an internal one. Therefore,
|
||||
// it is OK if this object is destroyed right after calling Dynamics::createRigidBody()
|
||||
rp3d::decimal* verticesArray = (rp3d::decimal*) getVerticesPointer();
|
||||
rp3d::ConvexMeshShape collisionShape(verticesArray, mVertices.size(),
|
||||
sizeof(openglframework::Vector3));
|
||||
|
||||
// Add the edges information of the mesh into the convex mesh collision shape.
|
||||
// This is optional but it really speed up the convex mesh collision detection at the
|
||||
// cost of some additional memory to store the edges inside the collision shape.
|
||||
for (unsigned int i=0; i<getNbFaces(); i++) { // For each triangle face of the mesh
|
||||
|
||||
// Get the three vertex IDs of the vertices of the face
|
||||
unsigned int v1 = getVertexIndexInFace(i, 0);
|
||||
unsigned int v2 = getVertexIndexInFace(i, 1);
|
||||
unsigned int v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
// Add the three edges into the collision shape
|
||||
collisionShape.addEdge(v1, v2);
|
||||
collisionShape.addEdge(v1, v3);
|
||||
collisionShape.addEdge(v2, v3);
|
||||
}
|
||||
collisionShape.setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
collisionShape.computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, collisionShape);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
ConvexMesh::~ConvexMesh() {
|
||||
|
||||
// Destroy the mesh
|
||||
destroy();
|
||||
}
|
||||
|
||||
// Render the sphere at the correct position and with the correct orientation
|
||||
void ConvexMesh::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void ConvexMesh::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix;
|
||||
}
|
72
examples/common/ConvexMesh.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CONVEX_MESH_H
|
||||
#define CONVEX_MESH_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// Class ConvexMesh
|
||||
class ConvexMesh : public openglframework::Mesh {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the mesh
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ConvexMesh(const openglframework::Vector3& position, float mass,
|
||||
rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~ConvexMesh();
|
||||
|
||||
/// Return a pointer to the rigid body of the mesh
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the mesh
|
||||
void updateTransform();
|
||||
|
||||
/// Render the mesh at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the mesh
|
||||
inline rp3d::RigidBody* ConvexMesh::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
#endif
|
136
examples/common/Cylinder.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Cylinder.h"
|
||||
|
||||
|
||||
// Constructor
|
||||
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3 &position,
|
||||
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Mesh(), mRadius(radius), mHeight(height) {
|
||||
|
||||
// Load the mesh from a file
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile("meshes/cylinder.obj", *this);
|
||||
|
||||
// Calculate the normals of the mesh
|
||||
calculateNormals();
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0,
|
||||
0, mHeight, 0, 0,
|
||||
0, 0, mRadius, 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
// Initialize the position where the cylinder will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (cylinder shape)
|
||||
// ReactPhysics3D will clone this object to create an internal one. Therefore,
|
||||
// it is OK if this object is destroyed right after calling Dynamics::createRigidBody()
|
||||
const rp3d::CylinderShape collisionShape(mRadius, mHeight);
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
collisionShape.computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the cylinder in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, collisionShape);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Cylinder::~Cylinder() {
|
||||
|
||||
// Destroy the mesh
|
||||
destroy();
|
||||
}
|
||||
|
||||
// Render the cylinder at the correct position and with the correct orientation
|
||||
void Cylinder::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the cylinder
|
||||
void Cylinder::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Compute the transform used for rendering the cylinder
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
// Apply the scaling matrix to have the correct cylinder dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
}
|
81
examples/common/Cylinder.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CYLINDER_H
|
||||
#define CYLINDER_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// Class Cylinder
|
||||
class Cylinder : public openglframework::Mesh {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Radius of the cylinder
|
||||
float mRadius;
|
||||
|
||||
/// Height of the cylinder
|
||||
float mHeight;
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the cylinder
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
/// Scaling matrix (applied to a sphere to obtain the correct cylinder dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Cylinder(float radius, float height, const openglframework::Vector3& position,
|
||||
float mass, rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~Cylinder();
|
||||
|
||||
/// Return a pointer to the rigid body of the cylinder
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the cylinder
|
||||
void updateTransform();
|
||||
|
||||
/// Render the cylinder at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the cylinder
|
||||
inline rp3d::RigidBody* Cylinder::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
#endif
|
136
examples/common/Sphere.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Sphere.h"
|
||||
|
||||
|
||||
// Constructor
|
||||
Sphere::Sphere(float radius, const openglframework::Vector3 &position,
|
||||
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Mesh(), mRadius(radius) {
|
||||
|
||||
// Load the mesh from a file
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile("meshes/sphere.obj", *this);
|
||||
|
||||
// Calculate the normals of the mesh
|
||||
calculateNormals();
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0,
|
||||
0, mRadius, 0, 0,
|
||||
0, 0, mRadius, 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
// Initialize the position where the sphere will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (sphere shape)
|
||||
// ReactPhysics3D will clone this object to create an internal one. Therefore,
|
||||
// it is OK if this object is destroyed right after calling Dynamics::createRigidBody()
|
||||
const rp3d::SphereShape collisionShape(mRadius);
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
collisionShape.computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the sphere in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, collisionShape);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Sphere::~Sphere() {
|
||||
|
||||
// Destroy the mesh
|
||||
destroy();
|
||||
}
|
||||
|
||||
// Render the sphere at the correct position and with the correct orientation
|
||||
void Sphere::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, getNormalsPointer());
|
||||
if(hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
|
||||
}
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, getIndicesPointer());
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the sphere
|
||||
void Sphere::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Compute the transform used for rendering the sphere
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
// Apply the scaling matrix to have the correct sphere dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
}
|
|
@ -23,59 +23,56 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CONTACT_INFO_H
|
||||
#define CONTACT_INFO_H
|
||||
#ifndef SPHERE_H
|
||||
#define SPHERE_H
|
||||
|
||||
// Libraries
|
||||
#include "../collision/shapes/BoxShape.h"
|
||||
#include "../mathematics/mathematics.h"
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
// Class Sphere
|
||||
class Sphere : public openglframework::Mesh {
|
||||
|
||||
// Structure ContactInfo
|
||||
/**
|
||||
* This structure contains informations about a collision contact
|
||||
* computed during the narrow-phase collision detection. Those
|
||||
* informations are used to compute the contact set for a contact
|
||||
* between two bodies.
|
||||
*/
|
||||
struct ContactInfo {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Private copy-constructor
|
||||
ContactInfo(const ContactInfo& contactInfo);
|
||||
|
||||
/// Private assignment operator
|
||||
ContactInfo& operator=(const ContactInfo& contactInfo);
|
||||
|
||||
public:
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Normal vector the the collision contact in world space
|
||||
const Vector3 normal;
|
||||
/// Radius of the sphere
|
||||
float mRadius;
|
||||
|
||||
/// Penetration depth of the contact
|
||||
const decimal penetrationDepth;
|
||||
/// Rigid body used to simulate the dynamics of the sphere
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
/// Contact point of body 1 in local space of body 1
|
||||
const Vector3 localPoint1;
|
||||
/// Scaling matrix (applied to a sphere to obtain the correct sphere dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Contact point of body 2 in local space of body 2
|
||||
const Vector3 localPoint2;
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ContactInfo(const Vector3& normal, decimal penetrationDepth,
|
||||
const Vector3& localPoint1, const Vector3& localPoint2);
|
||||
Sphere(float radius, const openglframework::Vector3& position,
|
||||
float mass, rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~Sphere();
|
||||
|
||||
/// Return a pointer to the rigid body of the sphere
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Update the transform matrix of the sphere
|
||||
void updateTransform();
|
||||
|
||||
/// Render the sphere at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
};
|
||||
|
||||
// Return a pointer to the rigid body of the sphere
|
||||
inline rp3d::RigidBody* Sphere::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
85
examples/common/Viewer.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Viewer.h"
|
||||
#include "openglframework.h"
|
||||
#include <sstream>
|
||||
|
||||
// Constructor
|
||||
Viewer::Viewer() : openglframework::GlutViewer(), fps(0), nbFrames(0) {
|
||||
|
||||
}
|
||||
|
||||
// Compute the FPS
|
||||
void Viewer::computeFPS() {
|
||||
|
||||
nbFrames++;
|
||||
|
||||
// Get the number of milliseconds since glutInit called
|
||||
currentTime = glutGet(GLUT_ELAPSED_TIME);
|
||||
|
||||
// Calculate time passed
|
||||
int timeInterval = currentTime - previousTime;
|
||||
|
||||
// Update the FPS counter each second
|
||||
if(timeInterval > 1000){
|
||||
|
||||
// calculate the number of frames per second
|
||||
fps = static_cast<int>(nbFrames / (timeInterval / 1000.0f));
|
||||
|
||||
// Set time
|
||||
previousTime = currentTime;
|
||||
|
||||
// Reset frame count
|
||||
nbFrames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the GUI
|
||||
void Viewer::displayGUI() {
|
||||
|
||||
// Display the FPS
|
||||
displayFPS();
|
||||
}
|
||||
|
||||
// Display the FPS
|
||||
void Viewer::displayFPS() {
|
||||
|
||||
#ifdef USE_FREEGLUT
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, mCamera.getWidth(), mCamera.getHeight(), 0, -1, 1);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glRasterPos2i(10, 20);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
std::stringstream ss;
|
||||
ss << "FPS : " << fps;
|
||||
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)ss.str().c_str());
|
||||
#endif
|
||||
}
|
71
examples/common/Viewer.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VIEWER_H
|
||||
#define VIEWER_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
|
||||
// Class Viewer
|
||||
class Viewer : public openglframework::GlutViewer {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Current number of frames per seconds
|
||||
int fps;
|
||||
|
||||
/// Number of frames during the last second
|
||||
int nbFrames;
|
||||
|
||||
/// Current time for fps computation
|
||||
int currentTime;
|
||||
|
||||
/// Previous time for fps computation
|
||||
int previousTime;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Display the FPS
|
||||
void displayFPS();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Viewer();
|
||||
|
||||
/// Compute the FPS
|
||||
void computeFPS();
|
||||
|
||||
/// Display the GUI
|
||||
void displayGUI();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
115
examples/common/VisualContactPoint.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "VisualContactPoint.h"
|
||||
|
||||
// Initialization of static variables
|
||||
int VisualContactPoint::mNbTotalPoints = 0;
|
||||
bool VisualContactPoint::mIsMeshInitialized = false;
|
||||
openglframework::Mesh VisualContactPoint::mMesh;
|
||||
|
||||
// Constructor
|
||||
VisualContactPoint::VisualContactPoint(const openglframework::Vector3 &position) {
|
||||
|
||||
assert(mIsMeshInitialized);
|
||||
|
||||
// Initialize the position where the sphere will be rendered
|
||||
translateWorld(position);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
VisualContactPoint::~VisualContactPoint() {
|
||||
|
||||
}
|
||||
|
||||
// Load and initialize the mesh for all the contact points
|
||||
void VisualContactPoint::createStaticData() {
|
||||
|
||||
if (!mIsMeshInitialized) {
|
||||
|
||||
// Load the mesh from a file
|
||||
openglframework::MeshReaderWriter::loadMeshFromFile("meshes/sphere.obj", mMesh);
|
||||
|
||||
// Calculate the normals of the mesh
|
||||
mMesh.calculateNormals();
|
||||
|
||||
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
|
||||
|
||||
mIsMeshInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the mesh for the contact points
|
||||
void VisualContactPoint::destroyStaticData() {
|
||||
|
||||
mMesh.destroy();
|
||||
mIsMeshInitialized = false;
|
||||
}
|
||||
|
||||
// Render the sphere at the correct position and with the correct orientation
|
||||
void VisualContactPoint::render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to camera matrix
|
||||
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
|
||||
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
|
||||
|
||||
// Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the
|
||||
// model-view matrix)
|
||||
const openglframework::Matrix3 normalMatrix =
|
||||
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
|
||||
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
if (mMesh.hasTexture()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, mMesh.getVerticesPointer());
|
||||
glNormalPointer(GL_FLOAT, 0, mMesh.getNormalsPointer());
|
||||
if(mMesh.hasTexture()) {
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, mMesh.getUVTextureCoordinatesPointer());
|
||||
}
|
||||
|
||||
// For each part of the mesh
|
||||
for (unsigned int i=0; i<mMesh.getNbParts(); i++) {
|
||||
glDrawElements(GL_TRIANGLES, mMesh.getNbFaces(i) * 3,
|
||||
GL_UNSIGNED_INT, mMesh.getIndicesPointer());
|
||||
}
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (mMesh.hasTexture()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
73
examples/common/VisualContactPoint.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VISUAL_CONTACT_POINT_H
|
||||
#define VISUAL_CONTACT_POINT_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
|
||||
const float VISUAL_CONTACT_POINT_RADIUS = 0.1f;
|
||||
|
||||
// Class VisualContactPoint
|
||||
class VisualContactPoint : public openglframework::Object3D {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Total number of existing contact points (static attribute)
|
||||
static int mNbTotalPoints;
|
||||
|
||||
/// Sphere mesh for the visual contact point
|
||||
static openglframework::Mesh mMesh;
|
||||
|
||||
/// True if the mesh has been initialized
|
||||
static bool mIsMeshInitialized;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
VisualContactPoint(const openglframework::Vector3& position);
|
||||
|
||||
/// Destructor
|
||||
~VisualContactPoint();
|
||||
|
||||
/// Load and initialize the mesh for all the contact points
|
||||
static void createStaticData();
|
||||
|
||||
/// Destroy the mesh for the contact points
|
||||
static void destroyStaticData();
|
||||
|
||||
/// Render the sphere at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader,
|
||||
const openglframework::Matrix4& worldToCameraMatrix);
|
||||
};
|
||||
|
||||
#endif
|
1060
examples/common/meshes/capsule.obj
Normal file
101
examples/common/meshes/cone.obj
Normal file
|
@ -0,0 +1,101 @@
|
|||
# Blender v2.66 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
v 0.000000 -0.500000 0.000000
|
||||
v 0.000000 -0.500000 -1.000000
|
||||
v 0.195090 -0.500000 -0.980785
|
||||
v 0.382683 -0.500000 -0.923880
|
||||
v 0.555570 -0.500000 -0.831470
|
||||
v 0.707107 -0.500000 -0.707107
|
||||
v 0.831470 -0.500000 -0.555570
|
||||
v 0.923880 -0.500000 -0.382683
|
||||
v 0.980785 -0.500000 -0.195090
|
||||
v 1.000000 -0.500000 -0.000000
|
||||
v 0.000000 0.500000 0.000000
|
||||
v 0.980785 -0.500000 0.195090
|
||||
v 0.923880 -0.500000 0.382683
|
||||
v 0.831470 -0.500000 0.555570
|
||||
v 0.707107 -0.500000 0.707107
|
||||
v 0.555570 -0.500000 0.831470
|
||||
v 0.382683 -0.500000 0.923880
|
||||
v 0.195090 -0.500000 0.980785
|
||||
v -0.000000 -0.500000 1.000000
|
||||
v -0.195091 -0.500000 0.980785
|
||||
v -0.382684 -0.500000 0.923879
|
||||
v -0.555571 -0.500000 0.831469
|
||||
v -0.707107 -0.500000 0.707106
|
||||
v -0.831470 -0.500000 0.555570
|
||||
v -0.923880 -0.500000 0.382683
|
||||
v -0.980785 -0.500000 0.195089
|
||||
v -1.000000 -0.500000 -0.000001
|
||||
v -0.980785 -0.500000 -0.195091
|
||||
v -0.923879 -0.500000 -0.382684
|
||||
v -0.831469 -0.500000 -0.555571
|
||||
v -0.707106 -0.500000 -0.707108
|
||||
v -0.555569 -0.500000 -0.831470
|
||||
v -0.382682 -0.500000 -0.923880
|
||||
v -0.195089 -0.500000 -0.980786
|
||||
s off
|
||||
f 1 2 3
|
||||
f 1 3 4
|
||||
f 1 4 5
|
||||
f 1 5 6
|
||||
f 1 6 7
|
||||
f 1 7 8
|
||||
f 1 8 9
|
||||
f 1 9 10
|
||||
f 1 10 12
|
||||
f 1 12 13
|
||||
f 1 13 14
|
||||
f 1 14 15
|
||||
f 1 15 16
|
||||
f 1 16 17
|
||||
f 1 17 18
|
||||
f 1 18 19
|
||||
f 1 19 20
|
||||
f 1 20 21
|
||||
f 1 21 22
|
||||
f 1 22 23
|
||||
f 1 23 24
|
||||
f 1 24 25
|
||||
f 1 25 26
|
||||
f 1 26 27
|
||||
f 1 27 28
|
||||
f 1 28 29
|
||||
f 1 29 30
|
||||
f 1 30 31
|
||||
f 1 31 32
|
||||
f 1 32 33
|
||||
f 1 33 34
|
||||
f 1 34 2
|
||||
f 2 11 3
|
||||
f 3 11 4
|
||||
f 4 11 5
|
||||
f 5 11 6
|
||||
f 6 11 7
|
||||
f 7 11 8
|
||||
f 8 11 9
|
||||
f 9 11 10
|
||||
f 10 11 12
|
||||
f 12 11 13
|
||||
f 13 11 14
|
||||
f 14 11 15
|
||||
f 15 11 16
|
||||
f 16 11 17
|
||||
f 17 11 18
|
||||
f 18 11 19
|
||||
f 19 11 20
|
||||
f 20 11 21
|
||||
f 21 11 22
|
||||
f 22 11 23
|
||||
f 23 11 24
|
||||
f 24 11 25
|
||||
f 25 11 26
|
||||
f 26 11 27
|
||||
f 27 11 28
|
||||
f 28 11 29
|
||||
f 29 11 30
|
||||
f 30 11 31
|
||||
f 31 11 32
|
||||
f 32 11 33
|
||||
f 33 11 34
|
||||
f 34 11 2
|
125
examples/common/meshes/convexmesh.obj
Normal file
|
@ -0,0 +1,125 @@
|
|||
# Blender v2.66 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
v 0.000000 -1.000000 0.000000
|
||||
v 0.723607 -0.447220 0.525725
|
||||
v -0.276388 -0.447220 0.850649
|
||||
v -0.894426 -0.447216 0.000000
|
||||
v -0.276388 -0.447220 -0.850649
|
||||
v 0.723607 -0.447220 -0.525725
|
||||
v 0.276388 0.447220 0.850649
|
||||
v -0.723607 0.447220 0.525725
|
||||
v -0.723607 0.447220 -0.525725
|
||||
v 0.276388 0.447220 -0.850649
|
||||
v 0.894426 0.447216 0.000000
|
||||
v 0.000000 1.000000 0.000000
|
||||
v 0.425323 -0.850654 0.309011
|
||||
v 0.262869 -0.525738 0.809012
|
||||
v -0.162456 -0.850654 0.499995
|
||||
v 0.425323 -0.850654 -0.309011
|
||||
v 0.850648 -0.525736 0.000000
|
||||
v -0.688189 -0.525736 0.499997
|
||||
v -0.525730 -0.850652 0.000000
|
||||
v -0.688189 -0.525736 -0.499997
|
||||
v -0.162456 -0.850654 -0.499995
|
||||
v 0.262869 -0.525738 -0.809012
|
||||
v 0.951058 0.000000 -0.309013
|
||||
v 0.951058 0.000000 0.309013
|
||||
v 0.587786 0.000000 0.809017
|
||||
v 0.000000 0.000000 1.000000
|
||||
v -0.587786 0.000000 0.809017
|
||||
v -0.951058 0.000000 0.309013
|
||||
v -0.951058 0.000000 -0.309013
|
||||
v -0.587786 0.000000 -0.809017
|
||||
v 0.000000 0.000000 -1.000000
|
||||
v 0.587786 0.000000 -0.809017
|
||||
v 0.688189 0.525736 0.499997
|
||||
v -0.262869 0.525738 0.809012
|
||||
v -0.850648 0.525736 0.000000
|
||||
v -0.262869 0.525738 -0.809012
|
||||
v 0.688189 0.525736 -0.499997
|
||||
v 0.525730 0.850652 0.000000
|
||||
v 0.162456 0.850654 0.499995
|
||||
v -0.425323 0.850654 0.309011
|
||||
v -0.425323 0.850654 -0.309011
|
||||
v 0.162456 0.850654 -0.499995
|
||||
s off
|
||||
f 1 13 15
|
||||
f 2 13 17
|
||||
f 1 15 19
|
||||
f 1 19 21
|
||||
f 1 21 16
|
||||
f 2 17 24
|
||||
f 3 14 26
|
||||
f 4 18 28
|
||||
f 5 20 30
|
||||
f 6 22 32
|
||||
f 2 24 25
|
||||
f 3 26 27
|
||||
f 4 28 29
|
||||
f 5 30 31
|
||||
f 6 32 23
|
||||
f 7 33 39
|
||||
f 8 34 40
|
||||
f 9 35 41
|
||||
f 10 36 42
|
||||
f 11 37 38
|
||||
f 15 14 3
|
||||
f 15 13 14
|
||||
f 13 2 14
|
||||
f 17 16 6
|
||||
f 17 13 16
|
||||
f 13 1 16
|
||||
f 19 18 4
|
||||
f 19 15 18
|
||||
f 15 3 18
|
||||
f 21 20 5
|
||||
f 21 19 20
|
||||
f 19 4 20
|
||||
f 16 22 6
|
||||
f 16 21 22
|
||||
f 21 5 22
|
||||
f 24 23 11
|
||||
f 24 17 23
|
||||
f 17 6 23
|
||||
f 26 25 7
|
||||
f 26 14 25
|
||||
f 14 2 25
|
||||
f 28 27 8
|
||||
f 28 18 27
|
||||
f 18 3 27
|
||||
f 30 29 9
|
||||
f 30 20 29
|
||||
f 20 4 29
|
||||
f 32 31 10
|
||||
f 32 22 31
|
||||
f 22 5 31
|
||||
f 25 33 7
|
||||
f 25 24 33
|
||||
f 24 11 33
|
||||
f 27 34 8
|
||||
f 27 26 34
|
||||
f 26 7 34
|
||||
f 29 35 9
|
||||
f 29 28 35
|
||||
f 28 8 35
|
||||
f 31 36 10
|
||||
f 31 30 36
|
||||
f 30 9 36
|
||||
f 23 37 11
|
||||
f 23 32 37
|
||||
f 32 10 37
|
||||
f 39 38 12
|
||||
f 39 33 38
|
||||
f 33 11 38
|
||||
f 40 39 12
|
||||
f 40 34 39
|
||||
f 34 7 39
|
||||
f 41 40 12
|
||||
f 41 35 40
|
||||
f 35 8 40
|
||||
f 42 41 12
|
||||
f 42 36 41
|
||||
f 36 9 41
|
||||
f 38 42 12
|
||||
f 38 37 42
|
||||
f 37 10 42
|
293
examples/common/meshes/cylinder.obj
Normal file
|
@ -0,0 +1,293 @@
|
|||
# Blender v2.66 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
v 0.000000 -0.500000 0.000000
|
||||
v 0.000000 0.500000 0.000000
|
||||
v 0.000000 -0.500000 -1.000000
|
||||
v 0.000000 0.500000 -1.000000
|
||||
v 0.195090 -0.500000 -0.980785
|
||||
v 0.195090 0.500000 -0.980785
|
||||
v 0.382683 -0.500000 -0.923880
|
||||
v 0.382683 0.500000 -0.923880
|
||||
v 0.555570 -0.500000 -0.831470
|
||||
v 0.555570 0.500000 -0.831470
|
||||
v 0.707107 -0.500000 -0.707107
|
||||
v 0.707107 0.500000 -0.707107
|
||||
v 0.831470 -0.500000 -0.555570
|
||||
v 0.831470 0.500000 -0.555570
|
||||
v 0.923880 -0.500000 -0.382683
|
||||
v 0.923880 0.500000 -0.382683
|
||||
v 0.980785 -0.500000 -0.195090
|
||||
v 0.980785 0.500000 -0.195090
|
||||
v 1.000000 -0.500000 -0.000000
|
||||
v 1.000000 0.500000 -0.000000
|
||||
v 0.980785 -0.500000 0.195090
|
||||
v 0.980785 0.500000 0.195090
|
||||
v 0.923880 -0.500000 0.382683
|
||||
v 0.923880 0.500000 0.382683
|
||||
v 0.831470 -0.500000 0.555570
|
||||
v 0.831470 0.500000 0.555570
|
||||
v 0.707107 -0.500000 0.707107
|
||||
v 0.707107 0.500000 0.707107
|
||||
v 0.555570 -0.500000 0.831470
|
||||
v 0.555570 0.500000 0.831470
|
||||
v 0.382683 -0.500000 0.923880
|
||||
v 0.382683 0.500000 0.923880
|
||||
v 0.195090 -0.500000 0.980785
|
||||
v 0.195090 0.500000 0.980785
|
||||
v -0.000000 -0.500000 1.000000
|
||||
v -0.000000 0.500000 1.000000
|
||||
v -0.195091 -0.500000 0.980785
|
||||
v -0.195091 0.500000 0.980785
|
||||
v -0.382684 -0.500000 0.923879
|
||||
v -0.382684 0.500000 0.923879
|
||||
v -0.555571 -0.500000 0.831469
|
||||
v -0.555571 0.500000 0.831469
|
||||
v -0.707107 -0.500000 0.707106
|
||||
v -0.707107 0.500000 0.707106
|
||||
v -0.831470 -0.500000 0.555570
|
||||
v -0.831470 0.500000 0.555570
|
||||
v -0.923880 -0.500000 0.382683
|
||||
v -0.923880 0.500000 0.382683
|
||||
v -0.980785 -0.500000 0.195089
|
||||
v -0.980785 0.500000 0.195089
|
||||
v -1.000000 -0.500000 -0.000001
|
||||
v -1.000000 0.500000 -0.000001
|
||||
v -0.980785 -0.500000 -0.195091
|
||||
v -0.980785 0.500000 -0.195091
|
||||
v -0.923879 -0.500000 -0.382684
|
||||
v -0.923879 0.500000 -0.382684
|
||||
v -0.831469 -0.500000 -0.555571
|
||||
v -0.831469 0.500000 -0.555571
|
||||
v -0.707106 -0.500000 -0.707108
|
||||
v -0.707106 0.500000 -0.707108
|
||||
v -0.555569 -0.500000 -0.831470
|
||||
v -0.555569 0.500000 -0.831470
|
||||
v -0.382682 -0.500000 -0.923880
|
||||
v -0.382682 0.500000 -0.923880
|
||||
v -0.195089 -0.500000 -0.980786
|
||||
v -0.195089 0.500000 -0.980786
|
||||
v 0.000000 0.000000 -1.000000
|
||||
v 0.195090 0.000000 -0.980785
|
||||
v 0.382683 0.000000 -0.923880
|
||||
v 0.555570 0.000000 -0.831470
|
||||
v 0.707107 0.000000 -0.707107
|
||||
v 0.831470 0.000000 -0.555570
|
||||
v 0.923880 0.000000 -0.382683
|
||||
v 0.980785 0.000000 -0.195090
|
||||
v 1.000000 0.000000 -0.000000
|
||||
v 0.980785 0.000000 0.195090
|
||||
v 0.923880 0.000000 0.382683
|
||||
v 0.831470 0.000000 0.555570
|
||||
v 0.707107 0.000000 0.707107
|
||||
v 0.555570 0.000000 0.831470
|
||||
v 0.382683 0.000000 0.923880
|
||||
v 0.195090 0.000000 0.980785
|
||||
v -0.000000 0.000000 1.000000
|
||||
v -0.195091 0.000000 0.980785
|
||||
v -0.382684 0.000000 0.923879
|
||||
v -0.555571 0.000000 0.831469
|
||||
v -0.707107 0.000000 0.707106
|
||||
v -0.831470 0.000000 0.555570
|
||||
v -0.923880 0.000000 0.382683
|
||||
v -0.980785 0.000000 0.195089
|
||||
v -1.000000 0.000000 -0.000001
|
||||
v -0.980785 0.000000 -0.195091
|
||||
v -0.923879 0.000000 -0.382684
|
||||
v -0.831469 0.000000 -0.555571
|
||||
v -0.707106 0.000000 -0.707108
|
||||
v -0.555569 0.000000 -0.831470
|
||||
v -0.382682 0.000000 -0.923880
|
||||
v -0.195089 0.000000 -0.980786
|
||||
s off
|
||||
f 1 3 5
|
||||
f 2 6 4
|
||||
f 67 4 6
|
||||
f 1 5 7
|
||||
f 2 8 6
|
||||
f 68 6 8
|
||||
f 1 7 9
|
||||
f 2 10 8
|
||||
f 69 8 10
|
||||
f 1 9 11
|
||||
f 2 12 10
|
||||
f 70 10 12
|
||||
f 1 11 13
|
||||
f 2 14 12
|
||||
f 71 12 14
|
||||
f 1 13 15
|
||||
f 2 16 14
|
||||
f 72 14 16
|
||||
f 1 15 17
|
||||
f 2 18 16
|
||||
f 73 16 18
|
||||
f 1 17 19
|
||||
f 2 20 18
|
||||
f 74 18 20
|
||||
f 1 19 21
|
||||
f 2 22 20
|
||||
f 75 20 22
|
||||
f 1 21 23
|
||||
f 2 24 22
|
||||
f 76 22 24
|
||||
f 1 23 25
|
||||
f 2 26 24
|
||||
f 77 24 26
|
||||
f 1 25 27
|
||||
f 2 28 26
|
||||
f 78 26 28
|
||||
f 1 27 29
|
||||
f 2 30 28
|
||||
f 79 28 30
|
||||
f 1 29 31
|
||||
f 2 32 30
|
||||
f 80 30 32
|
||||
f 1 31 33
|
||||
f 2 34 32
|
||||
f 81 32 34
|
||||
f 1 33 35
|
||||
f 2 36 34
|
||||
f 82 34 36
|
||||
f 1 35 37
|
||||
f 2 38 36
|
||||
f 83 36 38
|
||||
f 1 37 39
|
||||
f 2 40 38
|
||||
f 84 38 40
|
||||
f 1 39 41
|
||||
f 2 42 40
|
||||
f 85 40 42
|
||||
f 1 41 43
|
||||
f 2 44 42
|
||||
f 86 42 44
|
||||
f 1 43 45
|
||||
f 2 46 44
|
||||
f 87 44 46
|
||||
f 1 45 47
|
||||
f 2 48 46
|
||||
f 88 46 48
|
||||
f 1 47 49
|
||||
f 2 50 48
|
||||
f 89 48 50
|
||||
f 1 49 51
|
||||
f 2 52 50
|
||||
f 90 50 52
|
||||
f 1 51 53
|
||||
f 2 54 52
|
||||
f 91 52 54
|
||||
f 1 53 55
|
||||
f 2 56 54
|
||||
f 92 54 56
|
||||
f 1 55 57
|
||||
f 2 58 56
|
||||
f 93 56 58
|
||||
f 1 57 59
|
||||
f 2 60 58
|
||||
f 94 58 60
|
||||
f 1 59 61
|
||||
f 2 62 60
|
||||
f 95 60 62
|
||||
f 1 61 63
|
||||
f 2 64 62
|
||||
f 96 62 64
|
||||
f 1 63 65
|
||||
f 2 66 64
|
||||
f 97 64 66
|
||||
f 1 65 3
|
||||
f 2 4 66
|
||||
f 98 66 4
|
||||
f 3 67 68
|
||||
f 5 68 69
|
||||
f 7 69 70
|
||||
f 9 70 71
|
||||
f 11 71 72
|
||||
f 13 72 73
|
||||
f 15 73 74
|
||||
f 17 74 75
|
||||
f 19 75 76
|
||||
f 21 76 77
|
||||
f 23 77 78
|
||||
f 25 78 79
|
||||
f 27 79 80
|
||||
f 29 80 81
|
||||
f 31 81 82
|
||||
f 33 82 83
|
||||
f 35 83 84
|
||||
f 37 84 85
|
||||
f 39 85 86
|
||||
f 41 86 87
|
||||
f 43 87 88
|
||||
f 45 88 89
|
||||
f 47 89 90
|
||||
f 49 90 91
|
||||
f 51 91 92
|
||||
f 53 92 93
|
||||
f 55 93 94
|
||||
f 57 94 95
|
||||
f 59 95 96
|
||||
f 61 96 97
|
||||
f 63 97 98
|
||||
f 65 98 67
|
||||
f 86 85 42
|
||||
f 87 86 44
|
||||
f 88 87 46
|
||||
f 43 41 87
|
||||
f 45 43 88
|
||||
f 80 79 30
|
||||
f 81 80 32
|
||||
f 82 81 34
|
||||
f 83 82 36
|
||||
f 84 83 38
|
||||
f 85 84 40
|
||||
f 29 27 80
|
||||
f 31 29 81
|
||||
f 33 31 82
|
||||
f 35 33 83
|
||||
f 37 35 84
|
||||
f 39 37 85
|
||||
f 41 39 86
|
||||
f 68 67 6
|
||||
f 69 68 8
|
||||
f 70 69 10
|
||||
f 71 70 12
|
||||
f 72 71 14
|
||||
f 73 72 16
|
||||
f 74 73 18
|
||||
f 75 74 20
|
||||
f 76 75 22
|
||||
f 77 76 24
|
||||
f 78 77 26
|
||||
f 79 78 28
|
||||
f 89 88 48
|
||||
f 90 89 50
|
||||
f 91 90 52
|
||||
f 92 91 54
|
||||
f 93 92 56
|
||||
f 94 93 58
|
||||
f 95 94 60
|
||||
f 96 95 62
|
||||
f 97 96 64
|
||||
f 98 97 66
|
||||
f 67 98 4
|
||||
f 5 3 68
|
||||
f 7 5 69
|
||||
f 9 7 70
|
||||
f 11 9 71
|
||||
f 13 11 72
|
||||
f 15 13 73
|
||||
f 17 15 74
|
||||
f 19 17 75
|
||||
f 21 19 76
|
||||
f 23 21 77
|
||||
f 25 23 78
|
||||
f 27 25 79
|
||||
f 47 45 89
|
||||
f 49 47 90
|
||||
f 51 49 91
|
||||
f 53 51 92
|
||||
f 55 53 93
|
||||
f 57 55 94
|
||||
f 59 57 95
|
||||
f 61 59 96
|
||||
f 63 61 97
|
||||
f 65 63 98
|
||||
f 3 65 67
|
997
examples/common/meshes/sphere.obj
Normal file
|
@ -0,0 +1,997 @@
|
|||
# Blender v2.66 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
v -0.195090 0.980785 0.000000
|
||||
v -0.382683 0.923880 0.000000
|
||||
v -0.555570 0.831470 0.000000
|
||||
v -0.707107 0.707107 0.000000
|
||||
v -0.831470 0.555570 0.000000
|
||||
v -0.923880 0.382683 0.000000
|
||||
v -0.980785 0.195090 0.000000
|
||||
v -1.000000 0.000000 0.000000
|
||||
v -0.980785 -0.195090 0.000000
|
||||
v -0.923880 -0.382683 0.000000
|
||||
v -0.831470 -0.555570 0.000000
|
||||
v -0.707107 -0.707107 0.000000
|
||||
v -0.555570 -0.831470 0.000000
|
||||
v -0.382683 -0.923880 0.000000
|
||||
v -0.195090 -0.980785 0.000000
|
||||
v -0.191342 0.980785 -0.038060
|
||||
v -0.375330 0.923880 -0.074658
|
||||
v -0.544895 0.831470 -0.108386
|
||||
v -0.693520 0.707107 -0.137950
|
||||
v -0.815493 0.555570 -0.162212
|
||||
v -0.906127 0.382683 -0.180240
|
||||
v -0.961940 0.195090 -0.191342
|
||||
v -0.980785 0.000000 -0.195090
|
||||
v -0.961940 -0.195090 -0.191342
|
||||
v -0.906127 -0.382683 -0.180240
|
||||
v -0.815493 -0.555570 -0.162212
|
||||
v -0.693520 -0.707107 -0.137950
|
||||
v -0.544895 -0.831470 -0.108386
|
||||
v -0.375330 -0.923880 -0.074658
|
||||
v -0.191341 -0.980785 -0.038060
|
||||
v -0.180240 0.980785 -0.074658
|
||||
v -0.353553 0.923880 -0.146447
|
||||
v -0.513280 0.831470 -0.212608
|
||||
v -0.653281 0.707107 -0.270598
|
||||
v -0.768178 0.555570 -0.318190
|
||||
v -0.853553 0.382683 -0.353553
|
||||
v -0.906127 0.195090 -0.375330
|
||||
v -0.923880 0.000000 -0.382684
|
||||
v -0.906127 -0.195090 -0.375330
|
||||
v -0.853553 -0.382683 -0.353554
|
||||
v -0.768178 -0.555570 -0.318190
|
||||
v -0.653281 -0.707107 -0.270598
|
||||
v -0.513280 -0.831470 -0.212608
|
||||
v -0.353553 -0.923880 -0.146447
|
||||
v -0.180240 -0.980785 -0.074658
|
||||
v -0.162212 0.980785 -0.108387
|
||||
v -0.318190 0.923880 -0.212608
|
||||
v -0.461940 0.831470 -0.308658
|
||||
v -0.587938 0.707107 -0.392848
|
||||
v -0.691342 0.555570 -0.461940
|
||||
v -0.768178 0.382683 -0.513280
|
||||
v -0.815493 0.195090 -0.544895
|
||||
v -0.831470 0.000000 -0.555570
|
||||
v -0.815493 -0.195090 -0.544895
|
||||
v -0.768178 -0.382683 -0.513280
|
||||
v -0.691342 -0.555570 -0.461940
|
||||
v -0.587938 -0.707107 -0.392848
|
||||
v -0.461940 -0.831470 -0.308658
|
||||
v -0.318189 -0.923880 -0.212608
|
||||
v -0.162211 -0.980785 -0.108386
|
||||
v -0.137950 0.980785 -0.137950
|
||||
v -0.270598 0.923880 -0.270598
|
||||
v -0.392847 0.831470 -0.392848
|
||||
v -0.500000 0.707107 -0.500000
|
||||
v -0.587938 0.555570 -0.587938
|
||||
v -0.653281 0.382683 -0.653282
|
||||
v -0.693520 0.195090 -0.693520
|
||||
v -0.707107 0.000000 -0.707107
|
||||
v -0.693520 -0.195090 -0.693520
|
||||
v -0.653281 -0.382683 -0.653282
|
||||
v -0.587938 -0.555570 -0.587938
|
||||
v -0.500000 -0.707107 -0.500000
|
||||
v -0.392847 -0.831470 -0.392848
|
||||
v -0.270598 -0.923880 -0.270598
|
||||
v -0.137949 -0.980785 -0.137950
|
||||
v -0.108386 0.980785 -0.162212
|
||||
v -0.212607 0.923880 -0.318190
|
||||
v -0.308658 0.831470 -0.461940
|
||||
v -0.392847 0.707107 -0.587938
|
||||
v -0.461939 0.555570 -0.691342
|
||||
v -0.513280 0.382683 -0.768178
|
||||
v -0.544895 0.195090 -0.815493
|
||||
v -0.555570 0.000000 -0.831470
|
||||
v -0.544895 -0.195090 -0.815493
|
||||
v -0.513280 -0.382683 -0.768178
|
||||
v -0.461939 -0.555570 -0.691342
|
||||
v -0.392847 -0.707107 -0.587938
|
||||
v -0.308658 -0.831470 -0.461940
|
||||
v -0.212607 -0.923880 -0.318190
|
||||
v -0.108386 -0.980785 -0.162212
|
||||
v -0.074658 0.980785 -0.180240
|
||||
v -0.146446 0.923880 -0.353554
|
||||
v -0.212607 0.831470 -0.513280
|
||||
v -0.270598 0.707107 -0.653282
|
||||
v -0.318189 0.555570 -0.768178
|
||||
v -0.353553 0.382683 -0.853554
|
||||
v -0.375330 0.195090 -0.906128
|
||||
v -0.382683 0.000000 -0.923880
|
||||
v -0.375330 -0.195090 -0.906128
|
||||
v -0.353553 -0.382683 -0.853554
|
||||
v -0.318189 -0.555570 -0.768178
|
||||
v -0.270598 -0.707107 -0.653282
|
||||
v -0.212607 -0.831470 -0.513280
|
||||
v -0.146446 -0.923880 -0.353554
|
||||
v -0.074658 -0.980785 -0.180240
|
||||
v -0.038060 0.980785 -0.191342
|
||||
v -0.074658 0.923880 -0.375331
|
||||
v -0.108386 0.831470 -0.544895
|
||||
v -0.137949 0.707107 -0.693520
|
||||
v -0.162211 0.555570 -0.815493
|
||||
v -0.180240 0.382683 -0.906128
|
||||
v -0.191341 0.195090 -0.961940
|
||||
v -0.195090 0.000000 -0.980785
|
||||
v -0.191341 -0.195090 -0.961940
|
||||
v -0.180240 -0.382683 -0.906128
|
||||
v -0.162211 -0.555570 -0.815493
|
||||
v -0.137949 -0.707107 -0.693520
|
||||
v -0.108386 -0.831470 -0.544895
|
||||
v -0.074658 -0.923880 -0.375330
|
||||
v -0.038060 -0.980785 -0.191342
|
||||
v 0.000000 0.980785 -0.195091
|
||||
v 0.000000 0.923880 -0.382684
|
||||
v 0.000000 0.831470 -0.555570
|
||||
v 0.000000 0.707107 -0.707107
|
||||
v 0.000000 0.555570 -0.831470
|
||||
v 0.000000 0.382683 -0.923880
|
||||
v 0.000000 0.195090 -0.980785
|
||||
v 0.000000 0.000000 -1.000000
|
||||
v 0.000000 -0.195090 -0.980785
|
||||
v 0.000000 -0.382683 -0.923880
|
||||
v 0.000000 -0.555570 -0.831470
|
||||
v 0.000000 -0.707107 -0.707107
|
||||
v 0.000000 -0.831470 -0.555570
|
||||
v 0.000000 -0.923880 -0.382684
|
||||
v 0.000000 -0.980785 -0.195090
|
||||
v 0.038061 0.980785 -0.191342
|
||||
v 0.074658 0.923880 -0.375330
|
||||
v 0.108387 0.831470 -0.544895
|
||||
v 0.137950 0.707107 -0.693520
|
||||
v 0.162212 0.555570 -0.815493
|
||||
v 0.180240 0.382683 -0.906128
|
||||
v 0.191342 0.195090 -0.961940
|
||||
v 0.195091 0.000000 -0.980785
|
||||
v 0.191342 -0.195090 -0.961940
|
||||
v 0.180240 -0.382683 -0.906128
|
||||
v 0.162212 -0.555570 -0.815493
|
||||
v 0.137950 -0.707107 -0.693520
|
||||
v 0.108387 -0.831470 -0.544895
|
||||
v 0.074658 -0.923880 -0.375330
|
||||
v 0.038061 -0.980785 -0.191342
|
||||
v 0.074658 0.980785 -0.180240
|
||||
v 0.146447 0.923880 -0.353554
|
||||
v 0.212608 0.831470 -0.513280
|
||||
v 0.270599 0.707107 -0.653282
|
||||
v 0.318190 0.555570 -0.768178
|
||||
v 0.353554 0.382683 -0.853553
|
||||
v 0.375331 0.195090 -0.906127
|
||||
v 0.382684 0.000000 -0.923880
|
||||
v 0.375331 -0.195090 -0.906127
|
||||
v 0.353554 -0.382683 -0.853554
|
||||
v 0.318190 -0.555570 -0.768178
|
||||
v 0.270599 -0.707107 -0.653282
|
||||
v 0.212608 -0.831470 -0.513280
|
||||
v 0.146447 -0.923880 -0.353553
|
||||
v 0.074658 -0.980785 -0.180240
|
||||
v 0.108387 0.980785 -0.162212
|
||||
v 0.212608 0.923880 -0.318190
|
||||
v 0.308659 0.831470 -0.461940
|
||||
v 0.392848 0.707107 -0.587938
|
||||
v 0.461940 0.555570 -0.691342
|
||||
v 0.513280 0.382683 -0.768178
|
||||
v 0.544895 0.195090 -0.815493
|
||||
v 0.555571 0.000000 -0.831470
|
||||
v 0.544895 -0.195090 -0.815493
|
||||
v 0.513280 -0.382683 -0.768178
|
||||
v 0.461940 -0.555570 -0.691342
|
||||
v 0.392848 -0.707107 -0.587938
|
||||
v 0.308659 -0.831470 -0.461940
|
||||
v 0.212608 -0.923880 -0.318190
|
||||
v 0.108387 -0.980785 -0.162212
|
||||
v 0.137950 0.980785 -0.137950
|
||||
v 0.270599 0.923880 -0.270598
|
||||
v 0.392848 0.831470 -0.392848
|
||||
v 0.500000 0.707107 -0.500000
|
||||
v 0.587938 0.555570 -0.587938
|
||||
v 0.653282 0.382683 -0.653281
|
||||
v 0.693520 0.195090 -0.693520
|
||||
v 0.707107 0.000000 -0.707107
|
||||
v 0.693520 -0.195090 -0.693520
|
||||
v 0.653282 -0.382683 -0.653282
|
||||
v 0.587938 -0.555570 -0.587938
|
||||
v 0.500000 -0.707107 -0.500000
|
||||
v 0.392848 -0.831470 -0.392847
|
||||
v 0.270598 -0.923880 -0.270598
|
||||
v 0.137950 -0.980785 -0.137950
|
||||
v 0.162212 0.980785 -0.108386
|
||||
v 0.318190 0.923880 -0.212608
|
||||
v 0.461940 0.831470 -0.308658
|
||||
v 0.587938 0.707107 -0.392847
|
||||
v 0.691342 0.555570 -0.461940
|
||||
v 0.768178 0.382683 -0.513280
|
||||
v 0.815493 0.195090 -0.544895
|
||||
v 0.831470 0.000000 -0.555570
|
||||
v 0.815493 -0.195090 -0.544895
|
||||
v 0.768178 -0.382683 -0.513280
|
||||
v 0.691342 -0.555570 -0.461940
|
||||
v 0.587938 -0.707107 -0.392847
|
||||
v 0.461940 -0.831470 -0.308658
|
||||
v 0.318190 -0.923880 -0.212608
|
||||
v 0.162212 -0.980785 -0.108386
|
||||
v 0.180240 0.980785 -0.074658
|
||||
v 0.353554 0.923880 -0.146447
|
||||
v 0.513280 0.831470 -0.212608
|
||||
v 0.653282 0.707107 -0.270598
|
||||
v 0.768178 0.555570 -0.318190
|
||||
v 0.853554 0.382683 -0.353553
|
||||
v 0.906128 0.195090 -0.375330
|
||||
v 0.923880 0.000000 -0.382683
|
||||
v 0.906128 -0.195090 -0.375330
|
||||
v 0.853554 -0.382683 -0.353553
|
||||
v 0.768178 -0.555570 -0.318190
|
||||
v 0.653282 -0.707107 -0.270598
|
||||
v 0.513280 -0.831470 -0.212607
|
||||
v 0.353554 -0.923880 -0.146447
|
||||
v 0.180240 -0.980785 -0.074658
|
||||
v 0.191342 0.980785 -0.038060
|
||||
v 0.375331 0.923880 -0.074658
|
||||
v 0.544896 0.831470 -0.108386
|
||||
v 0.693520 0.707107 -0.137950
|
||||
v 0.815493 0.555570 -0.162212
|
||||
v 0.906128 0.382683 -0.180240
|
||||
v 0.961940 0.195090 -0.191342
|
||||
v 0.980785 0.000000 -0.195090
|
||||
v 0.961940 -0.195090 -0.191342
|
||||
v 0.906128 -0.382683 -0.180240
|
||||
v 0.815493 -0.555570 -0.162212
|
||||
v 0.693520 -0.707107 -0.137950
|
||||
v 0.544895 -0.831470 -0.108386
|
||||
v 0.375331 -0.923880 -0.074658
|
||||
v 0.191342 -0.980785 -0.038060
|
||||
v 0.195091 0.980785 0.000000
|
||||
v 0.382684 0.923880 0.000000
|
||||
v 0.555571 0.831470 0.000000
|
||||
v 0.707107 0.707107 0.000000
|
||||
v 0.831470 0.555570 0.000000
|
||||
v 0.923880 0.382683 0.000000
|
||||
v 0.980785 0.195090 0.000000
|
||||
v 1.000000 0.000000 0.000000
|
||||
v 0.980785 -0.195090 0.000000
|
||||
v 0.923880 -0.382683 0.000000
|
||||
v 0.831470 -0.555570 0.000000
|
||||
v 0.707107 -0.707107 0.000000
|
||||
v 0.555571 -0.831470 0.000000
|
||||
v 0.382684 -0.923880 0.000000
|
||||
v 0.195091 -0.980785 0.000000
|
||||
v 0.191342 0.980785 0.038060
|
||||
v 0.375331 0.923880 0.074658
|
||||
v 0.544896 0.831470 0.108386
|
||||
v 0.693520 0.707107 0.137950
|
||||
v 0.815493 0.555570 0.162212
|
||||
v 0.906128 0.382683 0.180240
|
||||
v 0.961940 0.195090 0.191342
|
||||
v 0.980785 0.000000 0.195090
|
||||
v 0.961940 -0.195090 0.191342
|
||||
v 0.906128 -0.382683 0.180240
|
||||
v 0.815493 -0.555570 0.162212
|
||||
v 0.693520 -0.707107 0.137950
|
||||
v 0.544895 -0.831470 0.108386
|
||||
v 0.375331 -0.923880 0.074658
|
||||
v 0.191342 -0.980785 0.038060
|
||||
v 0.180240 0.980785 0.074658
|
||||
v 0.353554 0.923880 0.146447
|
||||
v 0.513280 0.831470 0.212608
|
||||
v 0.653282 0.707107 0.270598
|
||||
v 0.768178 0.555570 0.318190
|
||||
v 0.853554 0.382683 0.353554
|
||||
v 0.906128 0.195090 0.375330
|
||||
v 0.923880 0.000000 0.382683
|
||||
v 0.906128 -0.195090 0.375330
|
||||
v 0.853554 -0.382683 0.353553
|
||||
v 0.768178 -0.555570 0.318190
|
||||
v 0.653282 -0.707107 0.270598
|
||||
v 0.513280 -0.831470 0.212608
|
||||
v 0.353554 -0.923880 0.146447
|
||||
v 0.180240 -0.980785 0.074658
|
||||
v 0.162212 0.980785 0.108387
|
||||
v 0.318190 0.923880 0.212608
|
||||
v 0.461940 0.831470 0.308658
|
||||
v 0.587938 0.707107 0.392848
|
||||
v 0.691342 0.555570 0.461940
|
||||
v 0.768178 0.382683 0.513280
|
||||
v 0.815493 0.195090 0.544895
|
||||
v 0.831470 0.000000 0.555570
|
||||
v 0.815493 -0.195090 0.544895
|
||||
v 0.768178 -0.382683 0.513280
|
||||
v 0.691342 -0.555570 0.461940
|
||||
v 0.587938 -0.707107 0.392848
|
||||
v 0.461940 -0.831470 0.308658
|
||||
v 0.318190 -0.923880 0.212608
|
||||
v 0.162212 -0.980785 0.108386
|
||||
v 0.137950 0.980785 0.137950
|
||||
v 0.270598 0.923880 0.270598
|
||||
v 0.392848 0.831470 0.392848
|
||||
v 0.500000 0.707107 0.500000
|
||||
v 0.587938 0.555570 0.587938
|
||||
v 0.653282 0.382683 0.653282
|
||||
v 0.693520 0.195090 0.693520
|
||||
v 0.707107 0.000000 0.707107
|
||||
v 0.693520 -0.195090 0.693520
|
||||
v 0.653282 -0.382683 0.653282
|
||||
v 0.587938 -0.555570 0.587938
|
||||
v 0.500000 -0.707107 0.500000
|
||||
v 0.392848 -0.831470 0.392848
|
||||
v 0.270598 -0.923880 0.270598
|
||||
v 0.137950 -0.980785 0.137950
|
||||
v 0.108387 0.980785 0.162212
|
||||
v 0.212608 0.923880 0.318190
|
||||
v 0.308659 0.831470 0.461940
|
||||
v 0.392848 0.707107 0.587938
|
||||
v 0.461940 0.555570 0.691342
|
||||
v 0.513280 0.382683 0.768178
|
||||
v 0.544895 0.195090 0.815493
|
||||
v 0.555570 0.000000 0.831469
|
||||
v 0.544895 -0.195090 0.815493
|
||||
v 0.513280 -0.382683 0.768178
|
||||
v 0.461940 -0.555570 0.691342
|
||||
v 0.392848 -0.707107 0.587938
|
||||
v 0.308659 -0.831470 0.461940
|
||||
v 0.212608 -0.923880 0.318190
|
||||
v 0.108387 -0.980785 0.162212
|
||||
v 0.000000 -1.000000 0.000000
|
||||
v 0.074658 0.980785 0.180240
|
||||
v 0.146447 0.923880 0.353554
|
||||
v 0.212608 0.831470 0.513280
|
||||
v 0.270598 0.707107 0.653281
|
||||
v 0.318190 0.555570 0.768178
|
||||
v 0.353554 0.382683 0.853553
|
||||
v 0.375330 0.195090 0.906127
|
||||
v 0.382683 0.000000 0.923879
|
||||
v 0.375330 -0.195090 0.906127
|
||||
v 0.353554 -0.382683 0.853553
|
||||
v 0.318190 -0.555570 0.768178
|
||||
v 0.270598 -0.707107 0.653281
|
||||
v 0.212608 -0.831470 0.513280
|
||||
v 0.146447 -0.923880 0.353553
|
||||
v 0.074658 -0.980785 0.180240
|
||||
v 0.038061 0.980785 0.191342
|
||||
v 0.074658 0.923880 0.375330
|
||||
v 0.108387 0.831470 0.544895
|
||||
v 0.137950 0.707107 0.693520
|
||||
v 0.162212 0.555570 0.815493
|
||||
v 0.180240 0.382683 0.906127
|
||||
v 0.191342 0.195090 0.961940
|
||||
v 0.195090 0.000000 0.980785
|
||||
v 0.191342 -0.195090 0.961940
|
||||
v 0.180240 -0.382683 0.906128
|
||||
v 0.162212 -0.555570 0.815493
|
||||
v 0.137950 -0.707107 0.693520
|
||||
v 0.108387 -0.831470 0.544895
|
||||
v 0.074658 -0.923880 0.375330
|
||||
v 0.038061 -0.980785 0.191342
|
||||
v 0.000000 0.980785 0.195090
|
||||
v 0.000000 0.923880 0.382684
|
||||
v 0.000000 0.831470 0.555570
|
||||
v 0.000000 0.707107 0.707107
|
||||
v 0.000000 0.555570 0.831469
|
||||
v 0.000000 0.382683 0.923879
|
||||
v 0.000000 0.195090 0.980785
|
||||
v 0.000000 0.000000 1.000000
|
||||
v 0.000000 -0.195090 0.980785
|
||||
v 0.000000 -0.382683 0.923880
|
||||
v 0.000000 -0.555570 0.831469
|
||||
v 0.000000 -0.707107 0.707107
|
||||
v 0.000000 -0.831470 0.555570
|
||||
v 0.000000 -0.923880 0.382683
|
||||
v 0.000000 -0.980785 0.195090
|
||||
v -0.038060 0.980785 0.191342
|
||||
v -0.074658 0.923880 0.375330
|
||||
v -0.108386 0.831470 0.544895
|
||||
v -0.137949 0.707107 0.693520
|
||||
v -0.162211 0.555570 0.815493
|
||||
v -0.180240 0.382683 0.906127
|
||||
v -0.191342 0.195090 0.961939
|
||||
v -0.195090 0.000000 0.980785
|
||||
v -0.191342 -0.195090 0.961939
|
||||
v -0.180240 -0.382683 0.906127
|
||||
v -0.162211 -0.555570 0.815493
|
||||
v -0.137949 -0.707107 0.693520
|
||||
v -0.108386 -0.831470 0.544895
|
||||
v -0.074658 -0.923880 0.375330
|
||||
v -0.038060 -0.980785 0.191342
|
||||
v -0.074658 0.980785 0.180240
|
||||
v -0.146446 0.923880 0.353553
|
||||
v -0.212607 0.831470 0.513280
|
||||
v -0.270598 0.707107 0.653281
|
||||
v -0.318189 0.555570 0.768177
|
||||
v -0.353553 0.382683 0.853553
|
||||
v -0.375330 0.195090 0.906127
|
||||
v -0.382683 0.000000 0.923879
|
||||
v -0.375330 -0.195090 0.906127
|
||||
v -0.353553 -0.382683 0.853553
|
||||
v -0.318189 -0.555570 0.768177
|
||||
v -0.270598 -0.707107 0.653281
|
||||
v -0.212607 -0.831470 0.513280
|
||||
v -0.146446 -0.923880 0.353553
|
||||
v -0.074657 -0.980785 0.180240
|
||||
v -0.108386 0.980785 0.162212
|
||||
v -0.212607 0.923880 0.318190
|
||||
v -0.308658 0.831470 0.461940
|
||||
v -0.392847 0.707107 0.587938
|
||||
v -0.461939 0.555570 0.691341
|
||||
v -0.513280 0.382683 0.768178
|
||||
v -0.544895 0.195090 0.815493
|
||||
v -0.555570 0.000000 0.831469
|
||||
v -0.544895 -0.195090 0.815493
|
||||
v -0.513280 -0.382683 0.768178
|
||||
v -0.461939 -0.555570 0.691341
|
||||
v -0.392847 -0.707107 0.587938
|
||||
v -0.308658 -0.831470 0.461940
|
||||
v -0.212607 -0.923880 0.318190
|
||||
v -0.108386 -0.980785 0.162212
|
||||
v -0.137949 0.980785 0.137950
|
||||
v -0.270598 0.923880 0.270598
|
||||
v -0.392847 0.831470 0.392847
|
||||
v -0.500000 0.707107 0.500000
|
||||
v -0.587937 0.555570 0.587937
|
||||
v -0.653281 0.382683 0.653281
|
||||
v -0.693519 0.195090 0.693519
|
||||
v -0.707106 0.000000 0.707106
|
||||
v -0.693519 -0.195090 0.693519
|
||||
v -0.653281 -0.382683 0.653281
|
||||
v -0.587937 -0.555570 0.587937
|
||||
v -0.500000 -0.707107 0.500000
|
||||
v -0.392847 -0.831470 0.392847
|
||||
v -0.270598 -0.923880 0.270598
|
||||
v -0.137949 -0.980785 0.137950
|
||||
v 0.000000 1.000000 0.000000
|
||||
v -0.162211 0.980785 0.108386
|
||||
v -0.318189 0.923880 0.212608
|
||||
v -0.461939 0.831470 0.308658
|
||||
v -0.587937 0.707107 0.392847
|
||||
v -0.691341 0.555570 0.461939
|
||||
v -0.768177 0.382683 0.513280
|
||||
v -0.815493 0.195090 0.544895
|
||||
v -0.831469 0.000000 0.555570
|
||||
v -0.815493 -0.195090 0.544895
|
||||
v -0.768178 -0.382683 0.513280
|
||||
v -0.691341 -0.555570 0.461939
|
||||
v -0.587937 -0.707107 0.392847
|
||||
v -0.461939 -0.831470 0.308658
|
||||
v -0.318189 -0.923880 0.212608
|
||||
v -0.162211 -0.980785 0.108386
|
||||
v -0.180240 0.980785 0.074658
|
||||
v -0.353553 0.923880 0.146447
|
||||
v -0.513280 0.831470 0.212607
|
||||
v -0.653281 0.707107 0.270598
|
||||
v -0.768177 0.555570 0.318189
|
||||
v -0.853553 0.382683 0.353553
|
||||
v -0.906127 0.195090 0.375330
|
||||
v -0.923879 0.000000 0.382683
|
||||
v -0.906127 -0.195090 0.375330
|
||||
v -0.853553 -0.382683 0.353553
|
||||
v -0.768177 -0.555570 0.318189
|
||||
v -0.653281 -0.707107 0.270598
|
||||
v -0.513280 -0.831470 0.212607
|
||||
v -0.353553 -0.923880 0.146447
|
||||
v -0.180240 -0.980785 0.074658
|
||||
v -0.191341 0.980785 0.038060
|
||||
v -0.375330 0.923880 0.074658
|
||||
v -0.544895 0.831470 0.108386
|
||||
v -0.693520 0.707107 0.137950
|
||||
v -0.815492 0.555570 0.162211
|
||||
v -0.906127 0.382683 0.180240
|
||||
v -0.961939 0.195090 0.191341
|
||||
v -0.980784 0.000000 0.195090
|
||||
v -0.961939 -0.195090 0.191341
|
||||
v -0.906127 -0.382683 0.180240
|
||||
v -0.815492 -0.555570 0.162211
|
||||
v -0.693520 -0.707107 0.137950
|
||||
v -0.544895 -0.831470 0.108386
|
||||
v -0.375330 -0.923880 0.074658
|
||||
v -0.191341 -0.980785 0.038060
|
||||
s off
|
||||
f 13 12 27 28
|
||||
f 7 6 21 22
|
||||
f 14 13 28 29
|
||||
f 8 7 22 23
|
||||
f 2 1 16 17
|
||||
f 15 14 29 30
|
||||
f 9 8 23 24
|
||||
f 3 2 17 18
|
||||
f 10 9 24 25
|
||||
f 4 3 18 19
|
||||
f 11 10 25 26
|
||||
f 5 4 19 20
|
||||
f 12 11 26 27
|
||||
f 6 5 20 21
|
||||
f 30 29 44 45
|
||||
f 24 23 38 39
|
||||
f 18 17 32 33
|
||||
f 25 24 39 40
|
||||
f 19 18 33 34
|
||||
f 26 25 40 41
|
||||
f 20 19 34 35
|
||||
f 27 26 41 42
|
||||
f 21 20 35 36
|
||||
f 28 27 42 43
|
||||
f 22 21 36 37
|
||||
f 29 28 43 44
|
||||
f 23 22 37 38
|
||||
f 17 16 31 32
|
||||
f 43 42 57 58
|
||||
f 37 36 51 52
|
||||
f 44 43 58 59
|
||||
f 38 37 52 53
|
||||
f 32 31 46 47
|
||||
f 45 44 59 60
|
||||
f 39 38 53 54
|
||||
f 33 32 47 48
|
||||
f 40 39 54 55
|
||||
f 34 33 48 49
|
||||
f 41 40 55 56
|
||||
f 35 34 49 50
|
||||
f 42 41 56 57
|
||||
f 36 35 50 51
|
||||
f 56 55 70 71
|
||||
f 50 49 64 65
|
||||
f 57 56 71 72
|
||||
f 51 50 65 66
|
||||
f 58 57 72 73
|
||||
f 52 51 66 67
|
||||
f 59 58 73 74
|
||||
f 53 52 67 68
|
||||
f 47 46 61 62
|
||||
f 60 59 74 75
|
||||
f 54 53 68 69
|
||||
f 48 47 62 63
|
||||
f 55 54 69 70
|
||||
f 49 48 63 64
|
||||
f 75 74 89 90
|
||||
f 69 68 83 84
|
||||
f 63 62 77 78
|
||||
f 70 69 84 85
|
||||
f 64 63 78 79
|
||||
f 71 70 85 86
|
||||
f 65 64 79 80
|
||||
f 72 71 86 87
|
||||
f 66 65 80 81
|
||||
f 73 72 87 88
|
||||
f 67 66 81 82
|
||||
f 74 73 88 89
|
||||
f 68 67 82 83
|
||||
f 62 61 76 77
|
||||
f 88 87 102 103
|
||||
f 82 81 96 97
|
||||
f 89 88 103 104
|
||||
f 83 82 97 98
|
||||
f 77 76 91 92
|
||||
f 90 89 104 105
|
||||
f 84 83 98 99
|
||||
f 78 77 92 93
|
||||
f 85 84 99 100
|
||||
f 79 78 93 94
|
||||
f 86 85 100 101
|
||||
f 80 79 94 95
|
||||
f 87 86 101 102
|
||||
f 81 80 95 96
|
||||
f 94 93 108 109
|
||||
f 101 100 115 116
|
||||
f 95 94 109 110
|
||||
f 102 101 116 117
|
||||
f 96 95 110 111
|
||||
f 103 102 117 118
|
||||
f 97 96 111 112
|
||||
f 104 103 118 119
|
||||
f 98 97 112 113
|
||||
f 92 91 106 107
|
||||
f 105 104 119 120
|
||||
f 99 98 113 114
|
||||
f 93 92 107 108
|
||||
f 100 99 114 115
|
||||
f 113 112 127 128
|
||||
f 107 106 121 122
|
||||
f 120 119 134 135
|
||||
f 114 113 128 129
|
||||
f 108 107 122 123
|
||||
f 115 114 129 130
|
||||
f 109 108 123 124
|
||||
f 116 115 130 131
|
||||
f 110 109 124 125
|
||||
f 117 116 131 132
|
||||
f 111 110 125 126
|
||||
f 118 117 132 133
|
||||
f 112 111 126 127
|
||||
f 119 118 133 134
|
||||
f 132 131 146 147
|
||||
f 126 125 140 141
|
||||
f 133 132 147 148
|
||||
f 127 126 141 142
|
||||
f 134 133 148 149
|
||||
f 128 127 142 143
|
||||
f 122 121 136 137
|
||||
f 135 134 149 150
|
||||
f 129 128 143 144
|
||||
f 123 122 137 138
|
||||
f 130 129 144 145
|
||||
f 124 123 138 139
|
||||
f 131 130 145 146
|
||||
f 125 124 139 140
|
||||
f 145 144 159 160
|
||||
f 139 138 153 154
|
||||
f 146 145 160 161
|
||||
f 140 139 154 155
|
||||
f 147 146 161 162
|
||||
f 141 140 155 156
|
||||
f 148 147 162 163
|
||||
f 142 141 156 157
|
||||
f 149 148 163 164
|
||||
f 143 142 157 158
|
||||
f 137 136 151 152
|
||||
f 150 149 164 165
|
||||
f 144 143 158 159
|
||||
f 138 137 152 153
|
||||
f 164 163 178 179
|
||||
f 158 157 172 173
|
||||
f 152 151 166 167
|
||||
f 165 164 179 180
|
||||
f 159 158 173 174
|
||||
f 153 152 167 168
|
||||
f 160 159 174 175
|
||||
f 154 153 168 169
|
||||
f 161 160 175 176
|
||||
f 155 154 169 170
|
||||
f 162 161 176 177
|
||||
f 156 155 170 171
|
||||
f 163 162 177 178
|
||||
f 157 156 171 172
|
||||
f 177 176 191 192
|
||||
f 171 170 185 186
|
||||
f 178 177 192 193
|
||||
f 172 171 186 187
|
||||
f 179 178 193 194
|
||||
f 173 172 187 188
|
||||
f 167 166 181 182
|
||||
f 180 179 194 195
|
||||
f 174 173 188 189
|
||||
f 168 167 182 183
|
||||
f 175 174 189 190
|
||||
f 169 168 183 184
|
||||
f 176 175 190 191
|
||||
f 170 169 184 185
|
||||
f 190 189 204 205
|
||||
f 184 183 198 199
|
||||
f 191 190 205 206
|
||||
f 185 184 199 200
|
||||
f 192 191 206 207
|
||||
f 186 185 200 201
|
||||
f 193 192 207 208
|
||||
f 187 186 201 202
|
||||
f 194 193 208 209
|
||||
f 188 187 202 203
|
||||
f 182 181 196 197
|
||||
f 195 194 209 210
|
||||
f 189 188 203 204
|
||||
f 183 182 197 198
|
||||
f 209 208 223 224
|
||||
f 203 202 217 218
|
||||
f 197 196 211 212
|
||||
f 210 209 224 225
|
||||
f 204 203 218 219
|
||||
f 198 197 212 213
|
||||
f 205 204 219 220
|
||||
f 199 198 213 214
|
||||
f 206 205 220 221
|
||||
f 200 199 214 215
|
||||
f 207 206 221 222
|
||||
f 201 200 215 216
|
||||
f 208 207 222 223
|
||||
f 202 201 216 217
|
||||
f 222 221 236 237
|
||||
f 216 215 230 231
|
||||
f 223 222 237 238
|
||||
f 217 216 231 232
|
||||
f 224 223 238 239
|
||||
f 218 217 232 233
|
||||
f 212 211 226 227
|
||||
f 225 224 239 240
|
||||
f 219 218 233 234
|
||||
f 213 212 227 228
|
||||
f 220 219 234 235
|
||||
f 214 213 228 229
|
||||
f 221 220 235 236
|
||||
f 215 214 229 230
|
||||
f 228 227 242 243
|
||||
f 235 234 249 250
|
||||
f 229 228 243 244
|
||||
f 236 235 250 251
|
||||
f 230 229 244 245
|
||||
f 237 236 251 252
|
||||
f 231 230 245 246
|
||||
f 238 237 252 253
|
||||
f 232 231 246 247
|
||||
f 239 238 253 254
|
||||
f 233 232 247 248
|
||||
f 227 226 241 242
|
||||
f 240 239 254 255
|
||||
f 234 233 248 249
|
||||
f 247 246 261 262
|
||||
f 254 253 268 269
|
||||
f 248 247 262 263
|
||||
f 242 241 256 257
|
||||
f 255 254 269 270
|
||||
f 249 248 263 264
|
||||
f 243 242 257 258
|
||||
f 250 249 264 265
|
||||
f 244 243 258 259
|
||||
f 251 250 265 266
|
||||
f 245 244 259 260
|
||||
f 252 251 266 267
|
||||
f 246 245 260 261
|
||||
f 253 252 267 268
|
||||
f 266 265 280 281
|
||||
f 260 259 274 275
|
||||
f 267 266 281 282
|
||||
f 261 260 275 276
|
||||
f 268 267 282 283
|
||||
f 262 261 276 277
|
||||
f 269 268 283 284
|
||||
f 263 262 277 278
|
||||
f 257 256 271 272
|
||||
f 270 269 284 285
|
||||
f 264 263 278 279
|
||||
f 258 257 272 273
|
||||
f 265 264 279 280
|
||||
f 259 258 273 274
|
||||
f 285 284 299 300
|
||||
f 279 278 293 294
|
||||
f 273 272 287 288
|
||||
f 280 279 294 295
|
||||
f 274 273 288 289
|
||||
f 281 280 295 296
|
||||
f 275 274 289 290
|
||||
f 282 281 296 297
|
||||
f 276 275 290 291
|
||||
f 283 282 297 298
|
||||
f 277 276 291 292
|
||||
f 284 283 298 299
|
||||
f 278 277 292 293
|
||||
f 272 271 286 287
|
||||
f 298 297 312 313
|
||||
f 292 291 306 307
|
||||
f 299 298 313 314
|
||||
f 293 292 307 308
|
||||
f 287 286 301 302
|
||||
f 300 299 314 315
|
||||
f 294 293 308 309
|
||||
f 288 287 302 303
|
||||
f 295 294 309 310
|
||||
f 289 288 303 304
|
||||
f 296 295 310 311
|
||||
f 290 289 304 305
|
||||
f 297 296 311 312
|
||||
f 291 290 305 306
|
||||
f 311 310 325 326
|
||||
f 305 304 319 320
|
||||
f 312 311 326 327
|
||||
f 306 305 320 321
|
||||
f 313 312 327 328
|
||||
f 307 306 321 322
|
||||
f 314 313 328 329
|
||||
f 308 307 322 323
|
||||
f 302 301 316 317
|
||||
f 315 314 329 330
|
||||
f 309 308 323 324
|
||||
f 303 302 317 318
|
||||
f 310 309 324 325
|
||||
f 304 303 318 319
|
||||
f 330 329 345 346
|
||||
f 324 323 339 340
|
||||
f 318 317 333 334
|
||||
f 325 324 340 341
|
||||
f 319 318 334 335
|
||||
f 326 325 341 342
|
||||
f 320 319 335 336
|
||||
f 327 326 342 343
|
||||
f 321 320 336 337
|
||||
f 328 327 343 344
|
||||
f 322 321 337 338
|
||||
f 329 328 344 345
|
||||
f 323 322 338 339
|
||||
f 317 316 332 333
|
||||
f 344 343 358 359
|
||||
f 338 337 352 353
|
||||
f 345 344 359 360
|
||||
f 339 338 353 354
|
||||
f 333 332 347 348
|
||||
f 346 345 360 361
|
||||
f 340 339 354 355
|
||||
f 334 333 348 349
|
||||
f 341 340 355 356
|
||||
f 335 334 349 350
|
||||
f 342 341 356 357
|
||||
f 336 335 350 351
|
||||
f 343 342 357 358
|
||||
f 337 336 351 352
|
||||
f 357 356 371 372
|
||||
f 351 350 365 366
|
||||
f 358 357 372 373
|
||||
f 352 351 366 367
|
||||
f 359 358 373 374
|
||||
f 353 352 367 368
|
||||
f 360 359 374 375
|
||||
f 354 353 368 369
|
||||
f 348 347 362 363
|
||||
f 361 360 375 376
|
||||
f 355 354 369 370
|
||||
f 349 348 363 364
|
||||
f 356 355 370 371
|
||||
f 350 349 364 365
|
||||
f 363 362 377 378
|
||||
f 376 375 390 391
|
||||
f 370 369 384 385
|
||||
f 364 363 378 379
|
||||
f 371 370 385 386
|
||||
f 365 364 379 380
|
||||
f 372 371 386 387
|
||||
f 366 365 380 381
|
||||
f 373 372 387 388
|
||||
f 367 366 381 382
|
||||
f 374 373 388 389
|
||||
f 368 367 382 383
|
||||
f 375 374 389 390
|
||||
f 369 368 383 384
|
||||
f 382 381 396 397
|
||||
f 389 388 403 404
|
||||
f 383 382 397 398
|
||||
f 390 389 404 405
|
||||
f 384 383 398 399
|
||||
f 378 377 392 393
|
||||
f 391 390 405 406
|
||||
f 385 384 399 400
|
||||
f 379 378 393 394
|
||||
f 386 385 400 401
|
||||
f 380 379 394 395
|
||||
f 387 386 401 402
|
||||
f 381 380 395 396
|
||||
f 388 387 402 403
|
||||
f 401 400 415 416
|
||||
f 395 394 409 410
|
||||
f 402 401 416 417
|
||||
f 396 395 410 411
|
||||
f 403 402 417 418
|
||||
f 397 396 411 412
|
||||
f 404 403 418 419
|
||||
f 398 397 412 413
|
||||
f 405 404 419 420
|
||||
f 399 398 413 414
|
||||
f 393 392 407 408
|
||||
f 406 405 420 421
|
||||
f 400 399 414 415
|
||||
f 394 393 408 409
|
||||
f 420 419 434 435
|
||||
f 414 413 428 429
|
||||
f 408 407 422 423
|
||||
f 421 420 435 436
|
||||
f 415 414 429 430
|
||||
f 409 408 423 424
|
||||
f 416 415 430 431
|
||||
f 410 409 424 425
|
||||
f 417 416 431 432
|
||||
f 411 410 425 426
|
||||
f 418 417 432 433
|
||||
f 412 411 426 427
|
||||
f 419 418 433 434
|
||||
f 413 412 427 428
|
||||
f 433 432 448 449
|
||||
f 427 426 442 443
|
||||
f 434 433 449 450
|
||||
f 428 427 443 444
|
||||
f 435 434 450 451
|
||||
f 429 428 444 445
|
||||
f 423 422 438 439
|
||||
f 436 435 451 452
|
||||
f 430 429 445 446
|
||||
f 424 423 439 440
|
||||
f 431 430 446 447
|
||||
f 425 424 440 441
|
||||
f 432 431 447 448
|
||||
f 426 425 441 442
|
||||
f 447 446 461 462
|
||||
f 441 440 455 456
|
||||
f 448 447 462 463
|
||||
f 442 441 456 457
|
||||
f 449 448 463 464
|
||||
f 443 442 457 458
|
||||
f 450 449 464 465
|
||||
f 444 443 458 459
|
||||
f 451 450 465 466
|
||||
f 445 444 459 460
|
||||
f 439 438 453 454
|
||||
f 452 451 466 467
|
||||
f 446 445 460 461
|
||||
f 440 439 454 455
|
||||
f 466 465 480 481
|
||||
f 460 459 474 475
|
||||
f 454 453 468 469
|
||||
f 467 466 481 482
|
||||
f 461 460 475 476
|
||||
f 455 454 469 470
|
||||
f 462 461 476 477
|
||||
f 456 455 470 471
|
||||
f 463 462 477 478
|
||||
f 457 456 471 472
|
||||
f 464 463 478 479
|
||||
f 458 457 472 473
|
||||
f 465 464 479 480
|
||||
f 459 458 473 474
|
||||
f 1 437 16
|
||||
f 331 15 30
|
||||
f 331 30 45
|
||||
f 16 437 31
|
||||
f 31 437 46
|
||||
f 331 45 60
|
||||
f 46 437 61
|
||||
f 331 60 75
|
||||
f 331 75 90
|
||||
f 61 437 76
|
||||
f 76 437 91
|
||||
f 331 90 105
|
||||
f 91 437 106
|
||||
f 331 105 120
|
||||
f 331 120 135
|
||||
f 106 437 121
|
||||
f 121 437 136
|
||||
f 331 135 150
|
||||
f 331 150 165
|
||||
f 136 437 151
|
||||
f 331 165 180
|
||||
f 151 437 166
|
||||
f 166 437 181
|
||||
f 331 180 195
|
||||
f 331 195 210
|
||||
f 181 437 196
|
||||
f 331 210 225
|
||||
f 196 437 211
|
||||
f 211 437 226
|
||||
f 331 225 240
|
||||
f 331 240 255
|
||||
f 226 437 241
|
||||
f 241 437 256
|
||||
f 331 255 270
|
||||
f 256 437 271
|
||||
f 331 270 285
|
||||
f 331 285 300
|
||||
f 271 437 286
|
||||
f 286 437 301
|
||||
f 331 300 315
|
||||
f 301 437 316
|
||||
f 331 315 330
|
||||
f 331 330 346
|
||||
f 316 437 332
|
||||
f 332 437 347
|
||||
f 331 346 361
|
||||
f 347 437 362
|
||||
f 331 361 376
|
||||
f 331 376 391
|
||||
f 362 437 377
|
||||
f 377 437 392
|
||||
f 331 391 406
|
||||
f 392 437 407
|
||||
f 331 406 421
|
||||
f 331 421 436
|
||||
f 407 437 422
|
||||
f 422 437 438
|
||||
f 331 436 452
|
||||
f 331 452 467
|
||||
f 438 437 453
|
||||
f 331 467 482
|
||||
f 453 437 468
|
||||
f 479 478 11 12
|
||||
f 473 472 5 6
|
||||
f 480 479 12 13
|
||||
f 474 473 6 7
|
||||
f 468 437 1
|
||||
f 481 480 13 14
|
||||
f 475 474 7 8
|
||||
f 469 468 1 2
|
||||
f 482 481 14 15
|
||||
f 476 475 8 9
|
||||
f 470 469 2 3
|
||||
f 331 482 15
|
||||
f 477 476 9 10
|
||||
f 471 470 3 4
|
||||
f 478 477 10 11
|
||||
f 472 471 4 5
|
109
examples/common/opengl-framework/CMakeLists.txt
Normal file
|
@ -0,0 +1,109 @@
|
|||
# Minimum cmake version required
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(OPENGLFRAMEWORK)
|
||||
|
||||
# Options
|
||||
OPTION(USE_JPEG_TEXTURES "Select this if you want to use jpeg textures (libjpeg required)" OFF)
|
||||
|
||||
# Where to find the module to find special packages/libraries
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
# Find OpenGL
|
||||
FIND_PACKAGE(OpenGL REQUIRED)
|
||||
IF(OPENGL_FOUND)
|
||||
MESSAGE("OpenGL found")
|
||||
ELSE()
|
||||
MESSAGE("OpenGL not found")
|
||||
ENDIF()
|
||||
|
||||
# Find the GLEW library
|
||||
FIND_PACKAGE(GLEW REQUIRED)
|
||||
IF(GLEW_FOUND)
|
||||
MESSAGE("GLEW found")
|
||||
ELSE()
|
||||
MESSAGE("GLEW not found")
|
||||
ENDIF()
|
||||
|
||||
# Find the GLUT/FREEGLUT library
|
||||
IF(APPLE)
|
||||
|
||||
# Find the GLUT library
|
||||
FIND_PACKAGE(GLUT REQUIRED)
|
||||
IF(GLUT_FOUND)
|
||||
MESSAGE("GLUT found")
|
||||
ELSE(GLUT_FOUND)
|
||||
MESSAGE(SEND_ERROR "GLUT not found")
|
||||
ENDIF(GLUT_FOUND)
|
||||
|
||||
ELSE(APPLE)
|
||||
|
||||
# Find the FREEGLUT library
|
||||
FIND_PACKAGE(FREEGLUT REQUIRED)
|
||||
IF(FREEGLUT_FOUND)
|
||||
MESSAGE("FREEGLUT found")
|
||||
ELSE(FREEGLUT_FOUND)
|
||||
MESSAGE(SEND_ERROR "FREEGLUT not found")
|
||||
ENDIF(FREEGLUT_FOUND)
|
||||
|
||||
ENDIF(APPLE)
|
||||
|
||||
# If the user wants to use JPEG textures
|
||||
IF(USE_JPEG_TEXTURES)
|
||||
|
||||
# Find the LIBJPEG library
|
||||
FIND_PACKAGE(JPEG REQUIRED)
|
||||
IF(JPEG_FOUND)
|
||||
MESSAGE("LIBJPEG found")
|
||||
ELSE()
|
||||
MESSAGE("LIBJPEG not found")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES(src ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_PATH} ${FREEGLUT_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ${JPEG_INCLUDE_DIR})
|
||||
|
||||
# Source files
|
||||
SET(OPENGL_FRAMEWORK_SOURCES
|
||||
"src/maths/Color.h"
|
||||
"src/maths/Matrix3.h"
|
||||
"src/maths/Matrix4.h"
|
||||
"src/maths/Vector2.h"
|
||||
"src/maths/Vector3.h"
|
||||
"src/maths/Vector4.h"
|
||||
"src/Camera.cpp"
|
||||
"src/Camera.h"
|
||||
"src/definitions.h"
|
||||
"src/FrameBufferObject.cpp"
|
||||
"src/FrameBufferObject.h"
|
||||
"src/GlutViewer.cpp"
|
||||
"src/GlutViewer.h"
|
||||
"src/Light.h"
|
||||
"src/Light.cpp"
|
||||
"src/Mesh.h"
|
||||
"src/Mesh.cpp"
|
||||
"src/MeshReaderWriter.h"
|
||||
"src/MeshReaderWriter.cpp"
|
||||
"src/Object3D.h"
|
||||
"src/Object3D.cpp"
|
||||
"src/openglframework.h"
|
||||
"src/Shader.h"
|
||||
"src/Shader.cpp"
|
||||
"src/Texture2D.h"
|
||||
"src/Texture2D.cpp"
|
||||
"src/TextureReaderWriter.h"
|
||||
"src/TextureReaderWriter.cpp"
|
||||
"src/VertexBufferObject.h"
|
||||
"src/VertexBufferObject.cpp"
|
||||
)
|
||||
|
||||
IF(USE_JPEG_TEXTURES)
|
||||
ADD_DEFINITIONS(-DUSE_JPEG_TEXTURE)
|
||||
ENDIF()
|
||||
|
||||
# Create the library
|
||||
ADD_LIBRARY (openglframework STATIC ${OPENGL_FRAMEWORK_SOURCES})
|
||||
|
||||
# Link with others libraries
|
||||
TARGET_LINK_LIBRARIES(openglframework ${GLEW_LIBRARIES} ${OPENGL_LIBRARY} ${FREEGLUT_LIBRARY} ${GLUT_LIBRARY})
|
32
examples/common/opengl-framework/cmake/FindFREEGLUT.cmake
Normal file
|
@ -0,0 +1,32 @@
|
|||
# This module is used to try to find the Freeglut library and include files
|
||||
|
||||
IF(WIN32)
|
||||
FIND_PATH(FREEGLUT_INCLUDE_DIR NAMES GL/freeglut.h)
|
||||
FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut freeglut_static
|
||||
PATHS ${OPENGL_LIBRARY_DIR})
|
||||
ELSE(WIN32)
|
||||
|
||||
IF(APPLE)
|
||||
# Do nothing, we do not want to use freeglut on Mac OS X
|
||||
ELSE(APPLE)
|
||||
FIND_PATH(FREEGLUT_INCLUDE_DIR GL/freeglut.h /usr/include/GL
|
||||
/usr/openwin/share/include
|
||||
/usr/openwin/include
|
||||
/opt/graphics/OpenGL/include
|
||||
/opt/graphics/OpenGL/contrib/libglut)
|
||||
|
||||
FIND_LIBRARY(FREEGLUT_LIBRARY NAMES glut freeglut freeglut_static PATHS /usr/openwin/lib)
|
||||
FIND_LIBRARY(Xi_LIBRARY Xi /usr/openwin/lib)
|
||||
FIND_LIBRARY(Xmu_LIBRARY Xmu /usr/openwin/lib)
|
||||
ENDIF(APPLE)
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEGLUT REQUIRED_VARS FREEGLUT_LIBRARY FREEGLUT_INCLUDE_DIR)
|
||||
|
||||
IF(FREEGLUT_FOUND)
|
||||
SET(FREEGLUT_LIBRARIES ${FREEGLUT_LIBRARY} ${Xi_LIBRARY} ${Xmu_LIBRARY})
|
||||
SET(FREEGLUT_LIBRARY ${FREEGLUT_LIBRARIES})
|
||||
ENDIF(FREEGLUT_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(FREEGLUT_INCLUDE_DIR FREEGLUT_LIBRARY Xi_LIBRARY Xmu_LIBRARY)
|
65
examples/common/opengl-framework/cmake/FindGLEW.cmake
Normal file
|
@ -0,0 +1,65 @@
|
|||
#
|
||||
# Try to find GLEW library and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# GLEW_FOUND
|
||||
# GLEW_INCLUDE_PATH
|
||||
# GLEW_LIBRARY
|
||||
#
|
||||
|
||||
IF (WIN32)
|
||||
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||
$ENV{PROGRAMFILES}/GLEW/include
|
||||
${GLEW_ROOT_DIR}/include
|
||||
DOC "The directory where GL/glew.h resides")
|
||||
|
||||
IF (NV_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES glew64 glew64s
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/GLEW/lib
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
|
||||
DOC "The GLEW library (64-bit)"
|
||||
)
|
||||
ELSE(NV_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES glew GLEW glew32 glew32s
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/GLEW/lib
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
|
||||
DOC "The GLEW library"
|
||||
)
|
||||
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
ELSE (WIN32)
|
||||
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/sw/include
|
||||
/opt/local/include
|
||||
${GLEW_ROOT_DIR}/include
|
||||
DOC "The directory where GL/glew.h resides")
|
||||
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES GLEW glew
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
${GLEW_ROOT_DIR}/lib
|
||||
DOC "The GLEW library")
|
||||
ENDIF (WIN32)
|
||||
|
||||
SET(GLEW_FOUND "NO")
|
||||
IF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY)
|
||||
SET(GLEW_LIBRARIES ${GLEW_LIBRARY})
|
||||
SET(GLEW_FOUND "YES")
|
||||
ENDIF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY)
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_PATH)
|
97
examples/common/opengl-framework/src/Camera.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
// Libraries
|
||||
#include "Camera.h"
|
||||
#include "definitions.h"
|
||||
#include <cmath>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Camera::Camera() : Object3D() {
|
||||
|
||||
// Set default values
|
||||
mFieldOfView = 45.0f;
|
||||
mSceneRadius = 1.0f;
|
||||
mNearPlane = 0.1f;
|
||||
mFarPlane = 10.0f;
|
||||
mWidth = 1;
|
||||
mHeight = 1;
|
||||
|
||||
// Update the projection matrix
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Camera::~Camera() {
|
||||
|
||||
}
|
||||
|
||||
// Update the projection matrix
|
||||
void Camera::updateProjectionMatrix() {
|
||||
|
||||
// Compute the aspect ratio
|
||||
float aspect = float(mWidth) / float(mHeight);
|
||||
|
||||
float top = mNearPlane * tan((mFieldOfView / 2.0f) * (float(PI) / 180.0f));
|
||||
float bottom = -top;
|
||||
float left = bottom * aspect;
|
||||
float right = top * aspect;
|
||||
|
||||
float fx = 2.0f * mNearPlane / (right - left);
|
||||
float fy = 2.0f * mNearPlane / (top - bottom);
|
||||
float fz = -(mFarPlane + mNearPlane) / (mFarPlane - mNearPlane);
|
||||
float fw = -2.0f * mFarPlane * mNearPlane / (mFarPlane - mNearPlane);
|
||||
|
||||
// Recompute the projection matrix
|
||||
mProjectionMatrix = Matrix4(fx, 0, 0, 0,
|
||||
0, fy, 0, 0,
|
||||
0, 0, fz, fw,
|
||||
0, 0, -1, 0);
|
||||
}
|
||||
|
||||
// Translate the camera go a given point using the dx, dy fraction
|
||||
void Camera::translateCamera(float dx, float dy, const Vector3& worldPoint) {
|
||||
|
||||
// Transform the world point into camera coordinates
|
||||
Vector3 pointCamera = mTransformMatrix.getInverse() * worldPoint;
|
||||
|
||||
// Get the depth
|
||||
float z = -pointCamera.z;
|
||||
|
||||
// Find the scaling of dx and dy from windows coordinates to near plane coordinates
|
||||
// and from there to camera coordinates at the object's depth
|
||||
float aspect = float(mWidth) / float(mHeight);
|
||||
float top = mNearPlane * tan(mFieldOfView * PI / 360.0f);
|
||||
float right = top * aspect;
|
||||
|
||||
// Translate the camera
|
||||
translateLocal(Vector3(2.0f * dx * right / mNearPlane * z,
|
||||
-2.0f * dy * top / mNearPlane * z,
|
||||
0.0f));
|
||||
}
|
181
examples/common/opengl-framework/src/Camera.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
// Libraries
|
||||
#include "Object3D.h"
|
||||
#include "definitions.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Camera
|
||||
class Camera : public Object3D {
|
||||
|
||||
protected :
|
||||
|
||||
// ------------------- Attributes ------------------- //
|
||||
|
||||
// Field of view
|
||||
float mFieldOfView;
|
||||
|
||||
// Radius of the scene
|
||||
float mSceneRadius;
|
||||
|
||||
// Near plane
|
||||
float mNearPlane;
|
||||
|
||||
// Far plane
|
||||
float mFarPlane;
|
||||
|
||||
// Width of the camera
|
||||
uint mWidth;
|
||||
|
||||
// Height of the camera
|
||||
uint mHeight;
|
||||
|
||||
// Projection matrix
|
||||
Matrix4 mProjectionMatrix;
|
||||
|
||||
// ------------------- Methods ------------------- //
|
||||
|
||||
// Update the projection matrix
|
||||
void updateProjectionMatrix();
|
||||
|
||||
public:
|
||||
|
||||
// ------------------- Methods ------------------- //
|
||||
|
||||
// Constructor
|
||||
Camera();
|
||||
|
||||
// Destructor
|
||||
~Camera();
|
||||
|
||||
// Get the projection matrix
|
||||
const Matrix4& getProjectionMatrix() const;
|
||||
|
||||
// Set the dimensions of the camera
|
||||
void setDimensions(uint width, uint height);
|
||||
|
||||
// Get the radius of the scene the camera should capture
|
||||
float getSceneRadius() const;
|
||||
|
||||
// Set the radius of the scene the camera should capture
|
||||
// This will update the clipping planes accordingly
|
||||
void setSceneRadius(float radius);
|
||||
|
||||
// Set the clipping planes
|
||||
void setClippingPlanes(float near, float far);
|
||||
|
||||
// Set the field of view
|
||||
void setFieldOfView(float fov);
|
||||
|
||||
// Set the zoom of the camera (a fraction between 0 and 1)
|
||||
void setZoom(float fraction);
|
||||
|
||||
// Translate the camera go a given point using the dx, dy fraction
|
||||
void translateCamera(float dx, float dy, const Vector3& worldPoint);
|
||||
|
||||
// Get the near clipping plane
|
||||
float getNearClippingPlane() const;
|
||||
|
||||
// Get the far clipping plane
|
||||
float getFarClippingPlane() const;
|
||||
|
||||
// Get the width
|
||||
uint getWidth() const;
|
||||
|
||||
// Get the height
|
||||
uint getHeight() const;
|
||||
};
|
||||
|
||||
// Get the projection matrix
|
||||
inline const Matrix4& Camera::getProjectionMatrix() const {
|
||||
return mProjectionMatrix;
|
||||
}
|
||||
|
||||
// Set the dimensions of the camera
|
||||
inline void Camera::setDimensions(uint width, uint height) {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Get the radius of the scene the camera should capture
|
||||
inline float Camera::getSceneRadius() const {
|
||||
return mSceneRadius;
|
||||
}
|
||||
|
||||
// Set the radius of the scene the camera should capture
|
||||
// This will update the clipping planes accordingly
|
||||
inline void Camera::setSceneRadius(float radius) {
|
||||
mSceneRadius = radius;
|
||||
setClippingPlanes(0.01f * radius, 10.0f * radius);
|
||||
}
|
||||
|
||||
// Set the clipping planes
|
||||
inline void Camera::setClippingPlanes(float near, float far) {
|
||||
mNearPlane = near;
|
||||
mFarPlane = far;
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Set the field of view
|
||||
inline void Camera::setFieldOfView(float fov) {
|
||||
mFieldOfView = fov;
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Set the zoom of the camera (a fraction between 0 and 1)
|
||||
inline void Camera::setZoom(float fraction) {
|
||||
Vector3 zoomVector(0, 0, mSceneRadius * fraction * 3.0f);
|
||||
translateLocal(zoomVector);
|
||||
}
|
||||
|
||||
// Get the near clipping plane
|
||||
inline float Camera::getNearClippingPlane() const {
|
||||
return mNearPlane;
|
||||
}
|
||||
|
||||
// Get the far clipping plane
|
||||
inline float Camera::getFarClippingPlane() const {
|
||||
return mFarPlane;
|
||||
}
|
||||
|
||||
// Get the width
|
||||
inline uint Camera::getWidth() const {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
// Get the height
|
||||
inline uint Camera::getHeight() const {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
115
examples/common/opengl-framework/src/FrameBufferObject.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "FrameBufferObject.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
FrameBufferObject::FrameBufferObject() : mFrameBufferID(0), mRenderBufferID (0) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
FrameBufferObject::~FrameBufferObject() {
|
||||
|
||||
}
|
||||
|
||||
// Create the frame buffer object
|
||||
bool FrameBufferObject::create(uint width, uint height, bool needRenderBuffer) {
|
||||
|
||||
// Destroy the current FBO
|
||||
destroy();
|
||||
|
||||
// Check that the needed OpenGL extensions are available
|
||||
bool isExtensionOK = checkOpenGLExtensions();
|
||||
if (!isExtensionOK) {
|
||||
std::cerr << "Error : Impossible to use Framebuffer Object on this platform" << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate a new FBO
|
||||
glGenFramebuffersEXT(1, &mFrameBufferID);
|
||||
assert(mFrameBufferID != 0);
|
||||
|
||||
// If we also need to create a render buffer
|
||||
if (needRenderBuffer) {
|
||||
|
||||
// Generate the render buffer
|
||||
glGenRenderbuffers(1, &mRenderBufferID);
|
||||
assert(mRenderBufferID != 0);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mRenderBufferID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mRenderBufferID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
// Check the FBO status
|
||||
GLenum statusFBO = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if(statusFBO != GL_FRAMEBUFFER_COMPLETE) {
|
||||
std::cerr << "Error : An error occured while creating the Frame Buffer Object !" << endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Destroy the FBO
|
||||
void FrameBufferObject::destroy() {
|
||||
|
||||
// Delete the frame buffer object
|
||||
if (mFrameBufferID) {
|
||||
glDeleteFramebuffers(1, &mFrameBufferID);
|
||||
mFrameBufferID = 0;
|
||||
}
|
||||
|
||||
// Delete the render buffer
|
||||
if (mRenderBufferID) {
|
||||
glDeleteRenderbuffers(1, &mRenderBufferID);
|
||||
}
|
||||
}
|
||||
|
||||
// Attach a texture to the frame buffer object
|
||||
void FrameBufferObject::attachTexture(uint position, uint textureID) {
|
||||
assert(mFrameBufferID);
|
||||
|
||||
// Bind the current FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID);
|
||||
|
||||
// Bind the texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, position, GL_TEXTURE_2D, textureID, 0);
|
||||
|
||||
// Unbind the current FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
105
examples/common/opengl-framework/src/FrameBufferObject.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FRAME_BUFFER_OBJECT_H
|
||||
#define FRAME_BUFFER_OBJECT_H
|
||||
|
||||
// Libraries
|
||||
#include "definitions.h"
|
||||
#include <GL/glew.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
|
||||
// Class FrameBufferObject
|
||||
class FrameBufferObject {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Frame buffer ID
|
||||
uint mFrameBufferID;
|
||||
|
||||
// Render buffer ID
|
||||
uint mRenderBufferID;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
FrameBufferObject();
|
||||
|
||||
// Destructor
|
||||
~FrameBufferObject();
|
||||
|
||||
// Create the frame buffer object
|
||||
bool create(uint width, uint height, bool needRenderBuffer = true);
|
||||
|
||||
// Attach a texture to the frame buffer object
|
||||
void attachTexture(uint position, uint textureID);
|
||||
|
||||
// Bind the FBO
|
||||
void bind(uint position) const;
|
||||
|
||||
// Unbind the FBO
|
||||
void unbind() const;
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for FBO
|
||||
static bool checkOpenGLExtensions();
|
||||
|
||||
// Destroy the FBO
|
||||
void destroy();
|
||||
};
|
||||
|
||||
// Bind the FBO
|
||||
inline void FrameBufferObject::bind(uint position) const {
|
||||
assert(mFrameBufferID != 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID);
|
||||
glDrawBuffer(position);
|
||||
glReadBuffer(position);
|
||||
}
|
||||
|
||||
// Unbind the FBO
|
||||
inline void FrameBufferObject::unbind() const {
|
||||
assert(mFrameBufferID != 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for FBO
|
||||
inline bool FrameBufferObject::checkOpenGLExtensions() {
|
||||
|
||||
// Check that OpenGL version is at least 3.0 or there the framebuffer object extension exists
|
||||
return (GLEW_VERSION_3_0 || GLEW_ARB_framebuffer_object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
270
examples/common/opengl-framework/src/GlutViewer.cpp
Normal file
|
@ -0,0 +1,270 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "GlutViewer.h"
|
||||
#include <string>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
GlutViewer::GlutViewer() {
|
||||
|
||||
// Initialize the state of the mouse buttons
|
||||
for (int i=0; i<10; i++) {
|
||||
mIsButtonDown[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
GlutViewer::~GlutViewer() {
|
||||
|
||||
}
|
||||
|
||||
// Initialize the viewer
|
||||
bool GlutViewer::init(int argc, char** argv, const string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive) {
|
||||
|
||||
// Initialize the GLUT library
|
||||
bool outputValue = initGLUT(argc, argv, windowsTitle, windowsSize,
|
||||
windowsPosition, isMultisamplingActive);
|
||||
|
||||
// Active the multi-sampling by default
|
||||
if (isMultisamplingActive) {
|
||||
activateMultiSampling(true);
|
||||
}
|
||||
|
||||
return outputValue;
|
||||
}
|
||||
|
||||
// Initialize the GLUT library
|
||||
bool GlutViewer::initGLUT(int argc, char** argv, const string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive) {
|
||||
|
||||
// Initialize GLUT
|
||||
glutInit(&argc, argv);
|
||||
uint modeWithoutMultiSampling = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
|
||||
uint modeWithMultiSampling = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GL_MULTISAMPLE;
|
||||
uint displayMode = isMultisamplingActive ? modeWithMultiSampling : modeWithoutMultiSampling;
|
||||
glutInitDisplayMode(displayMode);
|
||||
|
||||
// Initialize the size of the GLUT windows
|
||||
glutInitWindowSize(static_cast<int>(windowsSize.x),
|
||||
static_cast<int>(windowsSize.y));
|
||||
|
||||
// Initialize the position of the GLUT windows
|
||||
glutInitWindowPosition(static_cast<int>(windowsPosition.x),
|
||||
static_cast<int>(windowsPosition.y));
|
||||
|
||||
// Create the GLUT windows
|
||||
glutCreateWindow(windowsTitle.c_str());
|
||||
|
||||
// Initialize the GLEW library
|
||||
GLenum error = glewInit();
|
||||
if (error != GLEW_OK) {
|
||||
|
||||
// Problem: glewInit failed, something is wrong
|
||||
cerr << "GLEW Error : " << glewGetErrorString(error) << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set the camera so that we can view the whole scene
|
||||
void GlutViewer::resetCameraToViewAll() {
|
||||
|
||||
// Move the camera to the origin of the scene
|
||||
mCamera.translateWorld(-mCamera.getOrigin());
|
||||
|
||||
// Move the camera to the center of the scene
|
||||
mCamera.translateWorld(mCenterScene);
|
||||
|
||||
// Set the zoom of the camera so that the scene center is
|
||||
// in negative view direction of the camera
|
||||
mCamera.setZoom(1.0);
|
||||
}
|
||||
|
||||
// Called when a GLUT mouse button event occurs
|
||||
void GlutViewer::mouseButtonEvent(int button, int state, int x, int y) {
|
||||
|
||||
// If the mouse button is pressed
|
||||
if (state == GLUT_DOWN) {
|
||||
mLastMouseX = x;
|
||||
mLastMouseY = y;
|
||||
mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(x, y, mLastPointOnSphere);
|
||||
mIsButtonDown[button] = true;
|
||||
}
|
||||
else { // If the mouse button is released
|
||||
mIsLastPointOnSphereValid = false;
|
||||
mIsButtonDown[button] = false;
|
||||
|
||||
// If it is a mouse wheel click event
|
||||
if (button == 3) {
|
||||
zoom(0, (int) (y - 0.05f * mCamera.getWidth()));
|
||||
}
|
||||
else if (button == 4) {
|
||||
zoom(0, (int) (y + 0.05f * mCamera.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
mModifiers = glutGetModifiers();
|
||||
|
||||
// Notify GLUT to redisplay
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Called when a GLUT mouse motion event occurs
|
||||
void GlutViewer::mouseMotionEvent(int xMouse, int yMouse) {
|
||||
|
||||
// Zoom
|
||||
if ((mIsButtonDown[GLUT_LEFT_BUTTON] && mIsButtonDown[GLUT_MIDDLE_BUTTON]) ||
|
||||
(mIsButtonDown[GLUT_LEFT_BUTTON] && mModifiers == GLUT_ACTIVE_ALT)) {
|
||||
zoom(xMouse, yMouse);
|
||||
}
|
||||
// Translation
|
||||
else if (mIsButtonDown[GLUT_MIDDLE_BUTTON] || mIsButtonDown[GLUT_RIGHT_BUTTON] ||
|
||||
(mIsButtonDown[GLUT_LEFT_BUTTON] && (mModifiers == GLUT_ACTIVE_ALT))) {
|
||||
translate(xMouse, yMouse);
|
||||
}
|
||||
// Rotation
|
||||
else if (mIsButtonDown[GLUT_LEFT_BUTTON]) {
|
||||
rotate(xMouse, yMouse);
|
||||
}
|
||||
|
||||
// Remember the mouse position
|
||||
mLastMouseX = xMouse;
|
||||
mLastMouseY = yMouse;
|
||||
mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(xMouse, yMouse, mLastPointOnSphere);
|
||||
|
||||
// Notify GLUT to redisplay
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Called when a GLUT keyboard event occurs
|
||||
void GlutViewer::keyboardEvent(int key, int xMouse, int yMouse) {
|
||||
|
||||
}
|
||||
|
||||
// Called when a GLUT special keyboard event occurs
|
||||
void GlutViewer::keyboardSpecialEvent(int key, int xMouse, int yMouse) {
|
||||
|
||||
}
|
||||
|
||||
// Map the mouse x,y coordinates to a point on a sphere
|
||||
bool GlutViewer::mapMouseCoordinatesToSphere(int xMouse, int yMouse, Vector3& spherePoint) const {
|
||||
|
||||
int width = mCamera.getWidth();
|
||||
int height = mCamera.getHeight();
|
||||
|
||||
if ((xMouse >= 0) && (xMouse <= width) && (yMouse >= 0) && (yMouse <= height)) {
|
||||
float x = float(xMouse - 0.5f * width) / float(width);
|
||||
float y = float(0.5f * height - yMouse) / float(height);
|
||||
float sinx = sin(PI * x * 0.5f);
|
||||
float siny = sin(PI * y * 0.5f);
|
||||
float sinx2siny2 = sinx * sinx + siny * siny;
|
||||
|
||||
// Compute the point on the sphere
|
||||
spherePoint.x = sinx;
|
||||
spherePoint.y = siny;
|
||||
spherePoint.z = (sinx2siny2 < 1.0) ? sqrt(1.0f - sinx2siny2) : 0.0f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Zoom the camera
|
||||
void GlutViewer::zoom(int xMouse, int yMouse) {
|
||||
float dy = static_cast<float>(yMouse - mLastMouseY);
|
||||
float h = static_cast<float>(mCamera.getHeight());
|
||||
|
||||
// Zoom the camera
|
||||
mCamera.setZoom(-dy / h);
|
||||
}
|
||||
|
||||
// Translate the camera
|
||||
void GlutViewer::translate(int xMouse, int yMouse) {
|
||||
float dx = static_cast<float>(xMouse - mLastMouseX);
|
||||
float dy = static_cast<float>(yMouse - mLastMouseY);
|
||||
|
||||
// Translate the camera
|
||||
mCamera.translateCamera(-dx / float(mCamera.getWidth()),
|
||||
-dy / float(mCamera.getHeight()), mCenterScene);
|
||||
}
|
||||
|
||||
// Rotate the camera
|
||||
void GlutViewer::rotate(int xMouse, int yMouse) {
|
||||
|
||||
if (mIsLastPointOnSphereValid) {
|
||||
|
||||
Vector3 newPoint3D;
|
||||
bool isNewPointOK = mapMouseCoordinatesToSphere(xMouse, yMouse, newPoint3D);
|
||||
|
||||
if (isNewPointOK) {
|
||||
Vector3 axis = mLastPointOnSphere.cross(newPoint3D);
|
||||
float cosAngle = mLastPointOnSphere.dot(newPoint3D);
|
||||
|
||||
float epsilon = std::numeric_limits<float>::epsilon();
|
||||
if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) {
|
||||
axis.normalize();
|
||||
float angle = 2.0f * acos(cosAngle);
|
||||
|
||||
// Rotate the camera around the center of the scene
|
||||
mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the OpenGL errors
|
||||
void GlutViewer::checkOpenGLErrors() {
|
||||
GLenum glError;
|
||||
|
||||
// Get the OpenGL errors
|
||||
glError = glGetError();
|
||||
|
||||
// While there are errors
|
||||
while (glError != GL_NO_ERROR) {
|
||||
|
||||
// Get the error string
|
||||
const GLubyte* stringError = gluErrorString(glError);
|
||||
|
||||
// Display the error
|
||||
if (stringError)
|
||||
cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << endl;
|
||||
else
|
||||
cerr << "OpenGL Error #" << glError << " (no message available)" << endl;
|
||||
|
||||
// Get the next error
|
||||
glError = glGetError();
|
||||
}
|
||||
}
|
165
examples/common/opengl-framework/src/GlutViewer.h
Normal file
|
@ -0,0 +1,165 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef GLUT_VIEWER_H
|
||||
#define GLUT_VIEWER_H
|
||||
|
||||
// Libraries
|
||||
#include "Shader.h"
|
||||
#include "Camera.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include <string>
|
||||
#include <GL/glew.h>
|
||||
#ifdef __APPLE__
|
||||
#include "GLUT/glut.h"
|
||||
#else
|
||||
#include "GL/freeglut.h"
|
||||
#endif
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Renderer
|
||||
class GlutViewer {
|
||||
|
||||
protected :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Camera
|
||||
Camera mCamera;
|
||||
|
||||
// Center of the scene
|
||||
Vector3 mCenterScene;
|
||||
|
||||
// Last mouse coordinates on the windows
|
||||
int mLastMouseX, mLastMouseY;
|
||||
|
||||
// Last point computed on a sphere (for camera rotation)
|
||||
Vector3 mLastPointOnSphere;
|
||||
|
||||
// True if the last point computed on a sphere (for camera rotation) is valid
|
||||
bool mIsLastPointOnSphereValid;
|
||||
|
||||
// State of the mouse buttons
|
||||
bool mIsButtonDown[10];
|
||||
|
||||
// GLUT keyboard modifiers
|
||||
int mModifiers;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Initialize the GLUT library
|
||||
bool initGLUT(int argc, char** argv, const std::string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive);
|
||||
|
||||
bool mapMouseCoordinatesToSphere(int xMouse, int yMouse, Vector3& spherePoint) const;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
GlutViewer();
|
||||
|
||||
// Destructor
|
||||
virtual ~GlutViewer();
|
||||
|
||||
// Initialize the viewer
|
||||
bool init(int argc, char** argv, const std::string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive = false);
|
||||
|
||||
// Called when the windows is reshaped
|
||||
void reshape(int width, int height);
|
||||
|
||||
// Set the scene position (where the camera needs to look at)
|
||||
void setScenePosition(const Vector3& position, float sceneRadius);
|
||||
|
||||
// Set the camera so that we can view the whole scene
|
||||
void resetCameraToViewAll();
|
||||
|
||||
// Enable/Disable the multi-sampling for anti-aliasing
|
||||
void activateMultiSampling(bool isActive) const;
|
||||
|
||||
// Zoom the camera
|
||||
void zoom(int xMouse, int yMouse);
|
||||
|
||||
// Translate the camera
|
||||
void translate(int xMouse, int yMouse);
|
||||
|
||||
// Rotate the camera
|
||||
void rotate(int xMouse, int yMouse);
|
||||
|
||||
// Get the camera
|
||||
Camera& getCamera();
|
||||
|
||||
// Called when a GLUT mouse button event occurs
|
||||
void mouseButtonEvent(int button, int state, int x, int y);
|
||||
|
||||
// Called when a GLUT mouse motion event occurs
|
||||
void mouseMotionEvent(int xMouse, int yMouse);
|
||||
|
||||
// Called when a GLUT keyboard event occurs
|
||||
void keyboardEvent(int key, int xMouse, int yMouse);
|
||||
|
||||
// Called when a GLUT special keyboard event occurs
|
||||
void keyboardSpecialEvent(int key, int xMouse, int yMouse);
|
||||
|
||||
// Check the OpenGL errors
|
||||
static void checkOpenGLErrors();
|
||||
};
|
||||
|
||||
// Set the dimension of the camera viewport
|
||||
inline void GlutViewer::reshape(int width, int height) {
|
||||
mCamera.setDimensions(width, height);
|
||||
glViewport(0, 0, width, height);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Set the scene position (where the camera needs to look at)
|
||||
inline void GlutViewer::setScenePosition(const Vector3& position, float sceneRadius) {
|
||||
|
||||
// Set the position and radius of the scene
|
||||
mCenterScene = position;
|
||||
mCamera.setSceneRadius(sceneRadius);
|
||||
|
||||
// Reset the camera position and zoom in order to view all the scene
|
||||
resetCameraToViewAll();
|
||||
}
|
||||
|
||||
// Get the camera
|
||||
inline Camera& GlutViewer::getCamera() {
|
||||
return mCamera;
|
||||
}
|
||||
|
||||
// Enable/Disable the multi-sampling for anti-aliasing
|
||||
inline void GlutViewer::activateMultiSampling(bool isActive) const {
|
||||
(isActive) ? glEnable(GL_MULTISAMPLE) : glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
100
examples/common/opengl-framework/src/Light.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Light.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Light::Light(GLuint id)
|
||||
: mLightID(id), mDiffuseColor(Color::white()),
|
||||
mSpecularColor(Color::white()), mIsActive(false) {
|
||||
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Light::Light(GLuint id, Color diffuseColor, Color specularColor)
|
||||
: mLightID(id), mDiffuseColor(diffuseColor),
|
||||
mSpecularColor(specularColor), mIsActive(false) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Light::~Light() {
|
||||
|
||||
}
|
||||
|
||||
// Initialize the light
|
||||
void Light::init() {
|
||||
|
||||
// Enable the light
|
||||
enable();
|
||||
|
||||
// Set the diffuse and specular color
|
||||
GLfloat diffuseColor[] = {mDiffuseColor.r, mDiffuseColor.g, mDiffuseColor.b, mDiffuseColor.a};
|
||||
GLfloat specularColor[] = {mSpecularColor.r,mSpecularColor.g,mSpecularColor.b,mSpecularColor.a};
|
||||
glLightfv(mLightID, GL_DIFFUSE, diffuseColor);
|
||||
glLightfv(mLightID, GL_SPECULAR, specularColor);
|
||||
}
|
||||
|
||||
// Create a shadow map associated with this light
|
||||
bool Light::createShadowMap(uint width, uint height) {
|
||||
|
||||
// Destroy the current shadow map
|
||||
destroyShadowMap();
|
||||
|
||||
// Create the Framebuffer object to render the shadow map
|
||||
bool isFBOCreated = mFBOShadowMap.create(width, height, false);
|
||||
if (!isFBOCreated) {
|
||||
std::cerr << "Error : Cannot create the Shadow Map !" << std::endl;
|
||||
destroyShadowMap();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind the Framebuffer object
|
||||
mFBOShadowMap.bind(GL_NONE);
|
||||
|
||||
// Create the shadow map depth texture
|
||||
mShadowMap.create(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE);
|
||||
|
||||
// Attache the shadow map texture to the Framebuffer object
|
||||
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMap.getID());
|
||||
|
||||
// Unbind the Framebuffer object
|
||||
mFBOShadowMap.unbind();
|
||||
|
||||
// TODO : Change the path of the shader here so that it does not depend on the build folder
|
||||
bool isShaderCreated = mDepthShader.create("../../opengl-framework/src/shaders/depth.vert",
|
||||
"../../opengl-framework/src/shaders/depth.vert");
|
||||
if (!isShaderCreated) {
|
||||
std::cerr << "Error : Cannot create the Shadow Map !" << std::endl;
|
||||
destroyShadowMap();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
181
examples/common/opengl-framework/src/Light.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef LIGHT_H
|
||||
#define LIGHT_H
|
||||
|
||||
// Libraries
|
||||
#include "maths/Color.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "Object3D.h"
|
||||
#include "Texture2D.h"
|
||||
#include "FrameBufferObject.h"
|
||||
#include "Shader.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Light
|
||||
class Light : public Object3D {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// OpenGL light ID
|
||||
GLuint mLightID;
|
||||
|
||||
// Diffuse color of the light
|
||||
Color mDiffuseColor;
|
||||
|
||||
// Specular color of the light
|
||||
Color mSpecularColor;
|
||||
|
||||
// True if the light is active
|
||||
bool mIsActive;
|
||||
|
||||
// Shadow map associated with this light
|
||||
Texture2D mShadowMap;
|
||||
|
||||
// Framebuffer object to render the shadow map
|
||||
FrameBufferObject mFBOShadowMap;
|
||||
|
||||
// Shader to render the depth of the scene into a texture
|
||||
Shader mDepthShader;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Light(GLuint id);
|
||||
|
||||
// Constructor
|
||||
Light(GLuint id, Color diffuseColor, Color specularColor);
|
||||
|
||||
// Destructor
|
||||
virtual ~Light();
|
||||
|
||||
// Return the diffuse color
|
||||
Color getDiffuseColor() const;
|
||||
|
||||
// Set the diffuse color
|
||||
void setDiffuseColor(const Color& color);
|
||||
|
||||
// Return the specular color
|
||||
Color getSpecularColor() const;
|
||||
|
||||
// Set the specular color
|
||||
void setSpecularColor(const Color& color);
|
||||
|
||||
// Return true if the light is active
|
||||
bool getIsActive() const;
|
||||
|
||||
// Initialize the light
|
||||
void init();
|
||||
|
||||
// Enable the light
|
||||
void enable();
|
||||
|
||||
// Disable the light
|
||||
void disable();
|
||||
|
||||
// Create a shadow map associated with this light
|
||||
bool createShadowMap(uint width, uint height);
|
||||
|
||||
// Call this method before rendering the scene for the shadow map computation
|
||||
void startRenderingShadowMap();
|
||||
|
||||
// Call this method after having rendered the scene for the shadow map computation
|
||||
void stopRenderingShadowMap();
|
||||
|
||||
// Destroy the shadow map associated with this light
|
||||
void destroyShadowMap();
|
||||
};
|
||||
|
||||
// Return the diffuse color
|
||||
inline Color Light::getDiffuseColor() const {
|
||||
return mDiffuseColor;
|
||||
}
|
||||
|
||||
// Set the diffuse color
|
||||
inline void Light::setDiffuseColor(const Color& color) {
|
||||
mDiffuseColor = color;
|
||||
}
|
||||
|
||||
// Return the specular color
|
||||
inline Color Light::getSpecularColor() const {
|
||||
return mSpecularColor;
|
||||
}
|
||||
|
||||
// Set the specular color
|
||||
inline void Light::setSpecularColor(const Color& color) {
|
||||
mSpecularColor = color;
|
||||
}
|
||||
|
||||
// Return true if the light is active
|
||||
inline bool Light::getIsActive() const {
|
||||
return mIsActive;
|
||||
}
|
||||
|
||||
// Enable the light
|
||||
inline void Light::enable() {
|
||||
|
||||
mIsActive = true;
|
||||
|
||||
// Enable the light
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0 + mLightID);
|
||||
}
|
||||
|
||||
// Disable the light
|
||||
inline void Light::disable() {
|
||||
|
||||
mIsActive = false;
|
||||
|
||||
// Disable the light
|
||||
glDisable(GL_LIGHT0 + mLightID);
|
||||
}
|
||||
|
||||
// Destroy the shadow map associated with this light
|
||||
inline void Light::destroyShadowMap() {
|
||||
mShadowMap.destroy();
|
||||
mFBOShadowMap.destroy();
|
||||
mDepthShader.destroy();
|
||||
}
|
||||
|
||||
// Call this method before rendering the scene for the shadow map computation
|
||||
inline void Light::startRenderingShadowMap() {
|
||||
assert(mShadowMap.getID());
|
||||
}
|
||||
|
||||
// Call this method after having rendered the scene for the shadow map computation
|
||||
inline void Light::stopRenderingShadowMap() {
|
||||
assert(mShadowMap.getID());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
176
examples/common/opengl-framework/src/Mesh.cpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Mesh.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
Mesh::Mesh() {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Mesh::~Mesh() {
|
||||
|
||||
}
|
||||
|
||||
// Destroy the mesh
|
||||
void Mesh::destroy() {
|
||||
|
||||
mVertices.clear();
|
||||
mNormals.clear();
|
||||
mTangents.clear();
|
||||
mIndices.clear();
|
||||
mColors.clear();
|
||||
mUVs.clear();
|
||||
mTextures.clear();
|
||||
}
|
||||
|
||||
// Compute the normals of the mesh
|
||||
void Mesh::calculateNormals() {
|
||||
|
||||
mNormals = vector<Vector3>(getNbVertices(), Vector3(0, 0, 0));
|
||||
|
||||
// For each triangular face
|
||||
for (uint i=0; i<getNbFaces(); i++) {
|
||||
|
||||
// Get the three vertices index of the current face
|
||||
uint v1 = getVertexIndexInFace(i, 0);
|
||||
uint v2 = getVertexIndexInFace(i, 1);
|
||||
uint v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
assert(v1 < getNbVertices());
|
||||
assert(v2 < getNbVertices());
|
||||
assert(v3 < getNbVertices());
|
||||
|
||||
// Compute the normal of the face
|
||||
Vector3 p = getVertex(v1);
|
||||
Vector3 q = getVertex(v2);
|
||||
Vector3 r = getVertex(v3);
|
||||
Vector3 normal = (q-p).cross(r-p).normalize();
|
||||
|
||||
// Add the face surface normal to the sum of normals at
|
||||
// each vertex of the face
|
||||
mNormals[v1] += normal;
|
||||
mNormals[v2] += normal;
|
||||
mNormals[v3] += normal;
|
||||
}
|
||||
|
||||
// Normalize the normal at each vertex
|
||||
for (uint i=0; i<getNbVertices(); i++) {
|
||||
mNormals[i] = mNormals[i].normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the tangents of the mesh
|
||||
void Mesh::calculateTangents() {
|
||||
|
||||
mTangents = std::vector<Vector3>(getNbVertices(), Vector3(0, 0, 0));
|
||||
|
||||
// For each face
|
||||
for (uint i=0; i<getNbFaces(); i++) {
|
||||
|
||||
// Get the three vertices index of the face
|
||||
uint v1 = getVertexIndexInFace(i, 0);
|
||||
uint v2 = getVertexIndexInFace(i, 1);
|
||||
uint v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
assert(v1 < getNbVertices());
|
||||
assert(v2 < getNbVertices());
|
||||
assert(v3 < getNbVertices());
|
||||
|
||||
// Get the vertices positions
|
||||
Vector3 p = getVertex(v1);
|
||||
Vector3 q = getVertex(v2);
|
||||
Vector3 r = getVertex(v3);
|
||||
|
||||
// Get the texture coordinates of each vertex
|
||||
Vector2 uvP = getUV(v1);
|
||||
Vector2 uvQ = getUV(v2);
|
||||
Vector2 uvR = getUV(v3);
|
||||
|
||||
// Get the three edges
|
||||
Vector3 edge1 = q - p;
|
||||
Vector3 edge2 = r - p;
|
||||
Vector2 edge1UV = uvQ - uvP;
|
||||
Vector2 edge2UV = uvR - uvP;
|
||||
|
||||
float cp = edge1UV.y * edge2UV.x - edge1UV.x * edge2UV.y;
|
||||
|
||||
// Compute the tangent
|
||||
if (cp != 0.0f) {
|
||||
float factor = 1.0f / cp;
|
||||
Vector3 tangent = (edge1 * -edge2UV.y + edge2 * edge1UV.y) * factor;
|
||||
tangent.normalize();
|
||||
mTangents[v1] = tangent;
|
||||
mTangents[v2] = tangent;
|
||||
mTangents[v3] = tangent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the bounding box of the mesh
|
||||
void Mesh::calculateBoundingBox(Vector3& min, Vector3& max) const {
|
||||
|
||||
// If the mesh contains vertices
|
||||
if (!mVertices.empty()) {
|
||||
|
||||
min = mVertices[0];
|
||||
max = mVertices[0];
|
||||
|
||||
std::vector<Vector3>::const_iterator it(mVertices.begin());
|
||||
|
||||
// For each vertex of the mesh
|
||||
for (; it != mVertices.end(); ++it) {
|
||||
|
||||
if( (*it).x < min.x ) min.x = (*it).x;
|
||||
else if ( (*it).x > max.x ) max.x = (*it).x;
|
||||
|
||||
if( (*it).y < min.y ) min.y = (*it).y;
|
||||
else if ( (*it).y > max.y ) max.y = (*it).y;
|
||||
|
||||
if( (*it).z < min.z ) min.z = (*it).z;
|
||||
else if ( (*it).z > max.z ) max.z = (*it).z;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Impossible to calculate the bounding box of the mesh because there" <<
|
||||
"are no vertices !" << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Scale of vertices of the mesh using a given factor
|
||||
void Mesh::scaleVertices(float factor) {
|
||||
|
||||
// For each vertex
|
||||
for (uint i=0; i<getNbVertices(); i++) {
|
||||
mVertices.at(i) *= factor;
|
||||
}
|
||||
}
|
411
examples/common/opengl-framework/src/Mesh.h
Normal file
|
@ -0,0 +1,411 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MESH_H
|
||||
#define MESH_H
|
||||
|
||||
// Libraries
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "definitions.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Color.h"
|
||||
#include "Texture2D.h"
|
||||
#include "Object3D.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Mesh
|
||||
// This class represents a 3D triangular mesh
|
||||
// object that can be loaded from an OBJ file for instance.
|
||||
class Mesh : public Object3D {
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// A triplet of vertex indices for each triangle
|
||||
std::vector<std::vector<uint> > mIndices;
|
||||
|
||||
// Vertices coordinates (local space)
|
||||
std::vector<Vector3> mVertices;
|
||||
|
||||
// Normals coordinates
|
||||
std::vector<Vector3> mNormals;
|
||||
|
||||
// Tangents coordinates
|
||||
std::vector<Vector3> mTangents;
|
||||
|
||||
// Color for each vertex
|
||||
std::vector<Color> mColors;
|
||||
|
||||
// UV texture coordinates
|
||||
std::vector<Vector2> mUVs;
|
||||
|
||||
// Textures of the mesh (one for each part of the mesh)
|
||||
std::map<uint, Texture2D> mTextures;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Mesh();
|
||||
|
||||
// Destructor
|
||||
virtual ~Mesh();
|
||||
|
||||
// Destroy the mesh
|
||||
void destroy();
|
||||
|
||||
// Compute the normals of the mesh
|
||||
void calculateNormals();
|
||||
|
||||
// Compute the tangents of the mesh
|
||||
void calculateTangents();
|
||||
|
||||
// Calculate the bounding box of the mesh
|
||||
void calculateBoundingBox(Vector3& min, Vector3& max) const;
|
||||
|
||||
// Scale of vertices of the mesh using a given factor
|
||||
void scaleVertices(float factor);
|
||||
|
||||
// Return the number of triangles
|
||||
uint getNbFaces(uint part = 0) const;
|
||||
|
||||
// Return the number of vertices
|
||||
uint getNbVertices() const;
|
||||
|
||||
// Return the number of parts in the mesh
|
||||
uint getNbParts() const;
|
||||
|
||||
// Return a reference to the vertices
|
||||
const std::vector<Vector3>& getVertices() const;
|
||||
|
||||
// Set the vertices of the mesh
|
||||
void setVertices(std::vector<Vector3>& vertices);
|
||||
|
||||
// Return a reference to the normals
|
||||
const std::vector<Vector3>& getNormals() const;
|
||||
|
||||
// set the normals of the mesh
|
||||
void setNormals(std::vector<Vector3>& normals);
|
||||
|
||||
// Return a reference to the UVs
|
||||
const std::vector<Vector2>& getUVs() const;
|
||||
|
||||
// Set the UV texture coordinates of the mesh
|
||||
void setUVs(std::vector<Vector2>& uvs);
|
||||
|
||||
// Return a reference to the vertex indices
|
||||
const std::vector<uint>& getIndices(uint part = 0) const;
|
||||
|
||||
// Set the vertices indices of the mesh
|
||||
void setIndices(std::vector<std::vector<uint> >& indices);
|
||||
|
||||
// Return the coordinates of a given vertex
|
||||
const Vector3& getVertex(uint i) const;
|
||||
|
||||
// Set the coordinates of a given vertex
|
||||
void setVertex(uint i, const Vector3& vertex);
|
||||
|
||||
// Return the coordinates of a given normal
|
||||
const Vector3& getNormal(uint i) const;
|
||||
|
||||
// Set the coordinates of a given normal
|
||||
void setNormal(uint i, const Vector3& normal);
|
||||
|
||||
// Return the color of a given vertex
|
||||
const Color& getColor(uint i) const;
|
||||
|
||||
// Set the color of a given vertex
|
||||
void setColor(uint i, const Color& color);
|
||||
|
||||
// Set a color to all the vertices
|
||||
void setColorToAllVertices(const Color& color);
|
||||
|
||||
// Return the UV of a given vertex
|
||||
const Vector2& getUV(uint i) const;
|
||||
|
||||
// Set the UV of a given vertex
|
||||
void setUV(uint i, const Vector2& uv);
|
||||
|
||||
// Return the vertex index of the ith (i=0,1,2) vertex of a given face
|
||||
uint getVertexIndexInFace(uint faceIndex, uint i, uint part = 0) const;
|
||||
|
||||
// Return true if the mesh has normals
|
||||
bool hasNormals() const;
|
||||
|
||||
// Return true if the mesh has tangents
|
||||
bool hasTangents() const;
|
||||
|
||||
// Return true if the mesh has vertex colors
|
||||
bool hasColors() const;
|
||||
|
||||
// Return true if the mesh has UV texture coordinates
|
||||
bool hasUVTextureCoordinates() const;
|
||||
|
||||
// Return true if the mesh has a texture for a given part of the mesh and if it
|
||||
// also have texture coordinates
|
||||
bool hasTextureForPart(uint part = 0) const;
|
||||
|
||||
// Return true if the mesh has a texture (and texture coordinates) for at least one
|
||||
// part of the mesh
|
||||
bool hasTexture() const;
|
||||
|
||||
// Return a pointer to the vertices data
|
||||
void* getVerticesPointer();
|
||||
|
||||
// Return a pointer to the normals data
|
||||
void* getNormalsPointer();
|
||||
|
||||
// Return a pointer to the colors data
|
||||
void* getColorsPointer();
|
||||
|
||||
// Return a pointer to the tangents data
|
||||
void* getTangentsPointer();
|
||||
|
||||
// Return a pointer to the UV texture coordinates data
|
||||
void* getUVTextureCoordinatesPointer();
|
||||
|
||||
// Return a pointer to the vertex indicies data
|
||||
void* getIndicesPointer(uint part = 0);
|
||||
|
||||
// Return a reference to a texture of the mesh
|
||||
Texture2D &getTexture(uint part = 0);
|
||||
|
||||
// Set a texture to a part of the mesh
|
||||
void setTexture(Texture2D &texture, uint part = 0);
|
||||
};
|
||||
|
||||
// Return the number of triangles
|
||||
inline uint Mesh::getNbFaces(uint part) const {
|
||||
return mIndices[part].size() / 3;
|
||||
}
|
||||
|
||||
// Return the number of vertices
|
||||
inline uint Mesh::getNbVertices() const {
|
||||
return mVertices.size();
|
||||
}
|
||||
|
||||
// Return the number of parts in the mesh
|
||||
inline uint Mesh::getNbParts() const {
|
||||
return mIndices.size();
|
||||
}
|
||||
|
||||
// Return a reference to the vertices
|
||||
inline const std::vector<Vector3>& Mesh::getVertices() const {
|
||||
return mVertices;
|
||||
}
|
||||
|
||||
// Set the vertices of the mesh
|
||||
inline void Mesh::setVertices(std::vector<Vector3>& vertices) {
|
||||
mVertices = vertices;
|
||||
}
|
||||
|
||||
// Return a reference to the normals
|
||||
inline const std::vector<Vector3>& Mesh::getNormals() const {
|
||||
return mNormals;
|
||||
}
|
||||
|
||||
// set the normals of the mesh
|
||||
inline void Mesh::setNormals(std::vector<Vector3>& normals) {
|
||||
mNormals = normals;
|
||||
}
|
||||
|
||||
// Return a reference to the UVs
|
||||
inline const std::vector<Vector2>& Mesh::getUVs() const {
|
||||
return mUVs;
|
||||
}
|
||||
|
||||
// Set the UV texture coordinates of the mesh
|
||||
inline void Mesh::setUVs(std::vector<Vector2>& uvs) {
|
||||
mUVs = uvs;
|
||||
}
|
||||
|
||||
// Return a reference to the vertex indices
|
||||
inline const std::vector<uint>& Mesh::getIndices(uint part) const {
|
||||
return mIndices[part];
|
||||
}
|
||||
|
||||
// Set the vertices indices of the mesh
|
||||
inline void Mesh::setIndices(std::vector<std::vector<uint> >& indices) {
|
||||
mIndices = indices;
|
||||
}
|
||||
|
||||
// Return the coordinates of a given vertex
|
||||
inline const Vector3& Mesh::getVertex(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mVertices[i];
|
||||
}
|
||||
|
||||
// Set the coordinates of a given vertex
|
||||
inline void Mesh::setVertex(uint i, const Vector3& vertex) {
|
||||
assert(i < getNbVertices());
|
||||
mVertices[i] = vertex;
|
||||
}
|
||||
|
||||
// Return the coordinates of a given normal
|
||||
inline const Vector3& Mesh::getNormal(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mNormals[i];
|
||||
}
|
||||
|
||||
// Set the coordinates of a given normal
|
||||
inline void Mesh::setNormal(uint i, const Vector3& normal) {
|
||||
assert(i < getNbVertices());
|
||||
mNormals[i] = normal;
|
||||
}
|
||||
|
||||
// Return the color of a given vertex
|
||||
inline const Color& Mesh::getColor(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mColors[i];
|
||||
}
|
||||
|
||||
// Set the color of a given vertex
|
||||
inline void Mesh::setColor(uint i, const Color& color) {
|
||||
|
||||
// If the color array does not have the same size as
|
||||
// the vertices array
|
||||
if (mColors.size() != mVertices.size()) {
|
||||
|
||||
// Create the color array with the same size
|
||||
mColors = std::vector<Color>(mVertices.size());
|
||||
}
|
||||
|
||||
mColors[i] = color;
|
||||
}
|
||||
|
||||
// Set a color to all the vertices
|
||||
inline void Mesh::setColorToAllVertices(const Color& color) {
|
||||
|
||||
// If the color array does not have the same size as
|
||||
// the vertices array
|
||||
if (mColors.size() != mVertices.size()) {
|
||||
|
||||
// Create the color array with the same size
|
||||
mColors = std::vector<Color>(mVertices.size());
|
||||
}
|
||||
|
||||
for (size_t v=0; v<mVertices.size(); v++) {
|
||||
mColors[v] = color;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the UV of a given vertex
|
||||
inline const Vector2& Mesh::getUV(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mUVs[i];
|
||||
}
|
||||
|
||||
// Set the UV of a given vertex
|
||||
inline void Mesh::setUV(uint i, const Vector2& uv) {
|
||||
assert(i < getNbVertices());
|
||||
mUVs[i] = uv;
|
||||
}
|
||||
|
||||
// Return the vertex index of the ith (i=0,1,2) vertex of a given face
|
||||
inline uint Mesh::getVertexIndexInFace(uint faceIndex, uint i, uint part) const {
|
||||
return (mIndices[part])[faceIndex*3 + i];
|
||||
}
|
||||
|
||||
// Return true if the mesh has normals
|
||||
inline bool Mesh::hasNormals() const {
|
||||
return mNormals.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has tangents
|
||||
inline bool Mesh::hasTangents() const {
|
||||
return mTangents.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has vertex colors
|
||||
inline bool Mesh::hasColors() const {
|
||||
return mColors.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has UV texture coordinates
|
||||
inline bool Mesh::hasUVTextureCoordinates() const {
|
||||
return mUVs.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has a texture for a given part of the mesh and if it
|
||||
// also have texture coordinates
|
||||
inline bool Mesh::hasTextureForPart(uint part) const {
|
||||
return hasUVTextureCoordinates() && mTextures.count(part);
|
||||
}
|
||||
|
||||
// Return true if the mesh has a texture (and texture coordinates) for at least one
|
||||
// part of the mesh
|
||||
inline bool Mesh::hasTexture() const {
|
||||
return hasUVTextureCoordinates() && (mTextures.size() > 0);
|
||||
}
|
||||
|
||||
// Return a pointer to the vertices data
|
||||
inline void* Mesh::getVerticesPointer() {
|
||||
return &(mVertices[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the normals data
|
||||
inline void* Mesh::getNormalsPointer() {
|
||||
return &(mNormals[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the colors data
|
||||
inline void* Mesh::getColorsPointer() {
|
||||
return &(mColors[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the tangents data
|
||||
inline void* Mesh::getTangentsPointer() {
|
||||
return &(mTangents[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the UV texture coordinates data
|
||||
inline void* Mesh::getUVTextureCoordinatesPointer() {
|
||||
return &(mUVs[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the vertex indicies data
|
||||
inline void* Mesh::getIndicesPointer(uint part) {
|
||||
return &(mIndices[part])[0];
|
||||
}
|
||||
|
||||
// Return a reference to a texture of the mesh
|
||||
inline Texture2D& Mesh::getTexture(uint part) {
|
||||
return mTextures[part];
|
||||
}
|
||||
|
||||
// Set a texture to a part of the mesh
|
||||
inline void Mesh::setTexture(Texture2D& texture, uint part) {
|
||||
mTextures[part] = texture;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
393
examples/common/opengl-framework/src/MeshReaderWriter.cpp
Normal file
|
@ -0,0 +1,393 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "MeshReaderWriter.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <locale>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
MeshReaderWriter::MeshReaderWriter() {
|
||||
|
||||
}
|
||||
|
||||
// Load a mesh from a file and returns true if the mesh has been sucessfully loaded
|
||||
void MeshReaderWriter::loadMeshFromFile(const std::string& filename, Mesh& meshToCreate) {
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Load the file using the correct method
|
||||
if (extension == "obj") {
|
||||
loadOBJFile(filename, meshToCreate);
|
||||
}
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the MeshReaderWriter class cannot load a file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Write a mesh to a file
|
||||
void MeshReaderWriter::writeMeshToFile(const std::string& filename, const Mesh& meshToWrite) {
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Load the file using the correct method
|
||||
if (extension == "obj") {
|
||||
writeOBJFile(filename, meshToWrite);
|
||||
}
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the MeshReaderWriter class cannot store a mesh file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Load an OBJ file with a triangular or quad mesh
|
||||
void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||
|
||||
// Open the file
|
||||
std::ifstream meshFile(filename.c_str());
|
||||
|
||||
// If we cannot open the file
|
||||
if(!meshFile.is_open()) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot open the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
string line, tmp;
|
||||
int id1, id2, id3, id4;
|
||||
int nId1, nId2, nId3, nId4;
|
||||
int tId1, tId2, tId3, tId4;
|
||||
float v1, v2, v3;
|
||||
size_t found1, found2;
|
||||
std::vector<bool> isQuad;
|
||||
std::vector<Vector3> vertices;
|
||||
std::vector<Vector3> normals;
|
||||
std::vector<Vector2> uvs;
|
||||
std::vector<uint> verticesIndices;
|
||||
std::vector<uint> normalsIndices;
|
||||
std::vector<uint> uvsIndices;
|
||||
|
||||
// ---------- Collect the data from the file ---------- //
|
||||
|
||||
// For each line of the file
|
||||
while(std::getline(meshFile, buffer)) {
|
||||
|
||||
std::istringstream lineStream(buffer);
|
||||
std::string word;
|
||||
lineStream >> word;
|
||||
std::transform(word.begin(), word.end(), word.begin(), ::tolower);
|
||||
if(word == "usemtl") { // Material definition
|
||||
|
||||
// Loading of MTL file is not implemented
|
||||
|
||||
}
|
||||
else if(word == "v") { // Vertex position
|
||||
sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3);
|
||||
vertices.push_back(Vector3(v1, v2, v3));
|
||||
}
|
||||
else if(word == "vt") { // Vertex texture coordinate
|
||||
sscanf(buffer.c_str(), "%*s %f %f", &v1, &v2);
|
||||
uvs.push_back(Vector2(v1,v2));
|
||||
}
|
||||
else if(word == "vn") { // Vertex normal
|
||||
sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3);
|
||||
normals.push_back(Vector3(v1 ,v2, v3));
|
||||
}
|
||||
else if (word == "f") { // Face
|
||||
line = buffer;
|
||||
found1 = (int)line.find("/");
|
||||
bool isFaceQuad = false;
|
||||
int foundNext = (int)line.substr(found1+1).find("/");
|
||||
|
||||
// If the face definition is of the form "f v1 v2 v3 v4"
|
||||
if(found1 == string::npos) {
|
||||
int nbVertices = sscanf(buffer.c_str(), "%*s %d %d %d %d", &id1, &id2, &id3, &id4);
|
||||
if (nbVertices == 4) isFaceQuad = true;
|
||||
}
|
||||
// If the face definition is of the form "f v1// v2// v3// v4//"
|
||||
else if (foundNext == 0) {
|
||||
int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4);
|
||||
if (nbVertices == 4) isFaceQuad = true;
|
||||
}
|
||||
else { // If the face definition contains vertices and texture coordinates
|
||||
|
||||
//get the part of the string until the second index
|
||||
tmp = line.substr(found1+1);
|
||||
found2 = (int)tmp.find(" ");
|
||||
tmp = tmp.substr(0,found2);
|
||||
found2 = (int)tmp.find("/");
|
||||
|
||||
// If the face definition is of the form "f vert1/textcoord1 vert2/textcoord2 ..."
|
||||
if(found2 == string::npos) {
|
||||
int n = sscanf(buffer.c_str(), "%*s %d/%d %d/%d %d/%d %d/%d", &id1, &tId1, &id2, &tId2, &id3, &tId3, &id4, &tId4);
|
||||
if (n == 8) isFaceQuad = true;
|
||||
uvsIndices.push_back(tId1-1);
|
||||
uvsIndices.push_back(tId2-1);
|
||||
uvsIndices.push_back(tId3-1);
|
||||
if (isFaceQuad) uvsIndices.push_back(tId4-1);
|
||||
}
|
||||
else {
|
||||
tmp = line.substr(found1+1);
|
||||
found2 = (int)tmp.find("/");
|
||||
|
||||
// If the face definition is of the form "f vert1/normal1 vert2/normal2 ..."
|
||||
if(found2 == 0) {
|
||||
int n = sscanf(buffer.c_str(), "%*s %d//%d %d//%d %d//%d %d//%d", &id1, &nId1, &id2, &nId2, &id3, &nId3, &id4, &nId4);
|
||||
if (n == 8) isFaceQuad = true;
|
||||
}
|
||||
// If the face definition is of the form "f vert1/textcoord1/normal1 ..."
|
||||
else {
|
||||
int n = sscanf(buffer.c_str(), "%*s %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &id1, &tId1, &nId1, &id2, &tId2, &nId2, &id3, &tId3, &nId3, &id4, &tId4, &nId4);
|
||||
if (n == 12) isFaceQuad = true;
|
||||
uvsIndices.push_back(tId1-1);
|
||||
uvsIndices.push_back(tId2-1);
|
||||
uvsIndices.push_back(tId3-1);
|
||||
if (isFaceQuad) uvsIndices.push_back(tId4-1);
|
||||
}
|
||||
normalsIndices.push_back(nId1-1);
|
||||
normalsIndices.push_back(nId2-1);
|
||||
normalsIndices.push_back(nId3-1);
|
||||
if (isFaceQuad) normalsIndices.push_back(nId4-1);
|
||||
}
|
||||
}
|
||||
verticesIndices.push_back(id1-1);
|
||||
verticesIndices.push_back(id2-1);
|
||||
verticesIndices.push_back(id3-1);
|
||||
if (isFaceQuad) verticesIndices.push_back((id4-1));
|
||||
isQuad.push_back(isFaceQuad);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!verticesIndices.empty());
|
||||
assert(normalsIndices.empty() || normalsIndices.size() == verticesIndices.size());
|
||||
assert(uvsIndices.empty() || uvsIndices.size() == verticesIndices.size());
|
||||
meshFile.close();
|
||||
|
||||
// ---------- Merge the data that we have collected from the file ---------- //
|
||||
|
||||
// Destroy the current mesh
|
||||
meshToCreate.destroy();
|
||||
|
||||
// Mesh data
|
||||
vector<std::vector<uint> > meshIndices;
|
||||
vector<Vector3> meshNormals;
|
||||
if (!normals.empty()) meshNormals = vector<Vector3>(vertices.size(), Vector3(0, 0, 0));
|
||||
vector<Vector2> meshUVs;
|
||||
if (!uvs.empty()) meshUVs = vector<Vector2>(vertices.size(), Vector2(0, 0));
|
||||
|
||||
// We cannot load mesh with several parts for the moment
|
||||
uint meshPart = 0;
|
||||
|
||||
// Fill in the vertex indices
|
||||
// We also triangulate each quad face
|
||||
meshIndices.push_back(std::vector<uint>());
|
||||
for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) {
|
||||
|
||||
// Get the current vertex IDs
|
||||
uint i1 = verticesIndices[i];
|
||||
uint i2 = verticesIndices[i+1];
|
||||
uint i3 = verticesIndices[i+2];
|
||||
|
||||
// Add the vertex normal
|
||||
if (!normalsIndices.empty() && !normals.empty()) {
|
||||
meshNormals[i1] = normals[normalsIndices[i]];
|
||||
meshNormals[i2] = normals[normalsIndices[i+1]];
|
||||
meshNormals[i3] = normals[normalsIndices[i+2]];
|
||||
}
|
||||
|
||||
// Add the vertex UV texture coordinates
|
||||
if (!uvsIndices.empty() && !uvs.empty()) {
|
||||
meshUVs[i1] = uvs[uvsIndices[i]];
|
||||
meshUVs[i2] = uvs[uvsIndices[i+1]];
|
||||
meshUVs[i3] = uvs[uvsIndices[i+2]];
|
||||
}
|
||||
|
||||
// If the current vertex not in a quad (it is part of a triangle)
|
||||
if (!isQuad[j]) {
|
||||
|
||||
// Add the vertex indices
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
|
||||
i+=3;
|
||||
}
|
||||
else { // If the current vertex is in a quad
|
||||
|
||||
Vector3 v1 = vertices[i1];
|
||||
Vector3 v2 = vertices[i2];
|
||||
Vector3 v3 = vertices[i3];
|
||||
uint i4 = verticesIndices[i+3];
|
||||
Vector3 v4 = vertices[i4];
|
||||
|
||||
Vector3 v13 = v3-v1;
|
||||
Vector3 v12 = v2-v1;
|
||||
Vector3 v14 = v4-v1;
|
||||
|
||||
float a1 = v13.dot(v12);
|
||||
float a2 = v13.dot(v14);
|
||||
if((a1 >= 0 && a2 <= 0) || (a1 <= 0 && a2 >= 0)) {
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
meshIndices[meshPart].push_back(i4);
|
||||
}
|
||||
else {
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i4);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
meshIndices[meshPart].push_back(i4);
|
||||
}
|
||||
|
||||
// Add the vertex normal
|
||||
if (!normalsIndices.empty() && !normals.empty()) {
|
||||
meshNormals[i4] = normals[normalsIndices[i]];
|
||||
}
|
||||
|
||||
// Add the vertex UV texture coordinates
|
||||
if (!uvsIndices.empty() && !uvs.empty()) {
|
||||
meshUVs[i4] = uvs[uvsIndices[i]];
|
||||
}
|
||||
|
||||
i+=4;
|
||||
}
|
||||
}
|
||||
|
||||
assert(meshNormals.empty() || meshNormals.size() == vertices.size());
|
||||
assert(meshUVs.empty() || meshUVs.size() == vertices.size());
|
||||
|
||||
// Set the data to the mesh
|
||||
meshToCreate.setIndices(meshIndices);
|
||||
meshToCreate.setVertices(vertices);
|
||||
meshToCreate.setNormals(meshNormals);
|
||||
meshToCreate.setUVs(meshUVs);
|
||||
}
|
||||
|
||||
// Store a mesh into a OBJ file
|
||||
void MeshReaderWriter::writeOBJFile(const std::string& filename, const Mesh& meshToWrite) {
|
||||
std::ofstream file(filename.c_str());
|
||||
|
||||
// Geth the mesh data
|
||||
const std::vector<Vector3>& vertices = meshToWrite.getVertices();
|
||||
const std::vector<Vector3>& normals = meshToWrite.getNormals();
|
||||
const std::vector<Vector2>& uvs = meshToWrite.getUVs();
|
||||
|
||||
// If we can open the file
|
||||
if (file.is_open()) {
|
||||
|
||||
assert(meshToWrite.getNbVertices() == vertices.size());
|
||||
|
||||
// Write the vertices
|
||||
for (uint v=0; v<vertices.size(); v++) {
|
||||
|
||||
file << "v " << vertices[v].x << " " << vertices[v].y << " " << vertices[v].z <<
|
||||
std::endl;
|
||||
}
|
||||
|
||||
// Write the normals
|
||||
if (meshToWrite.hasNormals()) {
|
||||
file << std::endl;
|
||||
|
||||
assert(meshToWrite.getNbVertices() == normals.size());
|
||||
|
||||
for (uint v=0; v<normals.size(); v++) {
|
||||
|
||||
file << "vn " << normals[v].x << " " << normals[v].y << " " << normals[v].z <<
|
||||
std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the UVs texture coordinates
|
||||
if (meshToWrite.hasUVTextureCoordinates()) {
|
||||
file << std::endl;
|
||||
|
||||
assert(meshToWrite.getNbVertices() == uvs.size());
|
||||
|
||||
for (uint v=0; v<uvs.size(); v++) {
|
||||
|
||||
file << "vt " << uvs[v].x << " " << uvs[v].y << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the faces
|
||||
file << std::endl;
|
||||
for (uint p=0; p<meshToWrite.getNbParts(); p++) {
|
||||
|
||||
// Get the indices of the part
|
||||
const std::vector<uint>& indices = meshToWrite.getIndices(p);
|
||||
|
||||
// For each index of the part
|
||||
for (uint i=0; i<indices.size(); i+=3) {
|
||||
|
||||
if (meshToWrite.hasNormals() && meshToWrite.hasUVTextureCoordinates()) {
|
||||
file << "f " <<indices[i]+1 << "/" << indices[i]+1 << "/" << indices[i]+1 <<
|
||||
" " << indices[i+1]+1 << "/" << indices[i+1]+1 << "/" << indices[i+1]+1 <<
|
||||
" " << indices[i+2]+1 << "/" << indices[i+2]+1 << "/" << indices[i+2]+1 <<
|
||||
std::endl;
|
||||
}
|
||||
else if (meshToWrite.hasNormals() || meshToWrite.hasUVTextureCoordinates()) {
|
||||
file << "f " <<indices[i]+1 << "/" << indices[i]+1 <<
|
||||
" " << indices[i+1]+1 << "/" << indices[i+1]+1 <<
|
||||
" " << indices[i+2]+1 << "/" << indices[i+2]+1 << std::endl;
|
||||
}
|
||||
else {
|
||||
file << "f " << indices[i]+1 << " " << indices[i+1]+1 << " " << indices[i+2]+1 <<
|
||||
std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Cannot open the file " << filename << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
96
examples/common/opengl-framework/src/MeshReaderWriter.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MESH_LOADER_H
|
||||
#define MESH_LOADER_H
|
||||
|
||||
// Libraries
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "Mesh.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class MeshReaderWriter
|
||||
// This class is used to read or write any mesh file in order to
|
||||
// create the corresponding Mesh object. Currently, this class
|
||||
// is able to read meshes of the current formats : .obj
|
||||
class MeshReaderWriter {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor (private because we do not want instances of this class)
|
||||
MeshReaderWriter();
|
||||
|
||||
// Load an OBJ file with a triangular or quad mesh
|
||||
static void loadOBJFile(const std::string& filename, Mesh& meshToCreate);
|
||||
|
||||
// Store a mesh into a OBJ file
|
||||
static void writeOBJFile(const std::string& filename, const Mesh &meshToWrite);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Read a mesh from a file
|
||||
static void loadMeshFromFile(const std::string& filename, Mesh& meshToCreate);
|
||||
|
||||
// Write a mesh to a file
|
||||
static void writeMeshToFile(const std::string& filename, const Mesh& meshToWrite);
|
||||
};
|
||||
|
||||
// Class VertexMergingData
|
||||
// This class is used in the method to read a mesh
|
||||
class VertexMergingData {
|
||||
|
||||
public:
|
||||
VertexMergingData() : indexPosition(0), indexNormal(0), indexUV(0) {}
|
||||
unsigned int indexPosition;
|
||||
unsigned int indexNormal;
|
||||
unsigned int indexUV;
|
||||
};
|
||||
|
||||
// Class VertexMergingDataComparison
|
||||
// This class is used in the method to read a mesh
|
||||
class VertexMergingDataComparison {
|
||||
|
||||
public:
|
||||
bool operator()(const VertexMergingData& x, const VertexMergingData& y) const {
|
||||
if(x.indexPosition < y.indexPosition)
|
||||
return true;
|
||||
if(x.indexPosition == y.indexPosition && x.indexNormal < y.indexNormal)
|
||||
return true;
|
||||
if(x.indexPosition == y.indexPosition && x.indexNormal ==
|
||||
y.indexNormal && x.indexUV < y.indexUV)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
41
examples/common/opengl-framework/src/Object3D.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Object3D.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Object3D::Object3D() {
|
||||
// Set the transformation matrix to the identity
|
||||
setToIdentity();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Object3D::~Object3D() {
|
||||
|
||||
}
|
149
examples/common/opengl-framework/src/Object3D.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef OBJECT3D_H
|
||||
#define OBJECT3D_H
|
||||
|
||||
// Libraries
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Matrix4.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Object3D
|
||||
// This class represent a generic 3D object on the scene.
|
||||
class Object3D {
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Transformation matrix that convert local-space
|
||||
// coordinates to world-space coordinates
|
||||
Matrix4 mTransformMatrix;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Object3D();
|
||||
|
||||
// Destructor
|
||||
virtual ~Object3D();
|
||||
|
||||
// Return the transform matrix
|
||||
const Matrix4& getTransformMatrix() const;
|
||||
|
||||
// Set the transform matrix
|
||||
void setTransformMatrix(const Matrix4& matrix);
|
||||
|
||||
// Set to the identity transform
|
||||
void setToIdentity();
|
||||
|
||||
// Return the origin of object in world-space
|
||||
Vector3 getOrigin() const;
|
||||
|
||||
// Translate the object in world-space
|
||||
void translateWorld(const Vector3& v);
|
||||
|
||||
// Translate the object in local-space
|
||||
void translateLocal(const Vector3& v);
|
||||
|
||||
// Rotate the object in world-space
|
||||
void rotateWorld(const Vector3& axis, float angle);
|
||||
|
||||
// Rotate the object in local-space
|
||||
void rotateLocal(const Vector3& axis, float angle);
|
||||
|
||||
// Rotate around a world-space point
|
||||
void rotateAroundWorldPoint(const Vector3& axis, float angle, const Vector3& point);
|
||||
|
||||
// Rotate around a local-space point
|
||||
void rotateAroundLocalPoint(const Vector3& axis, float angle, const Vector3& worldPoint);
|
||||
};
|
||||
|
||||
// Return the transform matrix
|
||||
inline const Matrix4& Object3D::getTransformMatrix() const {
|
||||
return mTransformMatrix;
|
||||
}
|
||||
|
||||
// Set the transform matrix
|
||||
inline void Object3D::setTransformMatrix(const Matrix4& matrix) {
|
||||
mTransformMatrix = matrix;
|
||||
}
|
||||
|
||||
// Set to the identity transform
|
||||
inline void Object3D::setToIdentity() {
|
||||
mTransformMatrix.setToIdentity();
|
||||
}
|
||||
|
||||
// Return the origin of object in world-space
|
||||
inline Vector3 Object3D::getOrigin() const {
|
||||
return mTransformMatrix * Vector3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// Translate the object in world-space
|
||||
inline void Object3D::translateWorld(const Vector3& v) {
|
||||
mTransformMatrix = Matrix4::translationMatrix(v) * mTransformMatrix;
|
||||
}
|
||||
|
||||
// Translate the object in local-space
|
||||
inline void Object3D::translateLocal(const Vector3& v) {
|
||||
mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(v);
|
||||
}
|
||||
|
||||
// Rotate the object in world-space
|
||||
inline void Object3D::rotateWorld(const Vector3& axis, float angle) {
|
||||
mTransformMatrix = Matrix4::rotationMatrix(axis, angle) * mTransformMatrix;
|
||||
}
|
||||
|
||||
// Rotate the object in local-space
|
||||
inline void Object3D::rotateLocal(const Vector3& axis, float angle) {
|
||||
mTransformMatrix = mTransformMatrix * Matrix4::rotationMatrix(axis, angle);
|
||||
}
|
||||
|
||||
// Rotate the object around a world-space point
|
||||
inline void Object3D::rotateAroundWorldPoint(const Vector3& axis, float angle,
|
||||
const Vector3& worldPoint) {
|
||||
mTransformMatrix = Matrix4::translationMatrix(worldPoint) * Matrix4::rotationMatrix(axis, angle)
|
||||
* Matrix4::translationMatrix(-worldPoint) * mTransformMatrix;
|
||||
}
|
||||
|
||||
// Rotate the object around a local-space point
|
||||
inline void Object3D::rotateAroundLocalPoint(const Vector3& axis, float angle,
|
||||
const Vector3& worldPoint) {
|
||||
|
||||
// Convert the world point into the local coordinate system
|
||||
Vector3 localPoint = mTransformMatrix.getInverse() * worldPoint;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(localPoint)
|
||||
* Matrix4::rotationMatrix(axis, angle)
|
||||
* Matrix4::translationMatrix(-localPoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
207
examples/common/opengl-framework/src/Shader.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Shader.h"
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
Shader::Shader() : mProgramObjectID(0) {
|
||||
|
||||
}
|
||||
|
||||
// Constructor with arguments
|
||||
Shader::Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename)
|
||||
: mProgramObjectID(0) {
|
||||
|
||||
// Create the shader
|
||||
create(vertexShaderFilename, fragmentShaderFilename);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Shader::~Shader() {
|
||||
|
||||
}
|
||||
|
||||
// Create the shader
|
||||
bool Shader::create(const std::string vertexShaderFilename,
|
||||
const std::string fragmentShaderFilename) {
|
||||
|
||||
// Set the shader filenames
|
||||
mFilenameVertexShader = vertexShaderFilename;
|
||||
mFilenameFragmentShader = fragmentShaderFilename;
|
||||
|
||||
// Check that the needed OpenGL extensions are available
|
||||
bool isExtensionOK = checkOpenGLExtensions();
|
||||
if (!isExtensionOK) {
|
||||
cerr << "Error : Impossible to use GLSL vertex or fragment shaders on this platform" << endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete the current shader
|
||||
destroy();
|
||||
|
||||
assert(!vertexShaderFilename.empty() && !fragmentShaderFilename.empty());
|
||||
|
||||
// ------------------- Load the vertex shader ------------------- //
|
||||
GLuint vertexShaderID;
|
||||
std::ifstream fileVertexShader;
|
||||
fileVertexShader.open(vertexShaderFilename.c_str(), std::ios::binary);
|
||||
|
||||
if (fileVertexShader.is_open()) {
|
||||
|
||||
// Get the size of the file
|
||||
fileVertexShader.seekg(0, std::ios::end);
|
||||
uint fileSize = (uint) (fileVertexShader.tellg());
|
||||
assert(fileSize != 0);
|
||||
|
||||
// Read the file
|
||||
fileVertexShader.seekg(std::ios::beg);
|
||||
char* bufferVertexShader = new char[fileSize + 1];
|
||||
fileVertexShader.read(bufferVertexShader, fileSize);
|
||||
fileVertexShader.close();
|
||||
bufferVertexShader[fileSize] = '\0';
|
||||
|
||||
// Create the OpenGL vertex shader and compile it
|
||||
vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
assert(vertexShaderID != 0);
|
||||
glShaderSource(vertexShaderID, 1, (const char **) (&bufferVertexShader), NULL);
|
||||
glCompileShader(vertexShaderID);
|
||||
delete[] bufferVertexShader;
|
||||
|
||||
// Get the compilation information
|
||||
int compiled;
|
||||
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &compiled);
|
||||
|
||||
// If the compilation failed
|
||||
if (compiled == 0) {
|
||||
|
||||
// Get the log of the compilation
|
||||
int lengthLog;
|
||||
glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &lengthLog);
|
||||
char* str = new char[lengthLog];
|
||||
glGetShaderInfoLog(vertexShaderID, lengthLog, NULL, str);
|
||||
|
||||
// Display the log of the compilation
|
||||
std::cerr << "Vertex Shader Error : " << str << std::endl;
|
||||
delete[] str;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Impossible to open the vertex shader file " <<
|
||||
vertexShaderFilename << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------- Load the fragment shader ------------------- //
|
||||
GLuint fragmentShaderID;
|
||||
std::ifstream fileFragmentShader;
|
||||
fileFragmentShader.open(fragmentShaderFilename.c_str(), std::ios::binary);
|
||||
assert(fileFragmentShader.is_open());
|
||||
|
||||
if (fileFragmentShader.is_open()) {
|
||||
|
||||
// Get the size of the file
|
||||
fileFragmentShader.seekg(0, std::ios::end);
|
||||
uint fileSize = (uint) (fileFragmentShader.tellg());
|
||||
assert(fileSize != 0);
|
||||
|
||||
// Read the file
|
||||
fileFragmentShader.seekg(std::ios::beg);
|
||||
char* bufferFragmentShader = new char[fileSize + 1];
|
||||
fileFragmentShader.read(bufferFragmentShader, fileSize);
|
||||
fileFragmentShader.close();
|
||||
bufferFragmentShader[fileSize] = '\0';
|
||||
|
||||
// Create the OpenGL fragment shader and compile it
|
||||
fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
assert(fragmentShaderID != 0);
|
||||
glShaderSource(fragmentShaderID, 1, (const char **) (&bufferFragmentShader), NULL);
|
||||
glCompileShader(fragmentShaderID);
|
||||
delete[] bufferFragmentShader;
|
||||
|
||||
// Get the compilation information
|
||||
int compiled;
|
||||
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &compiled);
|
||||
|
||||
// If the compilation failed
|
||||
if (compiled == 0) {
|
||||
|
||||
// Get the log of the compilation
|
||||
int lengthLog;
|
||||
glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &lengthLog);
|
||||
char* str = new char[lengthLog];
|
||||
glGetShaderInfoLog(fragmentShaderID, lengthLog, NULL, str);
|
||||
|
||||
// Display the log of the compilation
|
||||
std::cerr << "Fragment Shader Error : " << str << std::endl;
|
||||
delete[] str;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Impossible to open the fragment shader file " <<
|
||||
fragmentShaderFilename << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the shader program and attach the shaders
|
||||
mProgramObjectID = glCreateProgram();
|
||||
assert(mProgramObjectID);
|
||||
glAttachShader(mProgramObjectID, vertexShaderID);
|
||||
glAttachShader(mProgramObjectID, fragmentShaderID);
|
||||
glDeleteShader(vertexShaderID);
|
||||
glDeleteShader(fragmentShaderID);
|
||||
|
||||
// Try to link the program
|
||||
glLinkProgram(mProgramObjectID);
|
||||
int linked;
|
||||
glGetProgramiv(mProgramObjectID, GL_LINK_STATUS, &linked);
|
||||
if (!linked) {
|
||||
int logLength;
|
||||
glGetProgramiv(mProgramObjectID, GL_INFO_LOG_LENGTH, &logLength);
|
||||
char* strLog = new char[logLength];
|
||||
glGetProgramInfoLog(mProgramObjectID, logLength, NULL, strLog);
|
||||
cerr << "Linker Error in vertex shader " << vertexShaderFilename <<
|
||||
" or in fragment shader " << fragmentShaderFilename << " : " << strLog << endl;
|
||||
delete[] strLog;
|
||||
destroy();
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
262
examples/common/opengl-framework/src/Shader.h
Normal file
|
@ -0,0 +1,262 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
// Libraries
|
||||
#include "definitions.h"
|
||||
#include "maths/Matrix4.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Vector4.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Shader
|
||||
class Shader {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Shader object program ID
|
||||
GLuint mProgramObjectID;
|
||||
|
||||
// Filenames of the vertex and fragment shaders
|
||||
std::string mFilenameVertexShader, mFilenameFragmentShader;
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Shader();
|
||||
|
||||
// Constructor with arguments
|
||||
Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename);
|
||||
|
||||
// Destructor
|
||||
~Shader();
|
||||
|
||||
// Create the shader
|
||||
bool create(const std::string vertexShaderFilename,
|
||||
const std::string fragmentShaderFilename);
|
||||
|
||||
// Clear the shader
|
||||
void destroy();
|
||||
|
||||
// Bind the shader
|
||||
void bind() const;
|
||||
|
||||
// Unbind the shader
|
||||
void unbind() const;
|
||||
|
||||
// Return the location of a uniform variable inside a shader program
|
||||
int getUniformLocation(const std::string& variableName) const;
|
||||
|
||||
// Set a float uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setFloatUniform(const std::string& variableName, float value) const;
|
||||
|
||||
// Set an int uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setIntUniform(const std::string& variableName, int value) const;
|
||||
|
||||
// Set a vector 2 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setVector2Uniform(const std::string& variableName, const Vector2& v) const;
|
||||
|
||||
// Set a vector 3 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setVector3Uniform(const std::string& variableName, const Vector3& v) const;
|
||||
|
||||
// Set a vector 4 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setVector4Uniform(const std::string& variableName, const Vector4 &v) const;
|
||||
|
||||
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix3x3Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose = false) const;
|
||||
|
||||
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const;
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix4x4Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose = false) const;
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const;
|
||||
|
||||
// Return true if the needed OpenGL extensions are available
|
||||
static bool checkOpenGLExtensions();
|
||||
};
|
||||
|
||||
// Bind the shader
|
||||
inline void Shader::bind() const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUseProgram(mProgramObjectID);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
inline void Shader::unbind() const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
// Return the location of a uniform variable inside a shader program
|
||||
inline int Shader::getUniformLocation(const std::string& variableName) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
int location = glGetUniformLocation(mProgramObjectID, variableName.c_str());
|
||||
if (location == -1) {
|
||||
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
|
||||
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
|
||||
<< std::endl;
|
||||
}
|
||||
assert(location != -1);
|
||||
return location;
|
||||
}
|
||||
|
||||
// Clear the shader
|
||||
inline void Shader::destroy() {
|
||||
if (mProgramObjectID != 0) {
|
||||
glDeleteShader(mProgramObjectID);
|
||||
mProgramObjectID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set a float uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setFloatUniform(const std::string& variableName, float value) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform1f(getUniformLocation(variableName), value);
|
||||
}
|
||||
|
||||
// Set an int uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setIntUniform(const std::string& variableName, int value) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform1i(getUniformLocation(variableName), value);
|
||||
}
|
||||
|
||||
// Set a vector 2 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform2f(getUniformLocation(variableName), v.x, v.y);
|
||||
}
|
||||
|
||||
// Set a vector 3 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform3f(getUniformLocation(variableName), v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
// Set a vector 4 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform4f(getUniformLocation(variableName), v.x, v.y, v.z, v.w);
|
||||
}
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniformMatrix3fv(getUniformLocation(variableName), 1, transpose, matrix);
|
||||
}
|
||||
|
||||
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
GLfloat mat[9];
|
||||
for (int i=0; i<3; i++) {
|
||||
for (int j=0; j<3; j++) {
|
||||
mat[i*3 + j] = matrix.getValue(i, j);
|
||||
}
|
||||
}
|
||||
glUniformMatrix3fv(getUniformLocation(variableName), 1, true, mat);
|
||||
}
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniformMatrix4fv(getUniformLocation(variableName), 1, transpose, matrix);
|
||||
}
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
GLfloat mat[16];
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
mat[i*4 + j] = matrix.m[i][j];
|
||||
}
|
||||
}
|
||||
glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat);
|
||||
}
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for shaders
|
||||
inline bool Shader::checkOpenGLExtensions() {
|
||||
|
||||
// Check that GLSL vertex and fragment shaders are available on the platform
|
||||
return (GLEW_VERSION_2_0 || (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
84
examples/common/opengl-framework/src/Texture2D.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Texture2D.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Texture2D::Texture2D() : mID(0), mLayer(0), mWidth(0), mHeight(0) {
|
||||
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Texture2D::Texture2D(uint width, uint height, uint internalFormat, uint format, uint type)
|
||||
: mID(0), mLayer(0), mWidth(0), mHeight(0){
|
||||
|
||||
// Create the texture
|
||||
create(width, height, internalFormat, format, type);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Texture2D::~Texture2D() {
|
||||
|
||||
}
|
||||
|
||||
// Create the texture
|
||||
void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type,
|
||||
void* data) {
|
||||
|
||||
// Destroy the current texture
|
||||
destroy();
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
// Create the OpenGL texture
|
||||
glGenTextures(1, &mID);
|
||||
assert(mID != 0);
|
||||
glBindTexture(GL_TEXTURE_2D, mID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, mWidth, mHeight, 0, format, type, data);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// Destroy the texture
|
||||
void Texture2D::destroy() {
|
||||
if (mID != 0) {
|
||||
glDeleteTextures(1, &mID);
|
||||
mID = 0;
|
||||
mLayer = 0;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
}
|
142
examples/common/opengl-framework/src/Texture2D.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEXTURE2D_H
|
||||
#define TEXTURE2D_H
|
||||
|
||||
// Libraries
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include "definitions.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Texture2D
|
||||
// This class represents a 2D texture
|
||||
class Texture2D {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// OpenGL texture ID
|
||||
GLuint mID;
|
||||
|
||||
// Layer of the texture
|
||||
GLuint mLayer;
|
||||
|
||||
// Width
|
||||
uint mWidth;
|
||||
|
||||
// Height
|
||||
uint mHeight;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Texture2D();
|
||||
|
||||
// Constructor
|
||||
Texture2D(uint width, uint height, uint internalFormat, uint format, uint type);
|
||||
|
||||
// Destructor
|
||||
~Texture2D();
|
||||
|
||||
// Create the texture
|
||||
void create(uint width, uint height, uint internalFormat, uint format, uint type,
|
||||
void* data = NULL);
|
||||
|
||||
// Destroy the texture
|
||||
void destroy();
|
||||
|
||||
// Bind the texture
|
||||
void bind() const;
|
||||
|
||||
// Unbind the texture
|
||||
void unbind() const;
|
||||
|
||||
// Get the OpenGL texture ID
|
||||
uint getID() const;
|
||||
|
||||
// Get the layer of the texture
|
||||
uint getLayer() const;
|
||||
|
||||
// Set the layer of the texture
|
||||
void setLayer(uint layer);
|
||||
|
||||
// Get the width
|
||||
uint getWidth() const;
|
||||
|
||||
// Get the height
|
||||
uint getHeight() const;
|
||||
};
|
||||
|
||||
// Bind the texture
|
||||
inline void Texture2D::bind() const {
|
||||
assert(mID != 0);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0 + mLayer);
|
||||
glBindTexture(GL_TEXTURE_2D, mID);
|
||||
}
|
||||
|
||||
// Unbind the texture
|
||||
inline void Texture2D::unbind() const {
|
||||
assert(mID != 0);
|
||||
glActiveTexture(GL_TEXTURE0 + mLayer);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Get the OpenGL texture ID
|
||||
inline uint Texture2D::getID() const {
|
||||
return mID;
|
||||
}
|
||||
|
||||
// Get the layer of the texture
|
||||
inline uint Texture2D::getLayer() const {
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
// Set the layer of the texture
|
||||
inline void Texture2D::setLayer(uint layer) {
|
||||
mLayer = layer;
|
||||
}
|
||||
|
||||
// Get the width
|
||||
inline uint Texture2D::getWidth() const {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
// Get the height
|
||||
inline uint Texture2D::getHeight() const {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
332
examples/common/opengl-framework/src/TextureReaderWriter.cpp
Normal file
|
@ -0,0 +1,332 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Librairies
|
||||
#include "TextureReaderWriter.h"
|
||||
#include <string>
|
||||
#ifdef USE_JPEG_TEXTURE
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
#endif
|
||||
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constants
|
||||
const uint TextureReaderWriter::JPEG_COMPRESSION_QUALITY = 98;
|
||||
|
||||
// TGA file Header
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
unsigned char identsize; // size of ID field that follows 18 byte header (0 usually)
|
||||
unsigned char colourmaptype; // type of colour map 0=none, 1=has palette
|
||||
unsigned char imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
|
||||
|
||||
short colourmapstart; // first colour map entry in palette
|
||||
short colourmaplength; // number of colours in palette
|
||||
unsigned char colourmapbits; // number of bits per palette entry 15,16,24,32
|
||||
|
||||
short xstart; // image x origin
|
||||
short ystart; // image y origin
|
||||
short width; // image width in pixels
|
||||
short height; // image height in pixels
|
||||
unsigned char bits; // image bits per pixel 8,16,24,32
|
||||
unsigned char descriptor; // image descriptor bits (vh flip bits)
|
||||
|
||||
// pixel data follows header
|
||||
} TGA_HEADER;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Load a texture from a file
|
||||
void TextureReaderWriter::loadTextureFromFile(const std::string& filename,
|
||||
Texture2D& textureToCreate) {
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Load the file using the correct method
|
||||
if (extension == "tga") {
|
||||
readTGAPicture(filename, textureToCreate);
|
||||
}
|
||||
#ifdef USE_JPEG_TEXTURE
|
||||
else if (extension == "jpg" || extension == "jpeg"){
|
||||
readJPEGPicture(filename, textureToCreate);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the TextureLoader class cannot load a file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Write a texture to a file
|
||||
void TextureReaderWriter::writeTextureToFile(const std::string& filename,const Texture2D& texture) {
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Write the file using the correct method
|
||||
if (extension == "tga") {
|
||||
writeTGAPicture(filename, texture);
|
||||
}
|
||||
#ifdef USE_JPEG_TEXTURE
|
||||
else if (extension == "jpg" || extension == "jpeg"){
|
||||
writeJPEGPicture(filename, texture);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the TextureReaderWriter class cannot write a file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Load a TGA picture
|
||||
void TextureReaderWriter::readTGAPicture(const std::string &filename, Texture2D& textureToCreate) {
|
||||
|
||||
// Open the file
|
||||
std::ifstream stream(filename.c_str(), std::ios::binary);
|
||||
|
||||
// If we cannot open the file
|
||||
if(!stream.is_open()) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot open the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
TGA_HEADER header;
|
||||
stream.read((char *)(&header), sizeof(TGA_HEADER));
|
||||
assert(header.width <= 4096 && header.width <= 4096 &&
|
||||
header.imagetype == 2 && header.bits == 24);
|
||||
|
||||
// Read the file
|
||||
uint width = header.width;
|
||||
uint height = header.width;
|
||||
uint sizeImg = width*height;
|
||||
char* data = new char[sizeImg*3];
|
||||
assert(data);
|
||||
stream.read(data, sizeImg*3);
|
||||
for(uint i = 0; i < sizeImg; i++) {
|
||||
unsigned pos = i*3;
|
||||
unsigned char red = data[pos];
|
||||
data[pos] = data[pos + 2];
|
||||
data[pos + 2] = red;
|
||||
}
|
||||
|
||||
// Close the stream
|
||||
stream.close();
|
||||
|
||||
// Create the OpenGL texture using the picture data from the file
|
||||
textureToCreate.create(width, height, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
// Free the data memory
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
|
||||
// Write a TGA picture
|
||||
void TextureReaderWriter::writeTGAPicture(const std::string& filename, const Texture2D& texture) {
|
||||
assert(texture.getID() != 0);
|
||||
|
||||
// Bind the corresponding texture
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getID());
|
||||
|
||||
uint sizeImg = texture.getWidth() * texture.getHeight();
|
||||
|
||||
// Get the bytes form the OpenGL texture
|
||||
char* data = new char[sizeImg * 3];
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
// Open the file
|
||||
std::ofstream stream(filename.c_str(), std::ios::binary);
|
||||
|
||||
// If the file cannot be opened
|
||||
if(!stream.is_open()) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot create/access the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
delete[] data;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
// Fill in the TGA header
|
||||
TGA_HEADER header;
|
||||
header.identsize = 0; // size of ID field that follows 18 byte header (0 usually)
|
||||
header.colourmaptype = 0; // type of colour map 0=none, 1=has palette
|
||||
header.imagetype = 2; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
|
||||
header.colourmapstart = 0; // first colour map entry in palette
|
||||
header.colourmaplength = 0; // number of colours in palette
|
||||
header.colourmapbits=0; // number of bits per palette entry 15,16,24,32
|
||||
header.xstart = 0; // image x origin
|
||||
header.ystart = 0; // image y origin
|
||||
header.width = (short)texture.getWidth(); // image width in pixels
|
||||
header.height = (short)texture.getHeight(); // image height in pixels
|
||||
header.bits = 24; // image bits per pixel 8,16,24,32
|
||||
header.descriptor = 0; // image descriptor bits (vh flip bits)
|
||||
|
||||
// Write the header to the file
|
||||
stream.write((char*)(&header), sizeof(TGA_HEADER));
|
||||
|
||||
// Write the bytes to the file
|
||||
for(uint i = 0; i < sizeImg; i++) {
|
||||
unsigned pos = i*3;
|
||||
unsigned char red = data[pos];
|
||||
data[pos] = data[pos + 2];
|
||||
data[pos + 2] = red;
|
||||
}
|
||||
stream.write(data, sizeImg*3);
|
||||
|
||||
// Close the file
|
||||
stream.close();
|
||||
|
||||
// Delete the data
|
||||
delete[] data;
|
||||
|
||||
// Unbind the corresponding texture
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
#ifdef USE_JPEG_TEXTURE
|
||||
|
||||
// Read a JPEG picture
|
||||
void TextureReaderWriter::readJPEGPicture(const std::string& filename, Texture2D& textureToCreate) {
|
||||
|
||||
struct jpeg_decompress_struct info;
|
||||
struct jpeg_error_mgr error;
|
||||
|
||||
info.err = jpeg_std_error(&error);
|
||||
jpeg_create_decompress(&info);
|
||||
|
||||
// Open the file
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
|
||||
// If we cannot open the file
|
||||
if (!file) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot open the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
jpeg_stdio_src(&info, file);
|
||||
jpeg_read_header(&info, true);
|
||||
jpeg_start_decompress(&info);
|
||||
|
||||
unsigned long x = info.output_width;
|
||||
unsigned long y = info.output_height;
|
||||
int channels = info.num_components;
|
||||
assert(channels == 3);
|
||||
|
||||
unsigned long size = x * y * 3;
|
||||
|
||||
BYTE* data = new BYTE[size];
|
||||
|
||||
BYTE* p1 = data;
|
||||
BYTE** p2 = &p1;
|
||||
int numlines = 0;
|
||||
|
||||
while(info.output_scanline < info.output_height) {
|
||||
numlines = jpeg_read_scanlines(&info, p2, 1);
|
||||
*p2 += numlines * 3 * info.output_width;
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&info); //finish decompressing this file
|
||||
|
||||
// Close the file
|
||||
fclose(file);
|
||||
|
||||
// Create the OpenGL texture
|
||||
textureToCreate.create(x, y, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
// Free allocated memory
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
// Write a JPEG picture
|
||||
void TextureReaderWriter::writeJPEGPicture(const std::string& filename, const Texture2D& texture) {
|
||||
|
||||
struct jpeg_compress_struct info;
|
||||
struct jpeg_error_mgr error;
|
||||
|
||||
info.err = jpeg_std_error(&error);
|
||||
jpeg_create_compress(&info);
|
||||
|
||||
// Open the file
|
||||
FILE* file = fopen(filename.c_str(), "wb");
|
||||
|
||||
if (!file) {
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot write JPEG picture into the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
// Get the bytes form the OpenGL texture
|
||||
char* data = new char[texture.getWidth() * texture.getHeight() * 3];
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
jpeg_stdio_dest(&info, file);
|
||||
|
||||
info.image_width = texture.getWidth();
|
||||
info.image_height = texture.getHeight();
|
||||
info.input_components = 3;
|
||||
info.in_color_space = JCS_RGB;
|
||||
jpeg_set_defaults(&info);
|
||||
jpeg_set_quality(&info, JPEG_COMPRESSION_QUALITY, true);
|
||||
|
||||
jpeg_start_compress(&info, true);
|
||||
|
||||
// Write the data into the file
|
||||
JSAMPROW rowPointer;
|
||||
int rowStride = texture.getWidth() * 3;
|
||||
while (info.next_scanline < info.image_height) {
|
||||
rowPointer = (JSAMPROW) &data[info.next_scanline * rowStride];
|
||||
jpeg_write_scanlines(&info, &rowPointer, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&info);
|
||||
jpeg_destroy_compress(&info);
|
||||
|
||||
// Close the file
|
||||
fclose(file);
|
||||
|
||||
// Free allocated memory
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
#endif
|
79
examples/common/opengl-framework/src/TextureReaderWriter.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEXTURE_READER_WRITER_H
|
||||
#define TEXTURE_READER_WRITER_H
|
||||
|
||||
// Libraries
|
||||
#include "Texture2D.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class TextureReaderWriter
|
||||
// This class is used to load or write a texture image in different picture format.
|
||||
// It currently allows to read and write the following formats : .tga
|
||||
class TextureReaderWriter {
|
||||
|
||||
private :
|
||||
|
||||
// ------------------- Constants ------------------- //
|
||||
|
||||
// JPEG quality for compression (in percent)
|
||||
static const uint JPEG_COMPRESSION_QUALITY;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor (private because we do not want instances of this class)
|
||||
TextureReaderWriter();
|
||||
|
||||
// Read a TGA picture
|
||||
static void readTGAPicture(const std::string& filename, Texture2D& textureToCreate);
|
||||
|
||||
// Write a TGA picture
|
||||
static void writeTGAPicture(const std::string& filename, const Texture2D& texture);
|
||||
|
||||
// Read a JPEG picture
|
||||
static void readJPEGPicture(const std::string& filename, Texture2D& textureToCreate);
|
||||
|
||||
// Write a JPEG picture
|
||||
static void writeJPEGPicture(const std::string& filename, const Texture2D& texture);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Load a texture from a file
|
||||
static void loadTextureFromFile(const std::string& filename, Texture2D& textureToCreate);
|
||||
|
||||
// Write a texture to a file
|
||||
static void writeTextureToFile(const std::string& filename, const Texture2D& texture);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
84
examples/common/opengl-framework/src/VertexBufferObject.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "VertexBufferObject.h"
|
||||
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
VertexBufferObject::VertexBufferObject(GLenum targetData)
|
||||
: mVertexBufferID(0), mTargetData(targetData) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
VertexBufferObject::~VertexBufferObject() {
|
||||
|
||||
}
|
||||
|
||||
// Create the vertex buffer object
|
||||
bool VertexBufferObject::create() {
|
||||
|
||||
// Destroy the current VBO
|
||||
destroy();
|
||||
|
||||
// Check that the needed OpenGL extensions are available
|
||||
bool isExtensionOK = checkOpenGLExtensions();
|
||||
if (!isExtensionOK) {
|
||||
std::cerr << "Error : Impossible to use Vertex Buffer Object on this platform" << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate a new VBO
|
||||
glGenBuffers(1, &mVertexBufferID);
|
||||
assert(mVertexBufferID != 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy data into the VBO
|
||||
void VertexBufferObject::copyDataIntoVBO(GLsizei size, const void* data, GLenum usage) {
|
||||
|
||||
// Bind the VBO
|
||||
bind();
|
||||
|
||||
// Copy the data into the VBO
|
||||
glBufferData(mTargetData, size, data, usage);
|
||||
|
||||
// Unbind the VBO
|
||||
unbind();
|
||||
}
|
||||
|
||||
// Destroy the VBO
|
||||
void VertexBufferObject::destroy() {
|
||||
|
||||
// Delete the vertex buffer object
|
||||
if (mVertexBufferID) {
|
||||
glDeleteFramebuffers(1, &mVertexBufferID);
|
||||
mVertexBufferID = 0;
|
||||
}
|
||||
}
|
106
examples/common/opengl-framework/src/VertexBufferObject.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VERTEX_BUFFER_OBJECT_H
|
||||
#define VERTEX_BUFFER_OBJECT_H
|
||||
|
||||
// Libraries
|
||||
#include <GL/glew.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
|
||||
// Class VertexBufferObject
|
||||
class VertexBufferObject {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// ID of the Vertex Buffer Object
|
||||
GLuint mVertexBufferID;
|
||||
|
||||
/// Target data. This variable must be GL_ARRAY_BUFFER if the VBO contains vertex
|
||||
/// data (vertex coordinates, texture coordinates, normals, colors) or must be
|
||||
/// GL_ELEMENT_ARRAY_BUFFER if the VBO contains index data (index array).
|
||||
GLenum mTargetData;
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
VertexBufferObject(GLenum targetData);
|
||||
|
||||
/// Destructor
|
||||
~VertexBufferObject();
|
||||
|
||||
/// Create the vertex buffer object
|
||||
bool create();
|
||||
|
||||
/// Copy data into the VBO
|
||||
void copyDataIntoVBO(GLsizei size, const void* data, GLenum usage);
|
||||
|
||||
/// Bind the VBO
|
||||
void bind() const;
|
||||
|
||||
/// Unbind the VBO
|
||||
void unbind() const;
|
||||
|
||||
/// Return true if the needed OpenGL extensions are available for VBO
|
||||
static bool checkOpenGLExtensions();
|
||||
|
||||
/// Destroy the VBO
|
||||
void destroy();
|
||||
};
|
||||
|
||||
// Bind the VBO
|
||||
inline void VertexBufferObject::bind() const {
|
||||
assert(mVertexBufferID != 0);
|
||||
|
||||
// Bind the VBO
|
||||
glBindBuffer(mTargetData, mVertexBufferID);
|
||||
}
|
||||
|
||||
// Unbind the VBO
|
||||
inline void VertexBufferObject::unbind() const {
|
||||
assert(mVertexBufferID != 0);
|
||||
|
||||
// Unbind the VBO
|
||||
glBindBuffer(mTargetData, 0);
|
||||
}
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for VBO
|
||||
inline bool VertexBufferObject::checkOpenGLExtensions() {
|
||||
|
||||
// Check that OpenGL version is at least 1.5 or there the vertex buffer object extension exists
|
||||
return (GLEW_VERSION_1_5 || GL_ARB_vertex_buffer_object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
39
examples/common/opengl-framework/src/definitions.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef DEFINITIONS_H
|
||||
#define DEFINITIONS_H
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// ------------------- Type definitions ------------------- //
|
||||
typedef unsigned int uint;
|
||||
|
||||
// ------------------- Constants ------------------- //
|
||||
const float PI = 3.141592654f;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
76
examples/common/opengl-framework/src/maths/Color.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Structure Color
|
||||
// This structure represents a RGBA color.
|
||||
struct Color {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// RGBA color components
|
||||
float r, g, b, a;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Color() : r(1), g(1), b(1), a(1) {}
|
||||
|
||||
// Constructor
|
||||
Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
|
||||
|
||||
// Copy-constructor
|
||||
Color(const Color& color) : r(color.r), g(color.g), b(color.b), a(color.a) {}
|
||||
|
||||
// Destructor
|
||||
~Color() {}
|
||||
|
||||
// Return the black color
|
||||
static Color black() { return Color(0.0f, 0.0f, 0.0f, 1.0f);}
|
||||
|
||||
// Return the white color
|
||||
static Color white() { return Color(1.0f, 1.0f, 1.0f, 1.0f);}
|
||||
|
||||
// = operator
|
||||
Color& operator=(const Color& color) {
|
||||
if (&color != this) {
|
||||
r = color.r;
|
||||
g = color.g;
|
||||
b = color.b;
|
||||
a = color.a;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
279
examples/common/opengl-framework/src/maths/Matrix3.h
Normal file
|
@ -0,0 +1,279 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MATRIX3_H
|
||||
#define MATRIX3_H
|
||||
|
||||
// Libraries
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include "Vector3.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Matrix4
|
||||
// This class represents a 4x4 matrix
|
||||
class Matrix3 {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Elements of the matrix
|
||||
float m[3][3];
|
||||
|
||||
public :
|
||||
|
||||
// Constructor
|
||||
Matrix3() {
|
||||
setToNull();
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(float a1, float a2,
|
||||
float a3, float b1, float b2, float b3,
|
||||
float c1, float c2, float c3) {
|
||||
setAllValues(a1, a2, a3, b1, b2, b3, c1, c2, c3);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(float n[3][3]) {
|
||||
m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2];
|
||||
m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2];
|
||||
m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2];
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(const Vector3& a1, const Vector3& a2, const Vector3& a3) {
|
||||
m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x;
|
||||
m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y;
|
||||
m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(const Matrix3& matrix) {
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]);
|
||||
}
|
||||
|
||||
// Method to get a value in the matrix
|
||||
float getValue(int i, int j) const {
|
||||
assert(i>=0 && i<3 && j>=0 && j<3);
|
||||
return m[i][j];
|
||||
}
|
||||
|
||||
// Method to set a value in the matrix
|
||||
void setValue(int i, int j, float value) {
|
||||
assert(i>=0 && i<3 && j>=0 && j<3);
|
||||
m[i][j] = value;
|
||||
}
|
||||
|
||||
// Method to set all the values in the matrix
|
||||
void setAllValues(float a1, float a2, float a3, float b1, float b2, float b3,
|
||||
float c1, float c2, float c3) {
|
||||
m[0][0] = a1; m[0][1] = a2; m[0][2] = a3;
|
||||
m[1][0] = b1; m[1][1] = b2; m[1][2] = b3;
|
||||
m[2][0] = c1; m[2][1] = c2; m[2][2] = c3;
|
||||
}
|
||||
|
||||
// Return a column
|
||||
Vector3 getColumn(int i) const {
|
||||
assert(i>= 0 && i<3);
|
||||
return Vector3(m[0][i], m[1][i], m[2][i]);
|
||||
}
|
||||
|
||||
// Return the transpose matrix
|
||||
Matrix3 getTranspose() const {
|
||||
// Return the transpose matrix
|
||||
return Matrix3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
// Return the determinant of the matrix
|
||||
float getDeterminant() const {
|
||||
// Compute and return the determinant of the matrix
|
||||
return (m[0][0]*(m[1][1]*m[2][2]-m[2][1]*m[1][2]) - m[0][1]*(m[1][0]*m[2][2]-m[2][0]*m[1][2]) +
|
||||
m[0][2]*(m[1][0]*m[2][1]-m[2][0]*m[1][1]));
|
||||
}
|
||||
|
||||
// Return the trace of the matrix
|
||||
float getTrace() const {
|
||||
// Compute and return the trace
|
||||
return (m[0][0] + m[1][1] + m[2][2]);
|
||||
}
|
||||
|
||||
void setToNull() {
|
||||
m[0][0] = 0.0; m[0][1] = 0.0; m[0][2] = 0.0;
|
||||
m[1][0] = 0.0; m[1][1] = 0.0; m[1][2] = 0.0;
|
||||
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 0.0;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
Matrix3 zero;
|
||||
return *this == zero;
|
||||
}
|
||||
|
||||
// Set the matrix to the identity matrix
|
||||
void setToIdentity() {
|
||||
m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0;
|
||||
m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0;
|
||||
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0;
|
||||
}
|
||||
|
||||
bool isIdentity() const {
|
||||
Matrix3 I;
|
||||
I.setToIdentity();
|
||||
return ( *this == I );
|
||||
}
|
||||
|
||||
// Return the inverse matrix
|
||||
Matrix3 getInverse() const {
|
||||
|
||||
// Compute the determinant of the matrix
|
||||
float determinant = getDeterminant();
|
||||
|
||||
// Check if the determinant is equal to zero
|
||||
assert(determinant > std::numeric_limits<float>::epsilon());
|
||||
|
||||
float invDeterminant = 1.0f / determinant;
|
||||
Matrix3 tempMatrix((m[1][1]*m[2][2]-m[2][1]*m[1][2]), -(m[0][1]*m[2][2]-m[2][1]*m[0][2]), (m[0][1]*m[1][2]-m[0][2]*m[1][1]),
|
||||
-(m[1][0]*m[2][2]-m[2][0]*m[1][2]), (m[0][0]*m[2][2]-m[2][0]*m[0][2]), -(m[0][0]*m[1][2]-m[1][0]*m[0][2]),
|
||||
(m[1][0]*m[2][1]-m[2][0]*m[1][1]), -(m[0][0]*m[2][1]-m[2][0]*m[0][1]), (m[0][0]*m[1][1]-m[0][1]*m[1][0]));
|
||||
|
||||
// Return the inverse matrix
|
||||
return (tempMatrix * invDeterminant);
|
||||
}
|
||||
|
||||
// Display the matrix
|
||||
void print() const {
|
||||
for (int i=0; i<3; i++) {
|
||||
for (int j=0; j<3; j++) {
|
||||
std::cout << m[i][j] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Overloaded operator =
|
||||
Matrix3& operator=(const Matrix3& matrix) {
|
||||
if (&matrix != this) {
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Overloaded operator for addition
|
||||
Matrix3 operator+(const Matrix3& matrix2) {
|
||||
return Matrix3(m[0][0] + matrix2.m[0][0], m[0][1] + matrix2.m[0][1], m[0][2] + matrix2.m[0][2],
|
||||
m[1][0] + matrix2.m[1][0], m[1][1] + matrix2.m[1][1], m[1][2] + matrix2.m[1][2],
|
||||
m[2][0] + matrix2.m[2][0], m[2][1] + matrix2.m[2][1], m[2][2] + matrix2.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for substraction
|
||||
Matrix3 operator-(const Matrix3& matrix2) {
|
||||
return Matrix3(m[0][0] - matrix2.m[0][0], m[0][1] - matrix2.m[0][1], m[0][2] - matrix2.m[0][2],
|
||||
m[1][0] - matrix2.m[1][0], m[1][1] - matrix2.m[1][1], m[1][2] - matrix2.m[1][2],
|
||||
m[2][0] - matrix2.m[2][0], m[2][1] - matrix2.m[2][1], m[2][2] - matrix2.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for the negative of the matrix
|
||||
Matrix3 operator-() {
|
||||
return Matrix3(-m[0][0], -m[0][1], -m[0][2],
|
||||
-m[1][0], -m[1][1], -m[1][2],
|
||||
-m[2][0], -m[2][1], -m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for multiplication with a number
|
||||
Matrix3 operator*(float nb) {
|
||||
return Matrix3(m[0][0] * nb, m[0][1] * nb, m[0][2] * nb,
|
||||
m[1][0] * nb, m[1][1] * nb, m[1][2] * nb,
|
||||
m[2][0] * nb, m[2][1] * nb, m[2][2] * nb);
|
||||
}
|
||||
|
||||
// Overloaded operator for matrix multiplication
|
||||
Matrix3 operator*(const Matrix3& matrix2) {
|
||||
return Matrix3(m[0][0]*matrix2.m[0][0] + m[0][1]*matrix2.m[1][0] + m[0][2]*matrix2.m[2][0],
|
||||
m[0][0]*matrix2.m[0][1] + m[0][1]*matrix2.m[1][1] + m[0][2]*matrix2.m[2][1],
|
||||
m[0][0]*matrix2.m[0][2] + m[0][1]*matrix2.m[1][2] + m[0][2]*matrix2.m[2][2],
|
||||
m[1][0]*matrix2.m[0][0] + m[1][1]*matrix2.m[1][0] + m[1][2]*matrix2.m[2][0],
|
||||
m[1][0]*matrix2.m[0][1] + m[1][1]*matrix2.m[1][1] + m[1][2]*matrix2.m[2][1],
|
||||
m[1][0]*matrix2.m[0][2] + m[1][1]*matrix2.m[1][2] + m[1][2]*matrix2.m[2][2],
|
||||
m[2][0]*matrix2.m[0][0] + m[2][1]*matrix2.m[1][0] + m[2][2]*matrix2.m[2][0],
|
||||
m[2][0]*matrix2.m[0][1] + m[2][1]*matrix2.m[1][1] + m[2][2]*matrix2.m[2][1],
|
||||
m[2][0]*matrix2.m[0][2] + m[2][1]*matrix2.m[1][2] + m[2][2]*matrix2.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for multiplication with a vector
|
||||
Vector3 operator*(const Vector3& vector) {
|
||||
return Vector3(m[0][0]*vector.x + m[0][1]*vector.y + m[0][2]*vector.z,
|
||||
m[1][0]*vector.x + m[1][1]*vector.y + m[1][2]*vector.z,
|
||||
m[2][0]*vector.x + m[2][1]*vector.y + m[2][2]*vector.z);
|
||||
}
|
||||
|
||||
// Overloaded operator for equality condition
|
||||
bool operator==(const Matrix3& matrix) const {
|
||||
return (m[0][0] == matrix.m[0][0] && m[0][1] == matrix.m[0][1] && m[0][2] == matrix.m[0][2] &&
|
||||
m[1][0] == matrix.m[1][0] && m[1][1] == matrix.m[1][1] && m[1][2] == matrix.m[1][2] &&
|
||||
m[2][0] == matrix.m[2][0] && m[2][1] == matrix.m[2][1] && m[2][2] == matrix.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for the is different condition
|
||||
bool operator!= (const Matrix3& matrix) const {
|
||||
return !(*this == matrix);
|
||||
}
|
||||
|
||||
// Overloaded operator for addition with assignment
|
||||
Matrix3& operator+=(const Matrix3& matrix) {
|
||||
m[0][0] += matrix.m[0][0]; m[0][1] += matrix.m[0][1]; m[0][2] += matrix.m[0][2];
|
||||
m[1][0] += matrix.m[1][0]; m[1][1] += matrix.m[1][1]; m[1][2] += matrix.m[1][2];
|
||||
m[2][0] += matrix.m[2][0]; m[2][1] += matrix.m[2][1]; m[2][2] += matrix.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Overloaded operator for substraction with assignment
|
||||
Matrix3& operator-=(const Matrix3& matrix) {
|
||||
m[0][0] -= matrix.m[0][0]; m[0][1] -= matrix.m[0][1]; m[0][2] -= matrix.m[0][2];
|
||||
m[1][0] -= matrix.m[1][0]; m[1][1] -= matrix.m[1][1]; m[1][2] -= matrix.m[1][2];
|
||||
m[2][0] -= matrix.m[2][0]; m[2][1] -= matrix.m[2][1]; m[2][2] -= matrix.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Overloaded operator for multiplication with a number with assignment
|
||||
Matrix3& operator*=(float nb) {
|
||||
m[0][0] *= nb; m[0][1] *= nb; m[0][2] *= nb;
|
||||
m[1][0] *= nb; m[1][1] *= nb; m[1][2] *= nb;
|
||||
m[2][0] *= nb; m[2][1] *= nb; m[2][2] *= nb;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
427
examples/common/opengl-framework/src/maths/Matrix4.h
Normal file
|
@ -0,0 +1,427 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MATRIX4_H
|
||||
#define MATRIX4_H
|
||||
|
||||
// Libraries
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
#include "Matrix3.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Matrix4
|
||||
// This class represents a 4x4 matrix
|
||||
class Matrix4 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Elements of the matrix
|
||||
float m[4][4];
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Matrix4(float m_00=0, float m_01=0, float m_02=0, float m_03=0,
|
||||
float m_10=0, float m_11=0, float m_12=0, float m_13=0,
|
||||
float m_20=0, float m_21=0, float m_22=0, float m_23=0,
|
||||
float m_30=0, float m_31=0, float m_32=0, float m_33=0) {
|
||||
m[0][0] = m_00; m[0][1] = m_01; m[0][2] = m_02; m[0][3] = m_03;
|
||||
m[1][0] = m_10; m[1][1] = m_11; m[1][2] = m_12; m[1][3] = m_13;
|
||||
m[2][0] = m_20; m[2][1] = m_21; m[2][2] = m_22; m[2][3] = m_23;
|
||||
m[3][0] = m_30; m[3][1] = m_31; m[3][2] = m_32; m[3][3] = m_33;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(float n[4][4]) {
|
||||
m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2]; m[0][3]=n[0][3];
|
||||
m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2]; m[1][3]=n[1][3];
|
||||
m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2]; m[2][3]=n[2][3];
|
||||
m[3][0]=n[3][0]; m[3][1]=n[3][1]; m[3][2]=n[3][2]; m[3][3]=n[3][3];
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(const Vector3& a1, const Vector3& a2, const Vector3& a3) {
|
||||
m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f;
|
||||
m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f;
|
||||
m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f;
|
||||
m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(const Vector4& a1, const Vector4& a2, const Vector4& a3) {
|
||||
m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f;
|
||||
m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f;
|
||||
m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f;
|
||||
m[3][0] = a1.w; m[3][1] = a2.w; m[3][2] = a3.w; m[3][3] = 1.f;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(const Matrix4& matrix) {
|
||||
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3],
|
||||
matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]);
|
||||
}
|
||||
|
||||
// + operator
|
||||
Matrix4 operator+(const Matrix4 &n) const {
|
||||
return Matrix4(m[0][0]+n.m[0][0], m[0][1]+n.m[0][1], m[0][2]+n.m[0][2], m[0][3]+n.m[0][3],
|
||||
m[1][0]+n.m[1][0], m[1][1]+n.m[1][1], m[1][2]+n.m[1][2], m[1][3]+n.m[1][3],
|
||||
m[2][0]+n.m[2][0], m[2][1]+n.m[2][1], m[2][2]+n.m[2][2], m[2][3]+n.m[2][3],
|
||||
m[3][0]+n.m[3][0], m[3][1]+n.m[3][1], m[3][2]+n.m[3][2], m[3][3]+n.m[3][3]);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Matrix4& operator+=(const Matrix4 &n) {
|
||||
m[0][0]+=n.m[0][0]; m[0][1]+=n.m[0][1]; m[0][2]+=n.m[0][2]; m[0][3]+=n.m[0][3];
|
||||
m[1][0]+=n.m[1][0]; m[1][1]+=n.m[1][1]; m[1][2]+=n.m[1][2]; m[1][3]+=n.m[1][3];
|
||||
m[2][0]+=n.m[2][0]; m[2][1]+=n.m[2][1]; m[2][2]+=n.m[2][2]; m[2][3]+=n.m[2][3];
|
||||
m[3][0]+=n.m[3][0]; m[3][1]+=n.m[3][1]; m[3][2]+=n.m[3][2]; m[3][3]+=n.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Matrix4 operator-(const Matrix4 &n) const {
|
||||
return Matrix4(m[0][0]-n.m[0][0], m[0][1]-n.m[0][1], m[0][2]-n.m[0][2], m[0][3]-n.m[0][3],
|
||||
m[1][0]-n.m[1][0], m[1][1]-n.m[1][1], m[1][2]-n.m[1][2], m[1][3]-n.m[1][3],
|
||||
m[2][0]-n.m[2][0], m[2][1]-n.m[2][1], m[2][2]-n.m[2][2], m[2][3]-n.m[2][3],
|
||||
m[3][0]-n.m[3][0], m[3][1]-n.m[3][1], m[3][2]-n.m[3][2], m[3][3]-n.m[3][3]);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Matrix4& operator-=(const Matrix4 &n) {
|
||||
m[0][0]-=n.m[0][0]; m[0][1]-=n.m[0][1]; m[0][2]-=n.m[0][2]; m[0][3]-=n.m[0][3];
|
||||
m[1][0]-=n.m[1][0]; m[1][1]-=n.m[1][1]; m[1][2]-=n.m[1][2]; m[1][3]-=n.m[1][3];
|
||||
m[2][0]-=n.m[2][0]; m[2][1]-=n.m[2][1]; m[2][2]-=n.m[2][2]; m[2][3]-=n.m[2][3];
|
||||
m[3][0]-=n.m[3][0]; m[3][1]-=n.m[3][1]; m[3][2]-=n.m[3][2]; m[3][3]-=n.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = operator
|
||||
Matrix4& operator=(const Matrix4& matrix) {
|
||||
if (&matrix != this) {
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3],
|
||||
matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Matrix4 &n) const {
|
||||
return m[0][0]==n.m[0][0] && m[0][1]==n.m[0][1] && m[0][2]==n.m[0][2] && m[0][3]==n.m[0][3] &&
|
||||
m[1][0]==n.m[1][0] && m[1][1]==n.m[1][1] && m[1][2]==n.m[1][2] && m[1][3]==n.m[1][3] &&
|
||||
m[2][0]==n.m[2][0] && m[2][1]==n.m[2][1] && m[2][2]==n.m[2][2] && m[2][3]==n.m[2][3] &&
|
||||
m[3][0]==n.m[3][0] && m[3][1]==n.m[3][1] && m[3][2]==n.m[3][2] && m[3][3]==n.m[3][3];
|
||||
}
|
||||
|
||||
// * operator
|
||||
Matrix4 operator*(const Matrix4 &n) const {
|
||||
Matrix4 o;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for(int j = 0; j < 4; j++) {
|
||||
float v = 0;
|
||||
for(int k = 0; k < 4; k++) {
|
||||
v += m[i][k] * n.m[k][j];
|
||||
}
|
||||
o.m[i][j] = v;
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector3 operator*(const Vector3 &v) const {
|
||||
Vector3 u =Vector3(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]);
|
||||
float w = m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + m[3][3];
|
||||
return u/w;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector4 operator*(const Vector4 &v) const {
|
||||
Vector4 u = Vector4(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + v.w*m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + v.w*m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + v.w*m[2][3],
|
||||
m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + v.w*m[3][3]);
|
||||
if(u.w != 0)
|
||||
return u/u.w;
|
||||
else
|
||||
return u;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Matrix4 operator*(float f) const {
|
||||
return Matrix4(m[0][0]*f, m[0][1]*f, m[0][2]*f, m[0][3]*f,
|
||||
m[1][0]*f, m[1][1]*f, m[1][2]*f, m[1][3]*f,
|
||||
m[2][0]*f, m[2][1]*f, m[2][2]*f, m[2][3]*f,
|
||||
m[3][0]*f, m[3][1]*f, m[3][2]*f, m[3][3]*f);
|
||||
}
|
||||
|
||||
// * operator
|
||||
Matrix4 &operator*=(float f) {
|
||||
m[0][0]*=f; m[0][1]*=f; m[0][2]*=f; m[0][3]*=f;
|
||||
m[1][0]*=f; m[1][1]*=f; m[1][2]*=f; m[1][3]*=f;
|
||||
m[2][0]*=f; m[2][1]*=f; m[2][2]*=f; m[2][3]*=f;
|
||||
m[3][0]*=f; m[3][1]*=f; m[3][2]*=f; m[3][3]*=f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Matrix4 operator/(float f) const {
|
||||
assert(f!=0);
|
||||
return Matrix4(m[0][0]/f, m[0][1]/f, m[0][2]/f, m[0][3]/f,
|
||||
m[1][0]/f, m[1][1]/f, m[1][2]/f, m[1][3]/f,
|
||||
m[2][0]/f, m[2][1]/f, m[2][2]/f, m[2][3]/f,
|
||||
m[3][0]/f, m[3][1]/f, m[3][2]/f, m[3][3]/f);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Matrix4 &operator/=(float f) {
|
||||
assert(f!=0);
|
||||
m[0][0]/=f; m[0][1]/=f; m[0][2]/=f; m[0][3]/=f;
|
||||
m[1][0]/=f; m[1][1]/=f; m[1][2]/=f; m[1][3]/=f;
|
||||
m[2][0]/=f; m[2][1]/=f; m[2][2]/=f; m[2][3]/=f;
|
||||
m[3][0]/=f; m[3][1]/=f; m[3][2]/=f; m[3][3]/=f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Matrix4 operator-() const {
|
||||
return Matrix4(-m[0][0], -m[0][1], -m[0][2], -m[0][3],
|
||||
-m[1][0], -m[1][1], -m[1][2], -m[1][3],
|
||||
-m[2][0], -m[2][1], -m[2][2], -m[2][3],
|
||||
-m[3][0], -m[3][1], -m[3][2], -m[3][3]);
|
||||
}
|
||||
|
||||
// Return the transpose matrix
|
||||
Matrix4 getTranspose() const {
|
||||
return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
|
||||
m[0][1], m[1][1], m[2][1], m[3][1],
|
||||
m[0][2], m[1][2], m[2][2], m[3][2],
|
||||
m[0][3], m[1][3], m[2][3], m[3][3]);
|
||||
}
|
||||
|
||||
// Return the 3x3 upper-left matrix
|
||||
Matrix3 getUpperLeft3x3Matrix() const {
|
||||
return Matrix3(m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
|
||||
// Return the inversed matrix
|
||||
Matrix4 getInverse() const {
|
||||
int indxc[4], indxr[4];
|
||||
int ipiv[4] = { 0, 0, 0, 0 };
|
||||
float minv[4][4];
|
||||
float temp;
|
||||
|
||||
for (int s=0; s<4; s++) {
|
||||
for (int t=0; t<4; t++) {
|
||||
minv[s][t] = m[s][t];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int irow = -1, icol = -1;
|
||||
float big = 0.;
|
||||
// Choose pivot
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (ipiv[j] != 1) {
|
||||
for (int k = 0; k < 4; k++) {
|
||||
if (ipiv[k] == 0) {
|
||||
if (fabs(minv[j][k]) >= big) {
|
||||
big = float(fabs(minv[j][k]));
|
||||
irow = j;
|
||||
icol = k;
|
||||
}
|
||||
}
|
||||
else if (ipiv[k] > 1) {
|
||||
std::cout << "ERROR: Singular matrix in MatrixInvert\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++ipiv[icol];
|
||||
// Swap rows _irow_ and _icol_ for pivot
|
||||
if (irow != icol) {
|
||||
for (int k = 0; k < 4; ++k){
|
||||
temp = minv[irow][k];
|
||||
minv[irow][k] = minv[icol][k];
|
||||
minv[icol][k] = temp;
|
||||
}
|
||||
}
|
||||
indxr[i] = irow;
|
||||
indxc[i] = icol;
|
||||
if (minv[icol][icol] == 0.){
|
||||
std::cout << "Singular matrix in MatrixInvert\n";
|
||||
}
|
||||
// Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
|
||||
float pivinv = 1.f / minv[icol][icol];
|
||||
minv[icol][icol] = 1.f;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
minv[icol][j] *= pivinv;
|
||||
}
|
||||
|
||||
// Subtract this row from others to zero out their columns
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (j != icol) {
|
||||
float save = minv[j][icol];
|
||||
minv[j][icol] = 0;
|
||||
for (int k = 0; k < 4; k++) {
|
||||
minv[j][k] -= minv[icol][k]*save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Swap columns to reflect permutation
|
||||
for (int j = 3; j >= 0; j--) {
|
||||
if (indxr[j] != indxc[j]) {
|
||||
for (int k = 0; k < 4; k++){
|
||||
temp = minv[k][indxr[j]];
|
||||
minv[k][indxr[j]] = minv[k][indxc[j]];
|
||||
minv[k][indxc[j]] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Matrix4(minv);
|
||||
}
|
||||
|
||||
// Method to set all the values in the matrix
|
||||
void setAllValues(float a1, float a2, float a3, float a4,
|
||||
float b1, float b2, float b3, float b4,
|
||||
float c1, float c2, float c3, float c4,
|
||||
float d1, float d2, float d3, float d4) {
|
||||
m[0][0] = a1; m[0][1] = a2; m[0][2] = a3, m[0][3] = a4;
|
||||
m[1][0] = b1; m[1][1] = b2; m[1][2] = b3; m[1][3] = b4;
|
||||
m[2][0] = c1; m[2][1] = c2; m[2][2] = c3; m[2][3] = c4;
|
||||
m[3][0] = d1; m[3][1] = d2; m[3][2] = d3; m[3][3] = d4;
|
||||
}
|
||||
|
||||
// Set the matrix to the identity matrix
|
||||
Matrix4 setToIdentity() {
|
||||
m[0][0] = 1.f; m[0][1] = 0.f; m[0][2] = 0.f; m[0][3] = 0.f;
|
||||
m[1][0] = 0.f; m[1][1] = 1.f; m[1][2] = 0.f; m[1][3] = 0.f;
|
||||
m[2][0] = 0.f; m[2][1] = 0.f; m[2][2] = 1.f; m[2][3] = 0.f;
|
||||
m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Display the matrix
|
||||
void print() const {
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
std::cout << m[i][j];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the pointer to the data array of the matrix
|
||||
float* dataBlock() {
|
||||
return m[0];
|
||||
}
|
||||
|
||||
// Return the constant pointer to the data array of the matrix
|
||||
const float* dataBlock() const {
|
||||
return m[0];
|
||||
}
|
||||
|
||||
// Return a given value from the matrix
|
||||
float getValue(int i, int j) const {
|
||||
assert(i >= 0 && i<4 && j >= 0 && j<4);
|
||||
return m[i][j];
|
||||
}
|
||||
|
||||
// Return the trace of the matrix
|
||||
float getTrace() const {
|
||||
// Compute and return the trace
|
||||
return (m[0][0] + m[1][1] + m[2][2] + m[3][3]);
|
||||
}
|
||||
|
||||
// Return a 4x4 translation matrix
|
||||
static Matrix4 translationMatrix(const Vector3& v);
|
||||
|
||||
// Return a 4x4 rotation matrix
|
||||
static Matrix4 rotationMatrix(const Vector3& axis, float angle);
|
||||
};
|
||||
|
||||
// * operator
|
||||
inline Matrix4 operator*(float f, const Matrix4 & m) {
|
||||
return (m * f);
|
||||
}
|
||||
|
||||
// Return a 4x4 translation matrix
|
||||
inline Matrix4 Matrix4::translationMatrix(const Vector3& v) {
|
||||
return Matrix4(1, 0, 0, v.x,
|
||||
0, 1, 0, v.y,
|
||||
0, 0, 1, v.z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
// Return a 4x4 rotation matrix
|
||||
inline Matrix4 Matrix4::rotationMatrix(const Vector3& axis, float angle) {
|
||||
|
||||
float cosA = cos(angle);
|
||||
float sinA = sin(angle);
|
||||
Matrix4 rotationMatrix;
|
||||
rotationMatrix.setToIdentity();
|
||||
|
||||
rotationMatrix.m[0][0] = cosA + (1-cosA) * axis.x * axis.x;
|
||||
rotationMatrix.m[0][1] = (1-cosA) * axis.x * axis.y - axis.z * sinA;
|
||||
rotationMatrix.m[0][2] = (1-cosA) * axis.x * axis.z + axis.y * sinA;
|
||||
rotationMatrix.m[0][3] = 0.f;
|
||||
|
||||
rotationMatrix.m[1][0] = (1-cosA) * axis.x * axis.y + axis.z * sinA;
|
||||
rotationMatrix.m[1][1] = cosA + (1-cosA) * axis.y * axis.y;
|
||||
rotationMatrix.m[1][2] = (1-cosA) * axis.y * axis.z - axis.x * sinA;
|
||||
rotationMatrix.m[1][3] = 0.f;
|
||||
|
||||
rotationMatrix.m[2][0] = (1-cosA) * axis.x * axis.z - axis.y * sinA;
|
||||
rotationMatrix.m[2][1] = (1-cosA) * axis.y * axis.z + axis.x * sinA;
|
||||
rotationMatrix.m[2][2] = cosA + (1-cosA) * axis.z * axis.z;
|
||||
rotationMatrix.m[2][3] = 0.f;
|
||||
|
||||
rotationMatrix.m[3][0] = 0.f;
|
||||
rotationMatrix.m[3][1] = 0.f;
|
||||
rotationMatrix.m[3][2] = 0.f;
|
||||
rotationMatrix.m[3][3] = 1.f;
|
||||
|
||||
return rotationMatrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //_MATRIX4_H
|
159
examples/common/opengl-framework/src/maths/Vector2.h
Normal file
|
@ -0,0 +1,159 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VECTOR2_H
|
||||
#define VECTOR2_H
|
||||
|
||||
// Libraries
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Vector2
|
||||
// This class represents a 2D vector.
|
||||
class Vector2 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Components of the vector
|
||||
float x, y;
|
||||
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Vector2(float x=0, float y=0) : x(x), y(y) {}
|
||||
|
||||
// Constructor
|
||||
Vector2(const Vector2& vector) : x(vector.x), y(vector.y) {}
|
||||
|
||||
// + operator
|
||||
Vector2 operator+(const Vector2 &v) const {
|
||||
return Vector2(x + v.x, y + v.y);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Vector2& operator+=(const Vector2 &v) {
|
||||
x += v.x; y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector2 operator-(const Vector2 &v) const {
|
||||
return Vector2(x - v.x, y - v.y);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Vector2& operator-=(const Vector2 &v) {
|
||||
x -= v.x; y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = operator
|
||||
Vector2& operator=(const Vector2& vector) {
|
||||
if (&vector != this) {
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Vector2 &v) const {
|
||||
return x == v.x && y == v.y;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector2 operator*(float f) const {
|
||||
return Vector2(f*x, f*y);
|
||||
}
|
||||
|
||||
// *= operator
|
||||
Vector2 &operator*=(float f) {
|
||||
x *= f; y *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Vector2 operator/(float f) const {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
return Vector2(x * inv, y * inv);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Vector2 &operator/=(float f) {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
x *= inv; y *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector2 operator-() const {
|
||||
return Vector2(-x, -y);
|
||||
}
|
||||
|
||||
// [] operator
|
||||
float &operator[](int i) {
|
||||
assert(i >= 0 && i <= 1);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// Normalize the vector and return it
|
||||
Vector2 normalize() {
|
||||
float l = length();
|
||||
assert(l > 0);
|
||||
x /= l;
|
||||
y /= l;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Clamp the vector values between 0 and 1
|
||||
Vector2 clamp01() {
|
||||
if (x>1.f) x=1.f;
|
||||
else if (x<0.f) x=0.f;
|
||||
if (y>1.f) y=1.f;
|
||||
else if (y<0.f) y=0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the squared length of the vector
|
||||
float lengthSquared() const { return x*x + y*y; }
|
||||
|
||||
// Return the length of the vector
|
||||
float length() const { return sqrt(lengthSquared()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
203
examples/common/opengl-framework/src/maths/Vector3.h
Normal file
|
@ -0,0 +1,203 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef OPENGLFRAMEWORK_VECTOR3_H
|
||||
#define OPENGLFRAMEWORK_VECTOR3_H
|
||||
|
||||
// Libraries
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Vector3
|
||||
// This class represents a 3D vector.
|
||||
class Vector3 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Components of the vector
|
||||
float x, y, z;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Vector3(float x=0, float y=0, float z=0) : x(x), y(y), z(z) {}
|
||||
|
||||
// Constructor
|
||||
Vector3(const Vector3& vector) : x(vector.x), y(vector.y), z(vector.z) {}
|
||||
|
||||
// Constructor
|
||||
~Vector3() {}
|
||||
|
||||
// = operator
|
||||
Vector3& operator=(const Vector3& vector) {
|
||||
if (&vector != this) {
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
z = vector.z;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// + operator
|
||||
Vector3 operator+(const Vector3 &v) const {
|
||||
return Vector3(x + v.x, y + v.y, z + v.z);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Vector3& operator+=(const Vector3 &v) {
|
||||
x += v.x; y += v.y; z += v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector3 operator-(const Vector3 &v) const {
|
||||
return Vector3(x - v.x, y - v.y, z - v.z);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Vector3& operator-=(const Vector3 &v) {
|
||||
x -= v.x; y -= v.y; z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Vector3 &v) const {
|
||||
return x == v.x && y == v.y && z == v.z;
|
||||
}
|
||||
|
||||
// != operator
|
||||
bool operator!=(const Vector3 &v) const {
|
||||
return !( *this == v );
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector3 operator*(float f) const {
|
||||
return Vector3(f*x, f*y, f*z);
|
||||
}
|
||||
|
||||
// *= operator
|
||||
Vector3 &operator*=(float f) {
|
||||
x *= f; y *= f; z *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Vector3 operator/(float f) const {
|
||||
assert(f > std::numeric_limits<float>::epsilon() );
|
||||
float inv = 1.f / f;
|
||||
return Vector3(x * inv, y * inv, z * inv);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Vector3 &operator/=(float f) {
|
||||
assert(f > std::numeric_limits<float>::epsilon());
|
||||
float inv = 1.f / f;
|
||||
x *= inv; y *= inv; z *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector3 operator-() const {
|
||||
return Vector3(-x, -y, -z);
|
||||
}
|
||||
|
||||
// [] operator
|
||||
float &operator[](int i) {
|
||||
assert(i >= 0 && i <= 2);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
// [] operator
|
||||
const float &operator[](int i) const {
|
||||
assert(i >= 0 && i <= 2);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
// Cross product operator
|
||||
Vector3 cross(const Vector3 &v) const{
|
||||
return Vector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||
}
|
||||
|
||||
// Dot product operator
|
||||
float dot(const Vector3 &v) const{
|
||||
return x * v.x + y * v.y + z * v.z;
|
||||
}
|
||||
|
||||
// Normalize the vector and return it
|
||||
Vector3 normalize() {
|
||||
float l = length();
|
||||
if(l < std::numeric_limits<float>::epsilon() ) {
|
||||
assert(false);
|
||||
}
|
||||
x /= l;
|
||||
y /= l;
|
||||
z /= l;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return( x == 0. && y == 0. && z == 0. );
|
||||
}
|
||||
|
||||
// Clamp the values between 0 and 1
|
||||
Vector3 clamp01() {
|
||||
if (x>1.f) x=1.f;
|
||||
else if (x<0.f) x=0.f;
|
||||
if (y>1.f) y=1.f;
|
||||
else if (y<0.f) y=0.f;
|
||||
if (z>1.f) z=1.f;
|
||||
else if (z<0.f) z=0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the squared length of the vector
|
||||
float lengthSquared() const { return x*x + y*y + z*z; }
|
||||
|
||||
// Return the length of the vector
|
||||
float length() const { return sqrt(lengthSquared()); }
|
||||
};
|
||||
|
||||
inline Vector3 operator*(float f, const Vector3 & o) {
|
||||
return o*f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
167
examples/common/opengl-framework/src/maths/Vector4.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VECTOR4_H
|
||||
#define VECTOR4_H
|
||||
|
||||
// Libraries
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Vector4
|
||||
// This class represents a 4D vector.
|
||||
class Vector4 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Components of the vector
|
||||
float x, y, z, w;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Vector4(float x=0, float y=0, float z=0, float w=0) : x(x), y(y), z(z), w(w) {}
|
||||
|
||||
// Constructor
|
||||
Vector4(const Vector4& vector) : x(vector.x), y(vector.y), z(vector.z), w(vector.w) {}
|
||||
|
||||
// + operator
|
||||
Vector4 operator+(const Vector4 &v) const {
|
||||
return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Vector4& operator+=(const Vector4 &v) {
|
||||
x += v.x; y += v.y; z += v.z; w += v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector4 operator-(const Vector4 &v) const {
|
||||
return Vector4(x - v.x, y - v.y, z - v.z, w - v.w);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Vector4& operator-=(const Vector4 &v) {
|
||||
x -= v.x; y -= v.y; z -= v.z, w -=v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = operator
|
||||
Vector4& operator=(const Vector4& vector) {
|
||||
if (&vector != this) {
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
z = vector.z;
|
||||
w = vector.w;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Vector4 &v) const {
|
||||
return x == v.x && y == v.y && z == v.z && w == v.w;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector4 operator*(float f) const {
|
||||
return Vector4(f*x, f*y, f*z, f*w);
|
||||
}
|
||||
|
||||
// *= operator
|
||||
Vector4 &operator*=(float f) {
|
||||
x *= f; y *= f; z *= f; w *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Vector4 operator/(float f) const {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
return Vector4(x * inv, y * inv, z * inv, w * inv);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Vector4 &operator/=(float f) {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
x *= inv; y *= inv; z *= inv; w *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector4 operator-() const {
|
||||
return Vector4(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
// [] operator
|
||||
float &operator[](int i) {
|
||||
assert(i >= 0 && i <= 3);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
case 3: return w;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
// Dot product operator
|
||||
float dot(const Vector4 &v) const {
|
||||
return x * v.x + y * v.y + z * v.z + w * v.w;
|
||||
}
|
||||
|
||||
// Multiply two vectors by their components
|
||||
Vector4 componentMul(const Vector4 &v) const {
|
||||
return Vector4(x * v.x, y * v.y, z * v.z, w * v.w);
|
||||
}
|
||||
|
||||
// Clamp the values between 0 and 1
|
||||
Vector4 clamp01() {
|
||||
if (x>1.f) x=1.f;
|
||||
else if (x<0.f) x=0.f;
|
||||
if (y>1.f) y=1.f;
|
||||
else if (y<0.f) y=0.f;
|
||||
if (z>1.f) z=1.f;
|
||||
else if (z<0.f) z=0.f;
|
||||
if (w>1.f) w=1.f;
|
||||
else if (w<0.f) w=0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the squared length of the vector
|
||||
float lengthSquared() const { return x * x + y * y + z * z + w * w; }
|
||||
|
||||
// Return the length of the vector
|
||||
float length() const { return sqrt(lengthSquared()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //_VECTOR4_H
|
49
examples/common/opengl-framework/src/openglframework.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef OPENGL_FRAMEWORK_H
|
||||
#define OPENGL_FRAMEWORK_H
|
||||
|
||||
// Libraries
|
||||
#include "MeshReaderWriter.h"
|
||||
#include "TextureReaderWriter.h"
|
||||
#include "GlutViewer.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include "Mesh.h"
|
||||
#include "Shader.h"
|
||||
#include "Texture2D.h"
|
||||
#include "FrameBufferObject.h"
|
||||
#include "VertexBufferObject.h"
|
||||
#include "Shader.h"
|
||||
#include "maths/Color.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Vector4.h"
|
||||
#include "maths/Matrix4.h"
|
||||
#include "maths/Matrix3.h"
|
||||
#include "definitions.h"
|
||||
|
||||
#endif
|
32
examples/common/opengl-framework/src/shaders/depth.frag
Normal file
|
@ -0,0 +1,32 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
void main(void) {
|
||||
|
||||
// Compute the depth of the pixel
|
||||
float depth =
|
||||
|
||||
gl_FragColor = vec4(depth, depth, depth, 1);
|
||||
}
|
36
examples/common/opengl-framework/src/shaders/depth.vert
Normal file
|
@ -0,0 +1,36 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Uniform variables
|
||||
uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix
|
||||
uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix
|
||||
uniform mat4 projectionMatrix; // Projection matrix
|
||||
|
||||
void main(void) {
|
||||
|
||||
// Compute the clip-space vertex coordinates
|
||||
gl_Position = projectionMatrix * worldToCameraMatrix *
|
||||
modelToWorldMatrix * gl_Vertex;
|
||||
}
|
67
examples/common/opengl-framework/src/shaders/phong.frag
Normal file
|
@ -0,0 +1,67 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Uniform variables
|
||||
uniform vec3 lightAmbientColor; // Lights ambient color
|
||||
uniform vec3 light0PosCameraSpace; // Camera-space position of the light
|
||||
uniform vec3 light0DiffuseColor; // Light 0 diffuse color
|
||||
uniform vec3 light0SpecularColor; // Light 0 specular color
|
||||
uniform float shininess; // Shininess
|
||||
uniform sampler2D texture; // Texture
|
||||
uniform bool isTexture; // True if we need to use the texture
|
||||
uniform vec4 vertexColor; // Vertex color
|
||||
|
||||
// Varying variables
|
||||
varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex
|
||||
varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
|
||||
varying vec2 texCoords; // Texture coordinates
|
||||
|
||||
void main() {
|
||||
|
||||
// Compute the ambient term
|
||||
vec3 ambient = lightAmbientColor;
|
||||
|
||||
// Get the texture color
|
||||
vec3 textureColor = vertexColor.rgb;
|
||||
if (isTexture) textureColor = texture2D(texture, texCoords).rgb;
|
||||
|
||||
// Compute the surface normal vector
|
||||
vec3 N = normalize(vertexNormalCameraSpace);
|
||||
|
||||
// Compute the diffuse term of light 0
|
||||
vec3 L0 = normalize(light0PosCameraSpace - vertexPosCameraSpace);
|
||||
float diffuseFactor = max(dot(N, L0), 0.0);
|
||||
vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor;
|
||||
|
||||
// Compute the specular term of light 0
|
||||
vec3 V = normalize(-vertexPosCameraSpace);
|
||||
vec3 H0 = normalize(V + L0);
|
||||
float specularFactor = pow(max(dot(N, H0), 0.0), shininess);
|
||||
if (diffuseFactor < 0.0) specularFactor = 0.0;
|
||||
vec3 specular = light0SpecularColor * specularFactor;
|
||||
|
||||
// Compute the final color
|
||||
gl_FragColor = vec4(ambient + diffuse + specular, 1.0);
|
||||
}
|
50
examples/common/opengl-framework/src/shaders/phong.vert
Normal file
|
@ -0,0 +1,50 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Uniform variables
|
||||
uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix
|
||||
uniform mat4 projectionMatrix; // Projection matrix
|
||||
uniform mat3 normalMatrix; // Normal matrix
|
||||
|
||||
// Varying variables
|
||||
varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex
|
||||
varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
|
||||
varying vec2 texCoords; // Texture coordinates
|
||||
|
||||
void main() {
|
||||
|
||||
// Compute the vertex position
|
||||
vec4 positionCameraSpace = localToCameraMatrix * gl_Vertex;
|
||||
vertexPosCameraSpace = positionCameraSpace.xyz;
|
||||
|
||||
// Compute the world surface normal
|
||||
vertexNormalCameraSpace = normalMatrix * gl_Normal;
|
||||
|
||||
// Get the texture coordinates
|
||||
texCoords = gl_MultiTexCoord0.xy;
|
||||
|
||||
// Compute the clip-space vertex coordinates
|
||||
gl_Position = projectionMatrix * positionCameraSpace;
|
||||
}
|
35
examples/cubes/CMakeLists.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Minimum cmake version required
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(Cubes)
|
||||
|
||||
# Where to build the executables
|
||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/cubes")
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
# Copy the shaders used for the demo into the build directory
|
||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/")
|
||||
|
||||
# Source files
|
||||
SET(CUBES_SOURCES
|
||||
Cubes.cpp
|
||||
Scene.cpp
|
||||
Scene.cpp
|
||||
Scene.h
|
||||
"../common/Box.cpp"
|
||||
"../common/Box.h"
|
||||
"../common/Viewer.cpp"
|
||||
"../common/Viewer.h"
|
||||
)
|
||||
|
||||
# Create the executable
|
||||
ADD_EXECUTABLE(cubes ${CUBES_SOURCES})
|
||||
|
||||
# Link with libraries
|
||||
TARGET_LINK_LIBRARIES(cubes reactphysics3d openglframework)
|
158
examples/cubes/Cubes.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
#include "Viewer.h"
|
||||
|
||||
// Declarations
|
||||
void simulate();
|
||||
void display();
|
||||
void finish();
|
||||
void reshape(int width, int height);
|
||||
void mouseButton(int button, int state, int x, int y);
|
||||
void mouseMotion(int x, int y);
|
||||
void keyboard(unsigned char key, int x, int y);
|
||||
void init();
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Global variables
|
||||
Viewer* viewer;
|
||||
Scene* scene;
|
||||
|
||||
// Main function
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// Create and initialize the Viewer
|
||||
viewer = new Viewer();
|
||||
Vector2 windowsSize = Vector2(800, 600);
|
||||
Vector2 windowsPosition = Vector2(100, 100);
|
||||
bool initOK = viewer->init(argc, argv, "ReactPhysics3D Examples - Cubes", windowsSize, windowsPosition);
|
||||
if (!initOK) return 1;
|
||||
|
||||
// Create the scene
|
||||
scene = new Scene(viewer);
|
||||
|
||||
init();
|
||||
|
||||
// Glut Idle function that is continuously called
|
||||
glutIdleFunc(simulate);
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutMouseFunc(mouseButton);
|
||||
glutMotionFunc(mouseMotion);
|
||||
glutKeyboardFunc(keyboard);
|
||||
|
||||
#ifdef USE_FREEGLUT
|
||||
glutCloseFunc(finish);
|
||||
#else
|
||||
atexit(finish);
|
||||
#endif
|
||||
|
||||
// Glut main looop
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Simulate function
|
||||
void simulate() {
|
||||
|
||||
// Physics simulation
|
||||
scene->simulate();
|
||||
|
||||
viewer->computeFPS();
|
||||
|
||||
// Ask GLUT to render the scene
|
||||
glutPostRedisplay ();
|
||||
}
|
||||
|
||||
// Initialization
|
||||
void init() {
|
||||
|
||||
// Define the background color (black)
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Reshape function
|
||||
void reshape(int newWidth, int newHeight) {
|
||||
viewer->reshape(newWidth, newHeight);
|
||||
}
|
||||
|
||||
// Called when a mouse button event occurs
|
||||
void mouseButton(int button, int state, int x, int y) {
|
||||
viewer->mouseButtonEvent(button, state, x, y);
|
||||
}
|
||||
|
||||
// Called when a mouse motion event occurs
|
||||
void mouseMotion(int x, int y) {
|
||||
viewer->mouseMotionEvent(x, y);
|
||||
}
|
||||
|
||||
// Called when the user hits a special key on the keyboard
|
||||
void keyboard(unsigned char key, int x, int y) {
|
||||
switch(key) {
|
||||
|
||||
// Escape key
|
||||
case 27:
|
||||
#ifdef USE_FREEGLUT
|
||||
glutLeaveMainLoop();
|
||||
#endif
|
||||
break;
|
||||
|
||||
// Space bar
|
||||
case 32:
|
||||
scene->pauseContinueSimulation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// End of the application
|
||||
void finish() {
|
||||
|
||||
// Destroy the viewer and the scene
|
||||
delete viewer;
|
||||
delete scene;
|
||||
}
|
||||
|
||||
// Display the scene
|
||||
void display() {
|
||||
|
||||
// Render the scene
|
||||
scene->render();
|
||||
|
||||
// Display the FPS
|
||||
viewer->displayGUI();
|
||||
|
||||
// Swap the buffers
|
||||
glutSwapBuffers();
|
||||
|
||||
// Check the OpenGL errors
|
||||
GlutViewer::checkOpenGLErrors();
|
||||
}
|
||||
|
||||
|
191
examples/cubes/Scene.cpp
Normal file
|
@ -0,0 +1,191 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
|
||||
mPhongShader("shaders/phong.vert",
|
||||
"shaders/phong.frag"), mIsRunning(false) {
|
||||
|
||||
// Move the light 0
|
||||
mLight0.translateWorld(Vector3(7, 15, 15));
|
||||
|
||||
// Compute the radius and the center of the scene
|
||||
float radiusScene = 10.0f;
|
||||
openglframework::Vector3 center(0, 5, 0);
|
||||
|
||||
// Set the center of the scene
|
||||
mViewer->setScenePosition(center, radiusScene);
|
||||
|
||||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
// Time step for the physics simulation
|
||||
rp3d::decimal timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
||||
float radius = 2.0f;
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=0; i<NB_SPHERES; i++) {
|
||||
|
||||
// Position of the cubes
|
||||
float angle = i * 30.0f;
|
||||
openglframework::Vector3 position(radius * cos(angle),
|
||||
1 + i * (BOX_SIZE.y + 0.3f),
|
||||
0);
|
||||
|
||||
// Create a cube and a corresponding rigid in the dynamics world
|
||||
Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
cube->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = cube->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.4));
|
||||
|
||||
// Add the box the list of box in the scene
|
||||
mBoxes.push_back(cube);
|
||||
}
|
||||
|
||||
// Create the floor
|
||||
openglframework::Vector3 floorPosition(0, 0, 0);
|
||||
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
|
||||
|
||||
// The floor must be a non-moving rigid body
|
||||
mFloor->getRigidBody()->enableMotion(false);
|
||||
|
||||
// Change the material properties of the floor rigid body
|
||||
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.3));
|
||||
|
||||
// Start the simulation
|
||||
startSimulation();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Scene::~Scene() {
|
||||
|
||||
// Stop the physics simulation
|
||||
stopSimulation();
|
||||
|
||||
// Destroy the shader
|
||||
mPhongShader.destroy();
|
||||
|
||||
// Destroy all the cubes of the scene
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the cube
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy the rigid body of the floor
|
||||
mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody());
|
||||
|
||||
// Destroy the floor
|
||||
delete mFloor;
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void Scene::simulate() {
|
||||
|
||||
// If the physics simulation is running
|
||||
if (mIsRunning) {
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
mFloor->updateTransform();
|
||||
|
||||
// Set the color of the awake/sleeping bodies
|
||||
for (uint i=0; i<mBoxes.size(); i++) {
|
||||
if (mBoxes[i]->getRigidBody()->isSleeping()) {
|
||||
mBoxes[i]->setColor(Color(1, 0, 0, 1));
|
||||
}
|
||||
else {
|
||||
mBoxes[i]->setColor(Color(0, 1, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render the scene
|
||||
void Scene::render() {
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Get the world-space to camera-space matrix
|
||||
const Camera& camera = mViewer->getCamera();
|
||||
const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse();
|
||||
|
||||
// Bind the shader
|
||||
mPhongShader.bind();
|
||||
|
||||
// Set the variables of the shader
|
||||
mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix());
|
||||
mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin());
|
||||
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
|
||||
const Color& diffCol = mLight0.getDiffuseColor();
|
||||
const Color& specCol = mLight0.getSpecularColor();
|
||||
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
|
||||
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
|
||||
mPhongShader.setFloatUniform("shininess", 60.0f);
|
||||
|
||||
// Render all the cubes of the scene
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
(*it)->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render the floor
|
||||
mFloor->render(mPhongShader, worldToCameraMatrix);
|
||||
|
||||
// Unbind the shader
|
||||
mPhongShader.unbind();
|
||||
}
|
117
examples/cubes/Scene.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "Box.h"
|
||||
|
||||
// Constants
|
||||
const int NB_SPHERES = 20; // Number of boxes in the scene
|
||||
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
|
||||
const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
|
||||
const float BOX_MASS = 1.0f; // Box mass in kilograms
|
||||
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
|
||||
|
||||
// Class Scene
|
||||
class Scene {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Pointer to the viewer
|
||||
openglframework::GlutViewer* mViewer;
|
||||
|
||||
/// Light 0
|
||||
openglframework::Light mLight0;
|
||||
|
||||
/// Phong shader
|
||||
openglframework::Shader mPhongShader;
|
||||
|
||||
/// All the boxes of the scene
|
||||
std::vector<Box*> mBoxes;
|
||||
|
||||
/// Box for the floor
|
||||
Box* mFloor;
|
||||
|
||||
/// Dynamics world used for the physics simulation
|
||||
rp3d::DynamicsWorld* mDynamicsWorld;
|
||||
|
||||
/// True if the physics simulation is running
|
||||
bool mIsRunning;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Scene(openglframework::GlutViewer* viewer);
|
||||
|
||||
/// Destructor
|
||||
~Scene();
|
||||
|
||||
/// Take a step for the simulation
|
||||
void simulate();
|
||||
|
||||
/// Stop the simulation
|
||||
void stopSimulation();
|
||||
|
||||
/// Start the simulation
|
||||
void startSimulation();
|
||||
|
||||
/// Pause or continue simulation
|
||||
void pauseContinueSimulation();
|
||||
|
||||
/// Render the scene
|
||||
void render();
|
||||
};
|
||||
|
||||
// Stop the simulation
|
||||
inline void Scene::stopSimulation() {
|
||||
mDynamicsWorld->stop();
|
||||
mIsRunning = false;
|
||||
}
|
||||
|
||||
// Start the simulation
|
||||
inline void Scene::startSimulation() {
|
||||
mDynamicsWorld->start();
|
||||
mIsRunning = true;
|
||||
}
|
||||
|
||||
// Pause or continue simulation
|
||||
inline void Scene::pauseContinueSimulation() {
|
||||
if (mIsRunning) {
|
||||
stopSimulation();
|
||||
}
|
||||
else {
|
||||
startSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
# Minimum cmake version required
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(FallingCubes)
|
||||
|
||||
# Find Glut or Freeglut
|
||||
FIND_PACKAGE(GLUT)
|
||||
if (NOT GLUT_FOUND)
|
||||
# Find the Freeglut library
|
||||
FIND_PATH(FREEGLUT_INCLUDE_DIR NAMES GL/freeglut.h
|
||||
/usr/include/GL
|
||||
)
|
||||
FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut glut)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEGLUT DEFAULT_MSG FREEGLUT_LIBRARY FREEGLUT_INCLUDE_DIR)
|
||||
IF(FREEGLUT_FOUND)
|
||||
MESSAGE("Freeglut found")
|
||||
SET(FREEGLUT_LIBRARIES ${FREEGLUT_LIBRARY})
|
||||
SET(FREEGLUT_INCLUDE_DIRS ${FREEGLUT_INCLUDE_DIR})
|
||||
else()
|
||||
MESSAGE("Freeglut not found (required to build the examples)")
|
||||
SET(FREEGLUT_LIBRARIES)
|
||||
SET(FREEGLUT_INCLUDE_DIRS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Find OpenGL
|
||||
FIND_PACKAGE(OpenGL)
|
||||
if(OPENGL_FOUND)
|
||||
MESSAGE("OpenGL found")
|
||||
else()
|
||||
MESSAGE("OpenGL not found")
|
||||
endif()
|
||||
|
||||
# Headers
|
||||
if(GLUT_FOUND)
|
||||
INCLUDE_DIRECTORIES(${REACTPHYSICS3D_SOURCE_DIR}/src ${GLUT_INCLUDE_DIR})
|
||||
elseif(FREEGLUT_FOUND)
|
||||
INCLUDE_DIRECTORIES(${REACTPHYSICS3D_SOURCE_DIR}/src ${FREEGLUT_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Definitions
|
||||
if (FREEGLUT_FOUND)
|
||||
ADD_DEFINITIONS(-DUSE_FREEGLUT)
|
||||
endif()
|
||||
|
||||
# Create the example executable using the
|
||||
# compiled reactphysics3d static library
|
||||
ADD_EXECUTABLE(fallingcubes main.cpp Box.cpp Box.h)
|
||||
|
||||
if(GLUT_FOUND)
|
||||
TARGET_LINK_LIBRARIES(fallingcubes reactphysics3d ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
|
||||
elseif(FREEGLUT_FOUND)
|
||||
TARGET_LINK_LIBRARIES(fallingcubes reactphysics3d ${FREEGLUT_LIBRARY} ${OPENGL_LIBRARY})
|
||||
endif()
|
|
@ -1,248 +0,0 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include <stdlib.h>
|
||||
#include <reactphysics3d.h>
|
||||
#include "Box.h"
|
||||
|
||||
// Prototypes
|
||||
void init();
|
||||
void display();
|
||||
void simulate();
|
||||
void clean();
|
||||
void reshape(int w, int h);
|
||||
|
||||
// Use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constants
|
||||
const double FLOOR_SIZE = 20;
|
||||
const double FLOOR_THICKNESS = 0.02;
|
||||
|
||||
// Global variables
|
||||
DynamicsWorld* dynamicsWorld; // Dynamics world
|
||||
Box* boxes[2]; // Falling boxes
|
||||
BoxShape* collisionShapeBox1; // Collision shape of the first box
|
||||
BoxShape* collisionShapeBox2; // Collision shape of the second box
|
||||
BoxShape* collisionShapeFloor; // Collision shape of the floor
|
||||
RigidBody* floorRigidBody; // Rigid body corresponding the floor
|
||||
|
||||
|
||||
// Simulation function
|
||||
void simulate() {
|
||||
|
||||
// Update the physics simulation
|
||||
dynamicsWorld->update();
|
||||
|
||||
// Display the scene
|
||||
display();
|
||||
}
|
||||
|
||||
// Main function
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// Initialize GLUT
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
|
||||
glutInitWindowSize(800, 600);
|
||||
glutInitWindowPosition(100, 100);
|
||||
glutCreateWindow("ReactPhysics3D Example - Falling Cubes");
|
||||
|
||||
init();
|
||||
|
||||
glutIdleFunc(simulate);
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutMainLoop();
|
||||
|
||||
// Stop the physics simulation
|
||||
dynamicsWorld->stop();
|
||||
|
||||
clean();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialization function
|
||||
void init() {
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
// Light
|
||||
glShadeModel(GL_SMOOTH);
|
||||
GLfloat light_position[] = {5.0f, 5.0f, 5.0f, 1.0f};
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Gravity vector of the physics world
|
||||
Vector3 gravity(0.0, -9.81, 0.0);
|
||||
|
||||
// Timestep of the simulation
|
||||
decimal timeStep = 1.0/60.0;
|
||||
|
||||
// Create the dynamics world
|
||||
dynamicsWorld = new DynamicsWorld(gravity, timeStep);
|
||||
|
||||
// --- Create a falling box with a size of 1m and weight of 3kg --- //
|
||||
|
||||
float size = 1.0f;
|
||||
|
||||
// Initial position and orientation of the box
|
||||
Vector3 positionBox1(-2.0f, 7.0f, 0.0f);
|
||||
Quaternion orientationBox1(0.3, 1.0, 0.8, 0.0);
|
||||
Transform initTransform(positionBox1, orientationBox1);
|
||||
|
||||
// Create a box collision shape for the box (used for collision detection)
|
||||
collisionShapeBox1 = new BoxShape(Vector3(size/2.0f, size/2.0f, size/2.0f));
|
||||
|
||||
// Compute the inertia tensor of the box using the collision shape
|
||||
Matrix3x3 inertiaTensorBox1;
|
||||
float massBox1 = 3.0f;
|
||||
collisionShapeBox1->computeLocalInertiaTensor(inertiaTensorBox1, massBox1);
|
||||
|
||||
// Create the rigid body associated with the box in the dynamics world
|
||||
RigidBody* rigidBody = dynamicsWorld->createRigidBody(initTransform, massBox1,
|
||||
inertiaTensorBox1, collisionShapeBox1);
|
||||
|
||||
// Set the contact velocity restitution factor of the rigid body
|
||||
rigidBody->setRestitution(0.5f);
|
||||
|
||||
// Create the box object (used for display)
|
||||
boxes[0] = new Box(size, rigidBody);
|
||||
|
||||
// --- Create a second falling box with a size of 1.5m and weight of 4.5kg --- //
|
||||
|
||||
size = 1.5;
|
||||
|
||||
// Initial position and orientation of the box
|
||||
Vector3 positionBox2(2.0, 4.0, 0.0);
|
||||
Quaternion orientationBox2(1.0, 1.0, 0.5, 0.0);
|
||||
Transform initTransform2(positionBox2, orientationBox2);
|
||||
|
||||
// Create a box collision shape for the box (used for collision detection)
|
||||
collisionShapeBox2 = new BoxShape(Vector3(size/2.0f, size/2.0f, size/2.0f));
|
||||
|
||||
// Compute the inertia tensor using the collision shape
|
||||
Matrix3x3 inertiaTensorBox2;
|
||||
float massBox2 = 4.5f;
|
||||
collisionShapeBox2->computeLocalInertiaTensor(inertiaTensorBox2, massBox2);
|
||||
|
||||
// Create the rigid body associated with the box in the dynamcis world
|
||||
RigidBody* rigidBody2 = dynamicsWorld->createRigidBody(initTransform2, massBox2,
|
||||
inertiaTensorBox2, collisionShapeBox2);
|
||||
|
||||
// Set the contact velocity restitution factor of the rigid body
|
||||
rigidBody2->setRestitution(0.5);
|
||||
|
||||
// Create the box object (used for display)
|
||||
boxes[1] = new Box(size, rigidBody2);
|
||||
|
||||
// --- Create the rigid body corresponding to the floor --- //
|
||||
|
||||
// Initial position and orientation of the floor
|
||||
Vector3 positionFloor(0.0, 0.0, 0.0);
|
||||
Quaternion orientationFloor(0.0, 1.0, 0.0, 0.0);
|
||||
Transform initTransformFloor(positionFloor, orientationFloor);
|
||||
|
||||
// Create a box collision shape for the floor (used for collision detection)
|
||||
collisionShapeFloor = new BoxShape(Vector3(FLOOR_SIZE, FLOOR_THICKNESS, FLOOR_SIZE));
|
||||
|
||||
// Compute the inertia tensor of the floor using the collision shape
|
||||
float massFloor = 100.0f;
|
||||
rp3d::Matrix3x3 inertiaTensorFloor;
|
||||
collisionShapeFloor->computeLocalInertiaTensor(inertiaTensorFloor, massFloor);
|
||||
|
||||
// Create the rigid body associated with the floor in the dynamcis world
|
||||
floorRigidBody = dynamicsWorld->createRigidBody(initTransformFloor, massFloor,
|
||||
inertiaTensorFloor, collisionShapeFloor);
|
||||
|
||||
// The floor is a rigid body that cannot move
|
||||
floorRigidBody->setIsMotionEnabled(false);
|
||||
|
||||
// Set the contact velocity restitution factor of the floor
|
||||
floorRigidBody->setRestitution(0.5);
|
||||
|
||||
// Start the dynamics simulation
|
||||
dynamicsWorld->start();
|
||||
}
|
||||
|
||||
// Display function
|
||||
void display() {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Display each falling box of the scene
|
||||
for (int i=0; i<2; i++) {
|
||||
boxes[i]->draw();
|
||||
}
|
||||
|
||||
// Display the plane for the floor
|
||||
glBegin(GL_POLYGON);
|
||||
glNormal3f(0.0, 1.0, 0.0);
|
||||
glVertex3f(-FLOOR_SIZE/2, 0.0, -FLOOR_SIZE/2);
|
||||
glVertex3f(-FLOOR_SIZE/2, 0.0, FLOOR_SIZE/2);
|
||||
glVertex3f(FLOOR_SIZE/2, 0.0, FLOOR_SIZE/2);
|
||||
glVertex3f(FLOOR_SIZE/2, 0.0, -FLOOR_SIZE/2);
|
||||
glEnd();
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
// Reshape function
|
||||
void reshape(int w, int h) {
|
||||
float ratio = ((float)w / h);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glViewport(0, 0, w, h);
|
||||
gluPerspective(45, ratio,1,1000);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(20.0, 4.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
// Clean the memory allocation
|
||||
void clean() {
|
||||
|
||||
// Destroy the rigid bodies from the dynamics world
|
||||
dynamicsWorld->destroyRigidBody(boxes[0]->getRigidBodyPointer());
|
||||
dynamicsWorld->destroyRigidBody(boxes[1]->getRigidBodyPointer());
|
||||
dynamicsWorld->destroyRigidBody(floorRigidBody);
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete dynamicsWorld;
|
||||
|
||||
// Destroy the boxes
|
||||
delete boxes[0];
|
||||
delete boxes[1];
|
||||
|
||||
// Destroy the collision shapes
|
||||
delete collisionShapeBox1;
|
||||
delete collisionShapeBox2;
|
||||
delete collisionShapeFloor;
|
||||
}
|
34
examples/joints/CMakeLists.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Minimum cmake version required
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(Joints)
|
||||
|
||||
# Where to build the executables
|
||||
SET(EXECUTABLE_OUTPUT_PATH "${OUR_EXECUTABLE_OUTPUT_PATH}/joints")
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
# Copy the shaders used for the demo into the build directory
|
||||
FILE(COPY "${OPENGLFRAMEWORK_DIR}/src/shaders/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/shaders/")
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES("${OPENGLFRAMEWORK_DIR}/src/" "../common/")
|
||||
|
||||
# Source files
|
||||
SET(JOINTS_SOURCES
|
||||
Joints.cpp
|
||||
Scene.cpp
|
||||
Scene.h
|
||||
"../common/Box.cpp"
|
||||
"../common/Box.h"
|
||||
"../common/Viewer.cpp"
|
||||
"../common/Viewer.h"
|
||||
)
|
||||
|
||||
# Create the executable
|
||||
ADD_EXECUTABLE(joints ${JOINTS_SOURCES})
|
||||
|
||||
# Link with libraries
|
||||
TARGET_LINK_LIBRARIES(joints reactphysics3d openglframework)
|
157
examples/joints/Joints.cpp
Normal file
|
@ -0,0 +1,157 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
#include "Viewer.h"
|
||||
|
||||
// Declarations
|
||||
void simulate();
|
||||
void display();
|
||||
void finish();
|
||||
void reshape(int width, int height);
|
||||
void mouseButton(int button, int state, int x, int y);
|
||||
void mouseMotion(int x, int y);
|
||||
void keyboard(unsigned char key, int x, int y);
|
||||
void init();
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Global variables
|
||||
Viewer* viewer;
|
||||
Scene* scene;
|
||||
|
||||
// Main function
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// Create and initialize the Viewer
|
||||
viewer = new Viewer();
|
||||
Vector2 windowsSize = Vector2(800, 600);
|
||||
Vector2 windowsPosition = Vector2(100, 100);
|
||||
bool initOK = viewer->init(argc, argv, "ReactPhysics3D Examples - Joints", windowsSize, windowsPosition);
|
||||
if (!initOK) return 1;
|
||||
|
||||
// Create the scene
|
||||
scene = new Scene(viewer);
|
||||
|
||||
init();
|
||||
|
||||
// Glut Idle function that is continuously called
|
||||
glutIdleFunc(simulate);
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutMouseFunc(mouseButton);
|
||||
glutMotionFunc(mouseMotion);
|
||||
glutKeyboardFunc(keyboard);
|
||||
#ifdef USE_FREEGLUT
|
||||
glutCloseFunc(finish);
|
||||
#else
|
||||
atexit(finish);
|
||||
#endif
|
||||
|
||||
// Glut main looop
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Simulate function
|
||||
void simulate() {
|
||||
|
||||
// Physics simulation
|
||||
scene->simulate();
|
||||
|
||||
viewer->computeFPS();
|
||||
|
||||
// Ask GLUT to render the scene
|
||||
glutPostRedisplay ();
|
||||
}
|
||||
|
||||
// Initialization
|
||||
void init() {
|
||||
|
||||
// Define the background color (black)
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Reshape function
|
||||
void reshape(int newWidth, int newHeight) {
|
||||
viewer->reshape(newWidth, newHeight);
|
||||
}
|
||||
|
||||
// Called when a mouse button event occurs
|
||||
void mouseButton(int button, int state, int x, int y) {
|
||||
viewer->mouseButtonEvent(button, state, x, y);
|
||||
}
|
||||
|
||||
// Called when a mouse motion event occurs
|
||||
void mouseMotion(int x, int y) {
|
||||
viewer->mouseMotionEvent(x, y);
|
||||
}
|
||||
|
||||
// Called when the user hits a special key on the keyboard
|
||||
void keyboard(unsigned char key, int x, int y) {
|
||||
switch(key) {
|
||||
|
||||
// Escape key
|
||||
case 27:
|
||||
#ifdef USE_FREEGLUT
|
||||
glutLeaveMainLoop();
|
||||
#endif
|
||||
break;
|
||||
|
||||
// Space bar
|
||||
case 32:
|
||||
scene->pauseContinueSimulation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// End of the application
|
||||
void finish() {
|
||||
|
||||
// Destroy the viewer and the scene
|
||||
delete viewer;
|
||||
delete scene;
|
||||
}
|
||||
|
||||
// Display the scene
|
||||
void display() {
|
||||
|
||||
// Render the scene
|
||||
scene->render();
|
||||
|
||||
// Display the FPS
|
||||
viewer->displayGUI();
|
||||
|
||||
// Swap the buffers
|
||||
glutSwapBuffers();
|
||||
|
||||
// Check the OpenGL errors
|
||||
GlutViewer::checkOpenGLErrors();
|
||||
}
|
||||
|
||||
|
404
examples/joints/Scene.cpp
Normal file
|
@ -0,0 +1,404 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
#include <cmath>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
|
||||
mPhongShader("shaders/phong.vert",
|
||||
"shaders/phong.frag"), mIsRunning(false) {
|
||||
// Move the light 0
|
||||
mLight0.translateWorld(Vector3(7, 15, 15));
|
||||
|
||||
// Compute the radius and the center of the scene
|
||||
float radiusScene = 10.0f;
|
||||
openglframework::Vector3 center(0, 5, 0);
|
||||
|
||||
// Set the center of the scene
|
||||
mViewer->setScenePosition(center, radiusScene);
|
||||
|
||||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
// Time step for the physics simulation
|
||||
rp3d::decimal timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
|
||||
// Set the number of iterations of the constraint solver
|
||||
mDynamicsWorld->setNbIterationsVelocitySolver(15);
|
||||
|
||||
// Create the Ball-and-Socket joint
|
||||
createBallAndSocketJoints();
|
||||
|
||||
// Create the Slider joint
|
||||
createSliderJoint();
|
||||
|
||||
// Create the Hinge joint
|
||||
createPropellerHingeJoint();
|
||||
|
||||
// Create the Fixed joint
|
||||
createFixedJoints();
|
||||
|
||||
// Create the floor
|
||||
createFloor();
|
||||
|
||||
// Start the simulation
|
||||
startSimulation();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Scene::~Scene() {
|
||||
|
||||
// Stop the physics simulation
|
||||
stopSimulation();
|
||||
|
||||
// Destroy the shader
|
||||
mPhongShader.destroy();
|
||||
|
||||
// Destroy the joints
|
||||
mDynamicsWorld->destroyJoint(mSliderJoint);
|
||||
mDynamicsWorld->destroyJoint(mPropellerHingeJoint);
|
||||
mDynamicsWorld->destroyJoint(mFixedJoint1);
|
||||
mDynamicsWorld->destroyJoint(mFixedJoint2);
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES-1; i++) {
|
||||
mDynamicsWorld->destroyJoint(mBallAndSocketJoints[i]);
|
||||
}
|
||||
|
||||
// Destroy all the rigid bodies of the scene
|
||||
mDynamicsWorld->destroyRigidBody(mSliderJointBottomBox->getRigidBody());
|
||||
mDynamicsWorld->destroyRigidBody(mSliderJointTopBox->getRigidBody());
|
||||
mDynamicsWorld->destroyRigidBody(mPropellerBox->getRigidBody());
|
||||
mDynamicsWorld->destroyRigidBody(mFixedJointBox1->getRigidBody());
|
||||
mDynamicsWorld->destroyRigidBody(mFixedJointBox2->getRigidBody());
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
|
||||
mDynamicsWorld->destroyRigidBody(mBallAndSocketJointChainBoxes[i]->getRigidBody());
|
||||
}
|
||||
|
||||
delete mSliderJointBottomBox;
|
||||
delete mSliderJointTopBox;
|
||||
delete mPropellerBox;
|
||||
delete mFixedJointBox1;
|
||||
delete mFixedJointBox2;
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
|
||||
delete mBallAndSocketJointChainBoxes[i];
|
||||
}
|
||||
|
||||
// Destroy the floor
|
||||
mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody());
|
||||
delete mFloor;
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void Scene::simulate() {
|
||||
|
||||
// If the physics simulation is running
|
||||
if (mIsRunning) {
|
||||
|
||||
// Update the motor speed of the Slider Joint (to move up and down)
|
||||
long double motorSpeed = 2 * cos(mDynamicsWorld->getPhysicsTime() * 1.5);
|
||||
mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed));
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
mSliderJointBottomBox->updateTransform();
|
||||
mSliderJointTopBox->updateTransform();
|
||||
mPropellerBox->updateTransform();
|
||||
mFixedJointBox1->updateTransform();
|
||||
mFixedJointBox2->updateTransform();
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
|
||||
mBallAndSocketJointChainBoxes[i]->updateTransform();
|
||||
}
|
||||
|
||||
// Update the position and orientation of the floor
|
||||
mFloor->updateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
// Render the scene
|
||||
void Scene::render() {
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Get the world-space to camera-space matrix
|
||||
const Camera& camera = mViewer->getCamera();
|
||||
const openglframework::Matrix4 worldToCameraMatrix = camera.getTransformMatrix().getInverse();
|
||||
|
||||
// Bind the shader
|
||||
mPhongShader.bind();
|
||||
|
||||
// Set the variables of the shader
|
||||
mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin());
|
||||
mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix());
|
||||
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
|
||||
const Color& diffCol = mLight0.getDiffuseColor();
|
||||
const Color& specCol = mLight0.getSpecularColor();
|
||||
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
|
||||
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
|
||||
mPhongShader.setFloatUniform("shininess", 60.0f);
|
||||
|
||||
// Render all the boxes
|
||||
mSliderJointBottomBox->render(mPhongShader, worldToCameraMatrix);
|
||||
mSliderJointTopBox->render(mPhongShader, worldToCameraMatrix);
|
||||
mPropellerBox->render(mPhongShader, worldToCameraMatrix);
|
||||
mFixedJointBox1->render(mPhongShader, worldToCameraMatrix);
|
||||
mFixedJointBox2->render(mPhongShader, worldToCameraMatrix);
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
|
||||
mBallAndSocketJointChainBoxes[i]->render(mPhongShader, worldToCameraMatrix);
|
||||
}
|
||||
|
||||
// Render the floor
|
||||
mFloor->render(mPhongShader, worldToCameraMatrix);
|
||||
|
||||
// Unbind the shader
|
||||
mPhongShader.unbind();
|
||||
}
|
||||
|
||||
// Create the boxes and joints for the Ball-and-Socket joint example
|
||||
void Scene::createBallAndSocketJoints() {
|
||||
|
||||
// --------------- Create the boxes --------------- //
|
||||
|
||||
openglframework::Vector3 positionBox(0, 15, 5);
|
||||
openglframework::Vector3 boxDimension(1, 1, 1);
|
||||
const float boxMass = 0.5f;
|
||||
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES; i++) {
|
||||
|
||||
// Create a box and a corresponding rigid in the dynamics world
|
||||
mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass,
|
||||
mDynamicsWorld);
|
||||
|
||||
// The fist box cannot move
|
||||
if (i == 0) mBallAndSocketJointChainBoxes[i]->getRigidBody()->enableMotion(false);
|
||||
else mBallAndSocketJointChainBoxes[i]->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Add some angular velocity damping
|
||||
mBallAndSocketJointChainBoxes[i]->getRigidBody()->setAngularDamping(rp3d::decimal(0.2));
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mBallAndSocketJointChainBoxes[i]->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.4));
|
||||
|
||||
positionBox.y -= boxDimension.y + 0.5f;
|
||||
}
|
||||
|
||||
// --------------- Create the joints --------------- //
|
||||
|
||||
for (int i=0; i<NB_BALLSOCKETJOINT_BOXES-1; i++) {
|
||||
|
||||
// Create the joint info object
|
||||
rp3d::RigidBody* body1 = mBallAndSocketJointChainBoxes[i]->getRigidBody();
|
||||
rp3d::RigidBody* body2 = mBallAndSocketJointChainBoxes[i+1]->getRigidBody();
|
||||
rp3d::Vector3 body1Position = body1->getTransform().getPosition();
|
||||
rp3d::Vector3 body2Position = body2->getTransform().getPosition();
|
||||
const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body1Position + body2Position);
|
||||
rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace);
|
||||
|
||||
// Create the joint in the dynamics world
|
||||
mBallAndSocketJoints[i] = dynamic_cast<rp3d::BallAndSocketJoint*>(
|
||||
mDynamicsWorld->createJoint(jointInfo));
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the boxes and joint for the Slider joint example
|
||||
void Scene::createSliderJoint() {
|
||||
|
||||
// --------------- Create the first box --------------- //
|
||||
|
||||
// Position of the box
|
||||
openglframework::Vector3 positionBox1(0, 2.1f, 0);
|
||||
|
||||
// Create a box and a corresponding rigid in the dynamics world
|
||||
openglframework::Vector3 box1Dimension(2, 4, 2);
|
||||
mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The fist box cannot move
|
||||
mSliderJointBottomBox->getRigidBody()->enableMotion(false);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material1 = mSliderJointBottomBox->getRigidBody()->getMaterial();
|
||||
material1.setBounciness(0.4f);
|
||||
|
||||
// --------------- Create the second box --------------- //
|
||||
|
||||
// Position of the box
|
||||
openglframework::Vector3 positionBox2(0, 4.2f, 0);
|
||||
|
||||
// Create a box and a corresponding rigid in the dynamics world
|
||||
openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f);
|
||||
mSliderJointTopBox = new Box(box2Dimension, positionBox2 , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The second box is allowed to move
|
||||
mSliderJointTopBox->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
|
||||
material2.setBounciness(0.4f);
|
||||
|
||||
// --------------- Create the joint --------------- //
|
||||
|
||||
// Create the joint info object
|
||||
rp3d::RigidBody* body1 = mSliderJointBottomBox->getRigidBody();
|
||||
rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody();
|
||||
const rp3d::Vector3& body1Position = body1->getTransform().getPosition();
|
||||
const rp3d::Vector3& body2Position = body2->getTransform().getPosition();
|
||||
const rp3d::Vector3 anchorPointWorldSpace = rp3d::decimal(0.5) * (body2Position + body1Position);
|
||||
const rp3d::Vector3 sliderAxisWorldSpace = (body2Position - body1Position);
|
||||
rp3d::SliderJointInfo jointInfo(body1, body2, anchorPointWorldSpace, sliderAxisWorldSpace,
|
||||
rp3d::decimal(-1.7), rp3d::decimal(1.7));
|
||||
jointInfo.isMotorEnabled = true;
|
||||
jointInfo.motorSpeed = 0.0;
|
||||
jointInfo.maxMotorForce = 10000.0;
|
||||
jointInfo.isCollisionEnabled = false;
|
||||
|
||||
// Create the joint in the dynamics world
|
||||
mSliderJoint = dynamic_cast<rp3d::SliderJoint*>(mDynamicsWorld->createJoint(jointInfo));
|
||||
}
|
||||
|
||||
/// Create the boxes and joint for the Hinge joint example
|
||||
void Scene::createPropellerHingeJoint() {
|
||||
|
||||
// --------------- Create the propeller box --------------- //
|
||||
|
||||
// Position of the box
|
||||
openglframework::Vector3 positionBox1(0, 7, 0);
|
||||
|
||||
// Create a box and a corresponding rigid in the dynamics world
|
||||
openglframework::Vector3 boxDimension(10, 1, 1);
|
||||
mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The fist box cannot move
|
||||
mPropellerBox->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.4));
|
||||
|
||||
// --------------- Create the Hinge joint --------------- //
|
||||
|
||||
// Create the joint info object
|
||||
rp3d::RigidBody* body1 = mPropellerBox->getRigidBody();
|
||||
rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody();
|
||||
const rp3d::Vector3& body1Position = body1->getTransform().getPosition();
|
||||
const rp3d::Vector3& body2Position = body2->getTransform().getPosition();
|
||||
const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body2Position + body1Position);
|
||||
const rp3d::Vector3 hingeAxisWorldSpace(0, 1, 0);
|
||||
rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, hingeAxisWorldSpace);
|
||||
jointInfo.isMotorEnabled = true;
|
||||
jointInfo.motorSpeed = - rp3d::decimal(0.5) * PI;
|
||||
jointInfo.maxMotorTorque = rp3d::decimal(60.0);
|
||||
jointInfo.isCollisionEnabled = false;
|
||||
|
||||
// Create the joint in the dynamics world
|
||||
mPropellerHingeJoint = dynamic_cast<rp3d::HingeJoint*>(mDynamicsWorld->createJoint(jointInfo));
|
||||
}
|
||||
|
||||
/// Create the boxes and joints for the fixed joints
|
||||
void Scene::createFixedJoints() {
|
||||
|
||||
// --------------- Create the first box --------------- //
|
||||
|
||||
// Position of the box
|
||||
openglframework::Vector3 positionBox1(5, 7, 0);
|
||||
|
||||
// Create a box and a corresponding rigid in the dynamics world
|
||||
openglframework::Vector3 boxDimension(1.5, 1.5, 1.5);
|
||||
mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The fist box cannot move
|
||||
mFixedJointBox1->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
|
||||
material1.setBounciness(rp3d::decimal(0.4));
|
||||
|
||||
// --------------- Create the second box --------------- //
|
||||
|
||||
// Position of the box
|
||||
openglframework::Vector3 positionBox2(-5, 7, 0);
|
||||
|
||||
// Create a box and a corresponding rigid in the dynamics world
|
||||
mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The second box is allowed to move
|
||||
mFixedJointBox2->getRigidBody()->enableMotion(true);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
|
||||
material2.setBounciness(rp3d::decimal(0.4));
|
||||
|
||||
// --------------- Create the first fixed joint --------------- //
|
||||
|
||||
// Create the joint info object
|
||||
rp3d::RigidBody* body1 = mFixedJointBox1->getRigidBody();
|
||||
rp3d::RigidBody* propellerBody = mPropellerBox->getRigidBody();
|
||||
const rp3d::Vector3 anchorPointWorldSpace1(5, 7, 0);
|
||||
rp3d::FixedJointInfo jointInfo1(body1, propellerBody, anchorPointWorldSpace1);
|
||||
jointInfo1.isCollisionEnabled = false;
|
||||
|
||||
// Create the joint in the dynamics world
|
||||
mFixedJoint1 = dynamic_cast<rp3d::FixedJoint*>(mDynamicsWorld->createJoint(jointInfo1));
|
||||
|
||||
// --------------- Create the second fixed joint --------------- //
|
||||
|
||||
// Create the joint info object
|
||||
rp3d::RigidBody* body2 = mFixedJointBox2->getRigidBody();
|
||||
const rp3d::Vector3 anchorPointWorldSpace2(-5, 7, 0);
|
||||
rp3d::FixedJointInfo jointInfo2(body2, propellerBody, anchorPointWorldSpace2);
|
||||
jointInfo2.isCollisionEnabled = false;
|
||||
|
||||
// Create the joint in the dynamics world
|
||||
mFixedJoint2 = dynamic_cast<rp3d::FixedJoint*>(mDynamicsWorld->createJoint(jointInfo2));
|
||||
}
|
||||
|
||||
|
||||
// Create the floor
|
||||
void Scene::createFloor() {
|
||||
|
||||
// Create the floor
|
||||
openglframework::Vector3 floorPosition(0, 0, 0);
|
||||
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
|
||||
|
||||
// The floor must be a non-moving rigid body
|
||||
mFloor->getRigidBody()->enableMotion(false);
|
||||
|
||||
// Change the material properties of the rigid body
|
||||
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
|
||||
material.setBounciness(rp3d::decimal(0.3));
|
||||
}
|
171
examples/joints/Scene.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "Box.h"
|
||||
|
||||
// Constants
|
||||
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
|
||||
const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters
|
||||
const float BOX_MASS = 1.0f; // Box mass in kilograms
|
||||
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
|
||||
const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes
|
||||
const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes
|
||||
|
||||
// Class Scene
|
||||
class Scene {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Pointer to the viewer
|
||||
openglframework::GlutViewer* mViewer;
|
||||
|
||||
/// Light 0
|
||||
openglframework::Light mLight0;
|
||||
|
||||
/// Phong shader
|
||||
openglframework::Shader mPhongShader;
|
||||
|
||||
/// Boxes of Ball-And-Socket joint chain
|
||||
Box* mBallAndSocketJointChainBoxes[NB_BALLSOCKETJOINT_BOXES];
|
||||
|
||||
/// Boxes of the Hinge joint chain
|
||||
Box* mHingeJointChainBoxes[NB_HINGE_BOXES];
|
||||
|
||||
/// Ball-And-Socket joints of the chain
|
||||
rp3d::BallAndSocketJoint* mBallAndSocketJoints[NB_BALLSOCKETJOINT_BOXES-1];
|
||||
|
||||
/// Hinge joints of the chain
|
||||
rp3d::HingeJoint* mHingeJoints[NB_HINGE_BOXES-1];
|
||||
|
||||
/// Bottom box of the Slider joint
|
||||
Box* mSliderJointBottomBox;
|
||||
|
||||
/// Top box of the Slider joint
|
||||
Box* mSliderJointTopBox;
|
||||
|
||||
/// Slider joint
|
||||
rp3d::SliderJoint* mSliderJoint;
|
||||
|
||||
/// Propeller box
|
||||
Box* mPropellerBox;
|
||||
|
||||
/// Box 1 of Fixed joint
|
||||
Box* mFixedJointBox1;
|
||||
|
||||
/// Box 2 of Fixed joint
|
||||
Box* mFixedJointBox2;
|
||||
|
||||
/// Hinge joint
|
||||
rp3d::HingeJoint* mPropellerHingeJoint;
|
||||
|
||||
/// First Fixed joint
|
||||
rp3d::FixedJoint* mFixedJoint1;
|
||||
|
||||
/// Second Fixed joint
|
||||
rp3d::FixedJoint* mFixedJoint2;
|
||||
|
||||
/// Box for the floor
|
||||
Box* mFloor;
|
||||
|
||||
/// Dynamics world used for the physics simulation
|
||||
rp3d::DynamicsWorld* mDynamicsWorld;
|
||||
|
||||
/// True if the physics simulation is running
|
||||
bool mIsRunning;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Create the boxes and joints for the Ball-and-Socket joint example
|
||||
void createBallAndSocketJoints();
|
||||
|
||||
/// Create the boxes and joint for the Slider joint example
|
||||
void createSliderJoint();
|
||||
|
||||
/// Create the boxes and joint for the Hinge joint example
|
||||
void createPropellerHingeJoint();
|
||||
|
||||
/// Create the boxes and joint for the Fixed joint example
|
||||
void createFixedJoints();
|
||||
|
||||
/// Create the floor
|
||||
void createFloor();
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Scene(openglframework::GlutViewer* viewer);
|
||||
|
||||
/// Destructor
|
||||
~Scene();
|
||||
|
||||
/// Take a step for the simulation
|
||||
void simulate();
|
||||
|
||||
/// Stop the simulation
|
||||
void stopSimulation();
|
||||
|
||||
/// Start the simulation
|
||||
void startSimulation();
|
||||
|
||||
/// Pause or continue simulation
|
||||
void pauseContinueSimulation();
|
||||
|
||||
/// Render the scene
|
||||
void render();
|
||||
};
|
||||
|
||||
// Stop the simulation
|
||||
inline void Scene::stopSimulation() {
|
||||
mDynamicsWorld->stop();
|
||||
mIsRunning = false;
|
||||
}
|
||||
|
||||
// Start the simulation
|
||||
inline void Scene::startSimulation() {
|
||||
mDynamicsWorld->start();
|
||||
mIsRunning = true;
|
||||
}
|
||||
|
||||
// Pause or continue simulation
|
||||
inline void Scene::pauseContinueSimulation() {
|
||||
if (mIsRunning) {
|
||||
stopSimulation();
|
||||
}
|
||||
else {
|
||||
startSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -23,7 +23,7 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
// Libraries
|
||||
#include "Body.h"
|
||||
#include "../collision/shapes/CollisionShape.h"
|
||||
|
||||
|
@ -31,7 +31,9 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
Body::Body(bodyindex id) : mID(id) {
|
||||
Body::Body(bodyindex id)
|
||||
: mID(id), mIsAlreadyInIsland(false), mIsAllowedToSleep(true), mIsActive(true),
|
||||
mIsSleeping(false), mSleepTime(0) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef BODY_H
|
||||
#define BODY_H
|
||||
#ifndef REACTPHYSICS3D_BODY_H
|
||||
#define REACTPHYSICS3D_BODY_H
|
||||
|
||||
// Libraries
|
||||
#include <stdexcept>
|
||||
|
@ -47,6 +47,21 @@ class Body {
|
|||
/// ID of the body
|
||||
bodyindex mID;
|
||||
|
||||
/// True if the body has already been added in an island (for sleeping technique)
|
||||
bool mIsAlreadyInIsland;
|
||||
|
||||
/// True if the body is allowed to go to sleep for better efficiency
|
||||
bool mIsAllowedToSleep;
|
||||
|
||||
/// True if the body is active
|
||||
bool mIsActive;
|
||||
|
||||
/// True if the body is sleeping (for sleeping technique)
|
||||
bool mIsSleeping;
|
||||
|
||||
/// Elapsed time since the body velocity was bellow the sleep velocity
|
||||
decimal mSleepTime;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Private copy-constructor
|
||||
|
@ -68,6 +83,21 @@ class Body {
|
|||
/// Return the id of the body
|
||||
bodyindex getID() const;
|
||||
|
||||
/// Return whether or not the body is allowed to sleep
|
||||
bool isAllowedToSleep() const;
|
||||
|
||||
/// Set whether or not the body is allowed to go to sleep
|
||||
void setIsAllowedToSleep(bool isAllowedToSleep);
|
||||
|
||||
/// Return whether or not the body is sleeping
|
||||
bool isSleeping() const;
|
||||
|
||||
/// Return true if the body is active
|
||||
bool isActive() const;
|
||||
|
||||
/// Set the variable to know whether or not the body is sleeping
|
||||
virtual void setIsSleeping(bool isSleeping);
|
||||
|
||||
/// Smaller than operator
|
||||
bool operator<(const Body& body2) const;
|
||||
|
||||
|
@ -79,6 +109,10 @@ class Body {
|
|||
|
||||
/// Not equal operator
|
||||
bool operator!=(const Body& body2) const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class DynamicsWorld;
|
||||
};
|
||||
|
||||
// Return the id of the body
|
||||
|
@ -86,6 +120,43 @@ inline bodyindex Body::getID() const {
|
|||
return mID;
|
||||
}
|
||||
|
||||
// Return whether or not the body is allowed to sleep
|
||||
inline bool Body::isAllowedToSleep() const {
|
||||
return mIsAllowedToSleep;
|
||||
}
|
||||
|
||||
// Set whether or not the body is allowed to go to sleep
|
||||
inline void Body::setIsAllowedToSleep(bool isAllowedToSleep) {
|
||||
mIsAllowedToSleep = isAllowedToSleep;
|
||||
|
||||
if (!mIsAllowedToSleep) setIsSleeping(false);
|
||||
}
|
||||
|
||||
// Return whether or not the body is sleeping
|
||||
inline bool Body::isSleeping() const {
|
||||
return mIsSleeping;
|
||||
}
|
||||
|
||||
// Return true if the body is active
|
||||
inline bool Body::isActive() const {
|
||||
return mIsActive;
|
||||
}
|
||||
|
||||
// Set the variable to know whether or not the body is sleeping
|
||||
inline void Body::setIsSleeping(bool isSleeping) {
|
||||
|
||||
if (isSleeping) {
|
||||
mSleepTime = decimal(0.0);
|
||||
}
|
||||
else {
|
||||
if (mIsSleeping) {
|
||||
mSleepTime = decimal(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
mIsSleeping = isSleeping;
|
||||
}
|
||||
|
||||
// Smaller than operator
|
||||
inline bool Body::operator<(const Body& body2) const {
|
||||
return (mID < body2.mID);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "CollisionBody.h"
|
||||
#include "../engine/ContactManifold.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
@ -32,8 +33,8 @@ using namespace reactphysics3d;
|
|||
// Constructor
|
||||
CollisionBody::CollisionBody(const Transform& transform, CollisionShape *collisionShape,
|
||||
bodyindex id)
|
||||
: Body(id), mCollisionShape(collisionShape), mTransform(transform),
|
||||
mIsActive(true), mHasMoved(false) {
|
||||
: Body(id), mCollisionShape(collisionShape), mTransform(transform),
|
||||
mHasMoved(false), mContactManifoldsList(NULL) {
|
||||
|
||||
assert(collisionShape);
|
||||
|
||||
|
@ -50,5 +51,24 @@ CollisionBody::CollisionBody(const Transform& transform, CollisionShape *collisi
|
|||
|
||||
// Destructor
|
||||
CollisionBody::~CollisionBody() {
|
||||
|
||||
assert(mContactManifoldsList == NULL);
|
||||
}
|
||||
|
||||
// Reset the contact manifold lists
|
||||
void CollisionBody::resetContactManifoldsList(MemoryAllocator& memoryAllocator) {
|
||||
|
||||
// Delete the linked list of contact manifolds of that body
|
||||
ContactManifoldListElement* currentElement = mContactManifoldsList;
|
||||
while (currentElement != NULL) {
|
||||
ContactManifoldListElement* nextElement = currentElement->next;
|
||||
|
||||
// Delete the current element
|
||||
currentElement->ContactManifoldListElement::~ContactManifoldListElement();
|
||||
memoryAllocator.release(currentElement, sizeof(ContactManifoldListElement));
|
||||
|
||||
currentElement = nextElement;
|
||||
}
|
||||
mContactManifoldsList = NULL;
|
||||
|
||||
assert(mContactManifoldsList == NULL);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef COLLISION_BODY_H
|
||||
#define COLLISION_BODY_H
|
||||
#ifndef REACTPHYSICS3D_COLLISION_BODY_H
|
||||
#define REACTPHYSICS3D_COLLISION_BODY_H
|
||||
|
||||
// Libraries
|
||||
#include <stdexcept>
|
||||
|
@ -33,11 +33,15 @@
|
|||
#include "../mathematics/Transform.h"
|
||||
#include "../collision/shapes/AABB.h"
|
||||
#include "../collision/shapes/CollisionShape.h"
|
||||
#include "../memory/MemoryAllocator.h"
|
||||
#include "../configuration.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Class declarations
|
||||
struct ContactManifoldListElement;
|
||||
|
||||
// Class CollisionBody
|
||||
/**
|
||||
* This class represents a body that is able to collide with others
|
||||
|
@ -61,9 +65,6 @@ class CollisionBody : public Body {
|
|||
/// Interpolation factor used for the state interpolation
|
||||
decimal mInterpolationFactor;
|
||||
|
||||
/// True if the body is active (not sleeping)
|
||||
bool mIsActive;
|
||||
|
||||
/// True if the body is able to move
|
||||
bool mIsMotionEnabled;
|
||||
|
||||
|
@ -76,6 +77,9 @@ class CollisionBody : public Body {
|
|||
/// True if the body has moved during the last frame
|
||||
bool mHasMoved;
|
||||
|
||||
/// First element of the linked list of contact manifolds involving this body
|
||||
ContactManifoldListElement* mContactManifoldsList;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Private copy-constructor
|
||||
|
@ -84,6 +88,15 @@ class CollisionBody : public Body {
|
|||
/// Private assignment operator
|
||||
CollisionBody& operator=(const CollisionBody& body);
|
||||
|
||||
/// Reset the contact manifold lists
|
||||
void resetContactManifoldsList(MemoryAllocator& memoryAllocator);
|
||||
|
||||
/// Update the old transform with the current one.
|
||||
void updateOldTransform();
|
||||
|
||||
/// Update the Axis-Aligned Bounding Box coordinates
|
||||
void updateAABB();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -94,24 +107,12 @@ class CollisionBody : public Body {
|
|||
/// Destructor
|
||||
virtual ~CollisionBody();
|
||||
|
||||
/// Return true if the body has moved during the last frame
|
||||
bool getHasMoved() const;
|
||||
|
||||
/// Set the hasMoved variable (true if the body has moved during the last frame)
|
||||
void setHasMoved(bool hasMoved);
|
||||
|
||||
/// Return the collision shape
|
||||
CollisionShape* getCollisionShape() const;
|
||||
|
||||
/// Set the collision shape
|
||||
void setCollisionShape(CollisionShape* collisionShape);
|
||||
|
||||
/// Return true for an active body
|
||||
bool getIsActive() const;
|
||||
|
||||
/// Set the isActive variable
|
||||
void setIsActive(bool isActive);
|
||||
|
||||
/// Return the current position and orientation
|
||||
const Transform& getTransform() const;
|
||||
|
||||
|
@ -127,35 +128,27 @@ class CollisionBody : public Body {
|
|||
/// Set the interpolation factor of the body
|
||||
void setInterpolationFactor(decimal factor);
|
||||
|
||||
/// Return if the rigid body can move
|
||||
bool getIsMotionEnabled() const;
|
||||
/// Return true if the rigid body is allowed to move
|
||||
bool isMotionEnabled() const;
|
||||
|
||||
/// Set the value to true if the body can move
|
||||
void setIsMotionEnabled(bool isMotionEnabled);
|
||||
/// Enable/disable the motion of the body
|
||||
void enableMotion(bool isMotionEnabled);
|
||||
|
||||
/// Return true if the body can collide with others bodies
|
||||
bool getIsCollisionEnabled() const;
|
||||
bool isCollisionEnabled() const;
|
||||
|
||||
/// Set the isCollisionEnabled value
|
||||
void setIsCollisionEnabled(bool isCollisionEnabled);
|
||||
/// Enable/disable the collision with this body
|
||||
void enableCollision(bool isCollisionEnabled);
|
||||
|
||||
/// Update the old transform with the current one.
|
||||
void updateOldTransform();
|
||||
/// Return the first element of the linked list of contact manifolds involving this body
|
||||
const ContactManifoldListElement* getContactManifoldsLists() const;
|
||||
|
||||
/// Update the Axis-Aligned Bounding Box coordinates
|
||||
void updateAABB();
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class DynamicsWorld;
|
||||
friend class CollisionDetection;
|
||||
};
|
||||
|
||||
// Return true if the body has moved during the last frame
|
||||
inline bool CollisionBody::getHasMoved() const {
|
||||
return mHasMoved;
|
||||
}
|
||||
|
||||
// Set the hasMoved variable (true if the body has moved during the last frame)
|
||||
inline void CollisionBody::setHasMoved(bool hasMoved) {
|
||||
mHasMoved = hasMoved;
|
||||
}
|
||||
|
||||
// Return the collision shape
|
||||
inline CollisionShape* CollisionBody::getCollisionShape() const {
|
||||
assert(mCollisionShape);
|
||||
|
@ -168,16 +161,6 @@ inline void CollisionBody::setCollisionShape(CollisionShape* collisionShape) {
|
|||
mCollisionShape = collisionShape;
|
||||
}
|
||||
|
||||
// Return true if the body is active
|
||||
inline bool CollisionBody::getIsActive() const {
|
||||
return mIsActive;
|
||||
}
|
||||
|
||||
// Set the isActive variable
|
||||
inline void CollisionBody::setIsActive(bool isActive) {
|
||||
mIsActive = isActive;
|
||||
}
|
||||
|
||||
// Return the interpolated transform for rendering
|
||||
inline Transform CollisionBody::getInterpolatedTransform() const {
|
||||
return Transform::interpolateTransforms(mOldTransform, mTransform, mInterpolationFactor);
|
||||
|
@ -189,13 +172,13 @@ inline void CollisionBody::setInterpolationFactor(decimal factor) {
|
|||
mInterpolationFactor = factor;
|
||||
}
|
||||
|
||||
// Return if the rigid body can move
|
||||
inline bool CollisionBody::getIsMotionEnabled() const {
|
||||
// Return true if the rigid body is allowed to move
|
||||
inline bool CollisionBody::isMotionEnabled() const {
|
||||
return mIsMotionEnabled;
|
||||
}
|
||||
|
||||
// Set the value to true if the body can move
|
||||
inline void CollisionBody::setIsMotionEnabled(bool isMotionEnabled) {
|
||||
// Enable/disable the motion of the body
|
||||
inline void CollisionBody::enableMotion(bool isMotionEnabled) {
|
||||
mIsMotionEnabled = isMotionEnabled;
|
||||
}
|
||||
|
||||
|
@ -208,7 +191,7 @@ inline const Transform& CollisionBody::getTransform() const {
|
|||
inline void CollisionBody::setTransform(const Transform& transform) {
|
||||
|
||||
// Check if the body has moved
|
||||
if (this->mTransform != transform) {
|
||||
if (mTransform != transform) {
|
||||
mHasMoved = true;
|
||||
}
|
||||
|
||||
|
@ -221,12 +204,12 @@ inline const AABB& CollisionBody::getAABB() const {
|
|||
}
|
||||
|
||||
// Return true if the body can collide with others bodies
|
||||
inline bool CollisionBody::getIsCollisionEnabled() const {
|
||||
inline bool CollisionBody::isCollisionEnabled() const {
|
||||
return mIsCollisionEnabled;
|
||||
}
|
||||
|
||||
// Set the isCollisionEnabled value
|
||||
inline void CollisionBody::setIsCollisionEnabled(bool isCollisionEnabled) {
|
||||
// Enable/disable the collision with this body
|
||||
inline void CollisionBody::enableCollision(bool isCollisionEnabled) {
|
||||
mIsCollisionEnabled = isCollisionEnabled;
|
||||
}
|
||||
|
||||
|
@ -239,12 +222,15 @@ inline void CollisionBody::updateOldTransform() {
|
|||
// Update the rigid body in order to reflect a change in the body state
|
||||
inline void CollisionBody::updateAABB() {
|
||||
|
||||
// TODO : An AABB should not be updated every frame but only if the body has moved
|
||||
|
||||
// Update the AABB
|
||||
mCollisionShape->updateAABB(mAabb, mTransform);
|
||||
}
|
||||
|
||||
// Return the first element of the linked list of contact manifolds involving this body
|
||||
inline const ContactManifoldListElement* CollisionBody::getContactManifoldsLists() const {
|
||||
return mContactManifoldsList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,25 +25,54 @@
|
|||
|
||||
// Libraries
|
||||
#include "RigidBody.h"
|
||||
#include "constraint/Joint.h"
|
||||
#include "../collision/shapes/CollisionShape.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal,
|
||||
// Constructor
|
||||
RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal,
|
||||
CollisionShape *collisionShape, bodyindex id)
|
||||
: CollisionBody(transform, collisionShape, id), mInertiaTensorLocal(inertiaTensorLocal),
|
||||
mMass(mass), mInertiaTensorLocalInverse(inertiaTensorLocal.getInverse()),
|
||||
mMassInverse(decimal(1.0) / mass), mFrictionCoefficient(DEFAULT_FRICTION_COEFFICIENT) {
|
||||
|
||||
mRestitution = decimal(1.0);
|
||||
mMassInverse(decimal(1.0) / mass), mIsGravityEnabled(true),
|
||||
mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)), mJointsList(NULL) {
|
||||
|
||||
assert(collisionShape);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
RigidBody::~RigidBody() {
|
||||
|
||||
assert(mJointsList == NULL);
|
||||
}
|
||||
|
||||
// Remove a joint from the joints list
|
||||
void RigidBody::removeJointFromJointsList(MemoryAllocator& memoryAllocator, const Joint* joint) {
|
||||
|
||||
assert(joint != NULL);
|
||||
assert(mJointsList != NULL);
|
||||
|
||||
// Remove the joint from the linked list of the joints of the first body
|
||||
if (mJointsList->joint == joint) { // If the first element is the one to remove
|
||||
JointListElement* elementToRemove = mJointsList;
|
||||
mJointsList = elementToRemove->next;
|
||||
elementToRemove->JointListElement::~JointListElement();
|
||||
memoryAllocator.release(elementToRemove, sizeof(JointListElement));
|
||||
}
|
||||
else { // If the element to remove is not the first one in the list
|
||||
JointListElement* currentElement = mJointsList;
|
||||
while (currentElement->next != NULL) {
|
||||
if (currentElement->next->joint == joint) {
|
||||
JointListElement* elementToRemove = currentElement->next;
|
||||
currentElement->next = elementToRemove->next;
|
||||
elementToRemove->JointListElement::~JointListElement();
|
||||
memoryAllocator.release(elementToRemove, sizeof(JointListElement));
|
||||
break;
|
||||
}
|
||||
currentElement = currentElement->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,17 +23,23 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef RIGID_BODY_H
|
||||
#define RIGID_BODY_H
|
||||
#ifndef REACTPHYSICS3D_RIGID_BODY_H
|
||||
#define REACTPHYSICS3D_RIGID_BODY_H
|
||||
|
||||
// Libraries
|
||||
#include <cassert>
|
||||
#include "CollisionBody.h"
|
||||
#include "../engine/Material.h"
|
||||
#include "../mathematics/mathematics.h"
|
||||
#include "../memory/MemoryAllocator.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Class declarations
|
||||
struct JointListElement;
|
||||
class Joint;
|
||||
|
||||
// Class RigidBody
|
||||
/**
|
||||
* This class represents a rigid body of the physics
|
||||
|
@ -73,11 +79,20 @@ class RigidBody : public CollisionBody {
|
|||
/// Inverse of the mass of the body
|
||||
decimal mMassInverse;
|
||||
|
||||
/// Coefficient of restitution (between 0 and 1) where 1 is for a very bouncy body
|
||||
decimal mRestitution;
|
||||
/// True if the gravity needs to be applied to this rigid body
|
||||
bool mIsGravityEnabled;
|
||||
|
||||
/// Friction coefficient
|
||||
decimal mFrictionCoefficient;
|
||||
/// Material properties of the rigid body
|
||||
Material mMaterial;
|
||||
|
||||
/// Linear velocity damping factor
|
||||
decimal mLinearDamping;
|
||||
|
||||
/// Angular velocity damping factor
|
||||
decimal mAngularDamping;
|
||||
|
||||
/// First element of the linked list of joints involving this body
|
||||
JointListElement* mJointsList;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
|
@ -87,6 +102,12 @@ class RigidBody : public CollisionBody {
|
|||
/// Private assignment operator
|
||||
RigidBody& operator=(const RigidBody& body);
|
||||
|
||||
/// Remove a joint from the joints list
|
||||
void removeJointFromJointsList(MemoryAllocator& memoryAllocator, const Joint* joint);
|
||||
|
||||
/// Set the inverse of the mass
|
||||
void setMassInverse(decimal massInverse);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -116,26 +137,11 @@ class RigidBody : public CollisionBody {
|
|||
/// Set the angular velocity
|
||||
void setAngularVelocity(const Vector3& angularVelocity);
|
||||
|
||||
/// Set the inverse of the mass
|
||||
void setMassInverse(decimal massInverse);
|
||||
|
||||
/// Return the current external force of the body
|
||||
Vector3 getExternalForce() const;
|
||||
|
||||
/// Set the current external force on the body
|
||||
void setExternalForce(const Vector3& force);
|
||||
|
||||
/// Return the current external torque of the body
|
||||
Vector3 getExternalTorque() const;
|
||||
|
||||
/// Set the current external torque of the body
|
||||
void setExternalTorque(const Vector3& torque);
|
||||
|
||||
/// Return the inverse of the mass of the body
|
||||
decimal getMassInverse() const;
|
||||
|
||||
/// Return the local inertia tensor of the body (in body coordinates)
|
||||
Matrix3x3 getInertiaTensorLocal() const;
|
||||
const Matrix3x3& getInertiaTensorLocal() const;
|
||||
|
||||
/// Set the local inertia tensor of the body (in body coordinates)
|
||||
void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal);
|
||||
|
@ -149,17 +155,48 @@ class RigidBody : public CollisionBody {
|
|||
/// Return the inverse of the inertia tensor in world coordinates.
|
||||
Matrix3x3 getInertiaTensorInverseWorld() const;
|
||||
|
||||
/// Get the restitution coefficient
|
||||
decimal getRestitution() const;
|
||||
/// Return true if the gravity needs to be applied to this rigid body
|
||||
bool isGravityEnabled() const;
|
||||
|
||||
/// Set the restitution coefficient
|
||||
void setRestitution(decimal restitution);
|
||||
/// Set the variable to know if the gravity is applied to this rigid body
|
||||
void enableGravity(bool isEnabled);
|
||||
|
||||
/// Get the friction coefficient
|
||||
decimal getFrictionCoefficient() const;
|
||||
/// Return a reference to the material properties of the rigid body
|
||||
Material& getMaterial();
|
||||
|
||||
/// Set the friction coefficient
|
||||
void setFrictionCoefficient(decimal frictionCoefficient);
|
||||
/// Set a new material for this rigid body
|
||||
void setMaterial(const Material& material);
|
||||
|
||||
/// Return the linear velocity damping factor
|
||||
decimal getLinearDamping() const;
|
||||
|
||||
/// Set the linear damping factor
|
||||
void setLinearDamping(decimal linearDamping);
|
||||
|
||||
/// Return the angular velocity damping factor
|
||||
decimal getAngularDamping() const;
|
||||
|
||||
/// Set the angular damping factor
|
||||
void setAngularDamping(decimal angularDamping);
|
||||
|
||||
/// Return the first element of the linked list of joints involving this body
|
||||
const JointListElement* getJointsList() const;
|
||||
|
||||
/// Set the variable to know whether or not the body is sleeping
|
||||
virtual void setIsSleeping(bool isSleeping);
|
||||
|
||||
/// Apply an external force to the body at its gravity center.
|
||||
void applyForceToCenter(const Vector3& force);
|
||||
|
||||
/// Apply an external force to the body at a given point (in world-space coordinates).
|
||||
void applyForce(const Vector3& force, const Vector3& point);
|
||||
|
||||
/// Apply an external torque to the body.
|
||||
void applyTorque(const Vector3& torque);
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class DynamicsWorld;
|
||||
};
|
||||
|
||||
// Method that return the mass of the body
|
||||
|
@ -196,33 +233,13 @@ inline Matrix3x3 RigidBody::getInertiaTensorLocalInverse() const {
|
|||
return mInertiaTensorLocalInverse;
|
||||
}
|
||||
|
||||
// Return the external force on the body
|
||||
inline Vector3 RigidBody::getExternalForce() const {
|
||||
return mExternalForce;
|
||||
}
|
||||
|
||||
// Set the external force on the body
|
||||
inline void RigidBody::setExternalForce(const Vector3& force) {
|
||||
mExternalForce = force;
|
||||
}
|
||||
|
||||
// Return the current external torque on the body
|
||||
inline Vector3 RigidBody::getExternalTorque() const {
|
||||
return mExternalTorque;
|
||||
}
|
||||
|
||||
// Set the current external torque on the body
|
||||
inline void RigidBody::setExternalTorque(const Vector3& torque) {
|
||||
mExternalTorque = torque;
|
||||
}
|
||||
|
||||
// Return the inverse of the mass of the body
|
||||
inline decimal RigidBody::getMassInverse() const {
|
||||
return mMassInverse;
|
||||
}
|
||||
|
||||
// Return the local inertia tensor of the body (in body coordinates)
|
||||
inline Matrix3x3 RigidBody::getInertiaTensorLocal() const {
|
||||
inline const Matrix3x3& RigidBody::getInertiaTensorLocal() const {
|
||||
return mInertiaTensorLocal;
|
||||
}
|
||||
|
||||
|
@ -267,25 +284,120 @@ inline void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
|
|||
}
|
||||
}
|
||||
|
||||
// Get the restitution coeffficient of the rigid body
|
||||
inline decimal RigidBody::getRestitution() const {
|
||||
return mRestitution;
|
||||
// Return true if the gravity needs to be applied to this rigid body
|
||||
inline bool RigidBody::isGravityEnabled() const {
|
||||
return mIsGravityEnabled;
|
||||
}
|
||||
|
||||
// Set the restitution coefficient
|
||||
inline void RigidBody::setRestitution(decimal restitution) {
|
||||
assert(restitution >= 0.0 && restitution <= 1.0);
|
||||
mRestitution = restitution;
|
||||
// Set the variable to know if the gravity is applied to this rigid body
|
||||
inline void RigidBody::enableGravity(bool isEnabled) {
|
||||
mIsGravityEnabled = isEnabled;
|
||||
}
|
||||
|
||||
// Get the friction coefficient
|
||||
inline decimal RigidBody::getFrictionCoefficient() const {
|
||||
return mFrictionCoefficient;
|
||||
// Return a reference to the material properties of the rigid body
|
||||
inline Material& RigidBody::getMaterial() {
|
||||
return mMaterial;
|
||||
}
|
||||
|
||||
// Set the friction coefficient
|
||||
inline void RigidBody::setFrictionCoefficient(decimal frictionCoefficient) {
|
||||
mFrictionCoefficient = frictionCoefficient;
|
||||
// Set a new material for this rigid body
|
||||
inline void RigidBody::setMaterial(const Material& material) {
|
||||
mMaterial = material;
|
||||
}
|
||||
|
||||
// Return the linear velocity damping factor
|
||||
inline decimal RigidBody::getLinearDamping() const {
|
||||
return mLinearDamping;
|
||||
}
|
||||
|
||||
// Set the linear damping factor
|
||||
inline void RigidBody::setLinearDamping(decimal linearDamping) {
|
||||
assert(linearDamping >= decimal(0.0));
|
||||
mLinearDamping = linearDamping;
|
||||
}
|
||||
|
||||
// Return the angular velocity damping factor
|
||||
inline decimal RigidBody::getAngularDamping() const {
|
||||
return mAngularDamping;
|
||||
}
|
||||
|
||||
// Set the angular damping factor
|
||||
inline void RigidBody::setAngularDamping(decimal angularDamping) {
|
||||
assert(angularDamping >= decimal(0.0));
|
||||
mAngularDamping = angularDamping;
|
||||
}
|
||||
|
||||
// Return the first element of the linked list of joints involving this body
|
||||
inline const JointListElement* RigidBody::getJointsList() const {
|
||||
return mJointsList;
|
||||
}
|
||||
|
||||
// Set the variable to know whether or not the body is sleeping
|
||||
inline void RigidBody::setIsSleeping(bool isSleeping) {
|
||||
|
||||
if (isSleeping) {
|
||||
mLinearVelocity.setToZero();
|
||||
mAngularVelocity.setToZero();
|
||||
mExternalForce.setToZero();
|
||||
mExternalTorque.setToZero();
|
||||
}
|
||||
|
||||
Body::setIsSleeping(isSleeping);
|
||||
}
|
||||
|
||||
// Apply an external force to the body at its gravity center.
|
||||
/// If the body is sleeping, calling this method will wake it up. Note that the
|
||||
/// force will we added to the sum of the applied forces and that this sum will be
|
||||
/// reset to zero at the end of each call of the DynamicsWorld::update() method.
|
||||
inline void RigidBody::applyForceToCenter(const Vector3& force) {
|
||||
// If it is a static body, do not apply any force
|
||||
if (!mIsMotionEnabled) return;
|
||||
|
||||
// Awake the body if it was sleeping
|
||||
if (mIsSleeping) {
|
||||
setIsSleeping(false);
|
||||
}
|
||||
|
||||
// Add the force
|
||||
mExternalForce += force;
|
||||
}
|
||||
|
||||
// Apply an external force to the body at a given point (in world-space coordinates).
|
||||
/// If the point is not at the center of gravity of the body, it will also
|
||||
/// generate some torque and therefore, change the angular velocity of the body.
|
||||
/// If the body is sleeping, calling this method will wake it up. Note that the
|
||||
/// force will we added to the sum of the applied forces and that this sum will be
|
||||
/// reset to zero at the end of each call of the DynamicsWorld::update() method.
|
||||
inline void RigidBody::applyForce(const Vector3& force, const Vector3& point) {
|
||||
|
||||
// If it is a static body, do not apply any force
|
||||
if (!mIsMotionEnabled) return;
|
||||
|
||||
// Awake the body if it was sleeping
|
||||
if (mIsSleeping) {
|
||||
setIsSleeping(false);
|
||||
}
|
||||
|
||||
// Add the force and torque
|
||||
mExternalForce += force;
|
||||
mExternalTorque += (point - mTransform.getPosition()).cross(force);
|
||||
}
|
||||
|
||||
// Apply an external torque to the body.
|
||||
/// If the body is sleeping, calling this method will wake it up. Note that the
|
||||
/// force will we added to the sum of the applied torques and that this sum will be
|
||||
/// reset to zero at the end of each call of the DynamicsWorld::update() method.
|
||||
inline void RigidBody::applyTorque(const Vector3& torque) {
|
||||
|
||||
// If it is a static body, do not apply any force
|
||||
if (!mIsMotionEnabled) return;
|
||||
|
||||
// Awake the body if it was sleeping
|
||||
if (mIsSleeping) {
|
||||
setIsSleeping(false);
|
||||
}
|
||||
|
||||
// Add the torque
|
||||
mExternalTorque += torque;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef BROAD_PHASE_PAIR_H
|
||||
#define BROAD_PHASE_PAIR_H
|
||||
#ifndef REACTPHYSICS3D_BROAD_PHASE_PAIR_H
|
||||
#define REACTPHYSICS3D_BROAD_PHASE_PAIR_H
|
||||
|
||||
// Libraries
|
||||
#include "../body/CollisionBody.h"
|
||||
|
@ -60,6 +60,9 @@ struct BroadPhasePair {
|
|||
/// Destructor
|
||||
~BroadPhasePair();
|
||||
|
||||
/// Return the pair of bodies index
|
||||
static bodyindexpair computeBodiesIndexPair(CollisionBody* body1, CollisionBody* body2);
|
||||
|
||||
/// Return the pair of bodies index
|
||||
bodyindexpair getBodiesIndexPair() const;
|
||||
|
||||
|
@ -77,16 +80,22 @@ struct BroadPhasePair {
|
|||
};
|
||||
|
||||
// Return the pair of bodies index
|
||||
inline bodyindexpair BroadPhasePair::getBodiesIndexPair() const {
|
||||
|
||||
inline bodyindexpair BroadPhasePair::computeBodiesIndexPair(CollisionBody* body1,
|
||||
CollisionBody* body2) {
|
||||
// Construct the pair of body index
|
||||
bodyindexpair indexPair = body1->getID() < body2->getID() ?
|
||||
bodyindexpair indexPair = body1->getID() < body2->getID() ?
|
||||
std::make_pair(body1->getID(), body2->getID()) :
|
||||
std::make_pair(body2->getID(), body1->getID());
|
||||
assert(indexPair.first != indexPair.second);
|
||||
return indexPair;
|
||||
}
|
||||
|
||||
// Return the pair of bodies index
|
||||
inline bodyindexpair BroadPhasePair::getBodiesIndexPair() const {
|
||||
|
||||
return computeBodiesIndexPair(body1, body2);
|
||||
}
|
||||
|
||||
// Smaller than operator
|
||||
inline bool BroadPhasePair::operator<(const BroadPhasePair& broadPhasePair2) const {
|
||||
return (body1 < broadPhasePair2.body1 ? true : (body2 < broadPhasePair2.body2));
|
||||
|
|
|
@ -43,9 +43,10 @@ using namespace reactphysics3d;
|
|||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
CollisionDetection::CollisionDetection(CollisionWorld* world)
|
||||
: mWorld(world), mNarrowPhaseGJKAlgorithm(mMemoryPoolContactInfos),
|
||||
mNarrowPhaseSphereVsSphereAlgorithm(mMemoryPoolContactInfos) {
|
||||
CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryAllocator& memoryAllocator)
|
||||
: mWorld(world), mMemoryAllocator(memoryAllocator),
|
||||
mNarrowPhaseGJKAlgorithm(memoryAllocator),
|
||||
mNarrowPhaseSphereVsSphereAlgorithm(memoryAllocator) {
|
||||
|
||||
// Create the broad-phase algorithm that will be used (Sweep and Prune with AABB)
|
||||
mBroadPhaseAlgorithm = new SweepAndPruneAlgorithm(*this);
|
||||
|
@ -62,6 +63,8 @@ CollisionDetection::~CollisionDetection() {
|
|||
// Compute the collision detection
|
||||
void CollisionDetection::computeCollisionDetection() {
|
||||
|
||||
PROFILE("CollisionDetection::computeCollisionDetection()");
|
||||
|
||||
// Compute the broad-phase collision detection
|
||||
computeBroadPhase();
|
||||
|
||||
|
@ -72,12 +75,14 @@ void CollisionDetection::computeCollisionDetection() {
|
|||
// Compute the broad-phase collision detection
|
||||
void CollisionDetection::computeBroadPhase() {
|
||||
|
||||
PROFILE("CollisionDetection::computeBroadPhase()");
|
||||
|
||||
// Notify the broad-phase algorithm about the bodies that have moved since last frame
|
||||
for (set<CollisionBody*>::iterator it = mWorld->getBodiesBeginIterator();
|
||||
it != mWorld->getBodiesEndIterator(); it++) {
|
||||
|
||||
// If the body has moved
|
||||
if ((*it)->getHasMoved()) {
|
||||
if ((*it)->mHasMoved) {
|
||||
|
||||
// Notify the broad-phase that the body has moved
|
||||
mBroadPhaseAlgorithm->updateObject(*it, (*it)->getAABB());
|
||||
|
@ -87,11 +92,14 @@ void CollisionDetection::computeBroadPhase() {
|
|||
|
||||
// Compute the narrow-phase collision detection
|
||||
void CollisionDetection::computeNarrowPhase() {
|
||||
|
||||
PROFILE("CollisionDetection::computeNarrowPhase()");
|
||||
|
||||
map<bodyindexpair, BroadPhasePair*>::iterator it;
|
||||
|
||||
// For each possible collision pair of bodies
|
||||
for (it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); it++) {
|
||||
ContactInfo* contactInfo = NULL;
|
||||
ContactPointInfo* contactInfo = NULL;
|
||||
|
||||
BroadPhasePair* pair = (*it).second;
|
||||
assert(pair != NULL);
|
||||
|
@ -102,6 +110,12 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
// Update the contact cache of the overlapping pair
|
||||
mWorld->updateOverlappingPair(pair);
|
||||
|
||||
// Check if the two bodies are allowed to collide, otherwise, we do not test for collision
|
||||
if (mNoCollisionPairs.count(pair->getBodiesIndexPair()) > 0) continue;
|
||||
|
||||
// Check if the two bodies are sleeping, if so, we do no test collision between them
|
||||
if (body1->isSleeping() && body2->isSleeping()) continue;
|
||||
|
||||
// Select the narrow phase algorithm to use according to the two collision shapes
|
||||
NarrowPhaseAlgorithm& narrowPhaseAlgorithm = SelectNarrowPhaseAlgorithm(
|
||||
body1->getCollisionShape(),
|
||||
|
@ -117,12 +131,18 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
contactInfo)) {
|
||||
assert(contactInfo != NULL);
|
||||
|
||||
// Set the bodies of the contact
|
||||
contactInfo->body1 = dynamic_cast<RigidBody*>(body1);
|
||||
contactInfo->body2 = dynamic_cast<RigidBody*>(body2);
|
||||
assert(contactInfo->body1 != NULL);
|
||||
assert(contactInfo->body2 != NULL);
|
||||
|
||||
// Notify the world about the new narrow-phase contact
|
||||
mWorld->notifyNewContact(pair, contactInfo);
|
||||
|
||||
// Delete and remove the contact info from the memory pool
|
||||
contactInfo->ContactInfo::~ContactInfo();
|
||||
mMemoryPoolContactInfos.freeObject(contactInfo);
|
||||
// Delete and remove the contact info from the memory allocator
|
||||
contactInfo->ContactPointInfo::~ContactPointInfo();
|
||||
mMemoryAllocator.release(contactInfo, sizeof(ContactPointInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +155,7 @@ void CollisionDetection::broadPhaseNotifyAddedOverlappingPair(BodyPair* addedPai
|
|||
bodyindexpair indexPair = addedPair->getBodiesIndexPair();
|
||||
|
||||
// Create the corresponding broad-phase pair object
|
||||
BroadPhasePair* broadPhasePair = new (mMemoryPoolBroadPhasePairs.allocateObject())
|
||||
BroadPhasePair* broadPhasePair = new (mMemoryAllocator.allocate(sizeof(BroadPhasePair)))
|
||||
BroadPhasePair(addedPair->body1, addedPair->body2);
|
||||
assert(broadPhasePair != NULL);
|
||||
|
||||
|
@ -162,8 +182,8 @@ void CollisionDetection::broadPhaseNotifyRemovedOverlappingPair(BodyPair* remove
|
|||
// Notify the world about the removed broad-phase pair
|
||||
mWorld->notifyRemovedOverlappingPair(broadPhasePair);
|
||||
|
||||
// Remove the overlapping pair from the memory pool
|
||||
// Remove the overlapping pair from the memory allocator
|
||||
broadPhasePair->BroadPhasePair::~BroadPhasePair();
|
||||
mMemoryPoolBroadPhasePairs.freeObject(broadPhasePair);
|
||||
mMemoryAllocator.release(broadPhasePair, sizeof(BroadPhasePair));
|
||||
mOverlappingPairs.erase(indexPair);
|
||||
}
|
||||
|
|
|
@ -23,23 +23,21 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef COLLISION_DETECTION_H
|
||||
#define COLLISION_DETECTION_H
|
||||
#ifndef REACTPHYSICS3D_COLLISION_DETECTION_H
|
||||
#define REACTPHYSICS3D_COLLISION_DETECTION_H
|
||||
|
||||
// Libraries
|
||||
#include "../body/CollisionBody.h"
|
||||
#include "broadphase/BroadPhaseAlgorithm.h"
|
||||
#include "BroadPhasePair.h"
|
||||
#include "../memory/MemoryPool.h"
|
||||
#include "narrowphase/GJK/GJKAlgorithm.h"
|
||||
#include "narrowphase/SphereVsSphereAlgorithm.h"
|
||||
#include "ContactInfo.h"
|
||||
#include "../memory/MemoryAllocator.h"
|
||||
#include "../constraint/ContactPoint.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <iostream> // TODO : Delete this
|
||||
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -64,6 +62,9 @@ class CollisionDetection {
|
|||
/// Pointer to the physics world
|
||||
CollisionWorld* mWorld;
|
||||
|
||||
/// Memory allocator
|
||||
MemoryAllocator& mMemoryAllocator;
|
||||
|
||||
/// Broad-phase overlapping pairs
|
||||
std::map<bodyindexpair, BroadPhasePair*> mOverlappingPairs;
|
||||
|
||||
|
@ -76,11 +77,8 @@ class CollisionDetection {
|
|||
/// Narrow-phase Sphere vs Sphere algorithm
|
||||
SphereVsSphereAlgorithm mNarrowPhaseSphereVsSphereAlgorithm;
|
||||
|
||||
/// Memory pool for contactinfo
|
||||
MemoryPool<ContactInfo> mMemoryPoolContactInfos;
|
||||
|
||||
/// Memory pool for broad-phase pairs
|
||||
MemoryPool<BroadPhasePair> mMemoryPoolBroadPhasePairs;
|
||||
/// Set of pair of bodies that cannot collide between each other
|
||||
std::set<bodyindexpair> mNoCollisionPairs;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
|
@ -105,7 +103,7 @@ class CollisionDetection {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CollisionDetection(CollisionWorld* world);
|
||||
CollisionDetection(CollisionWorld* world, MemoryAllocator& memoryAllocator);
|
||||
|
||||
/// Destructor
|
||||
~CollisionDetection();
|
||||
|
@ -116,6 +114,12 @@ class CollisionDetection {
|
|||
/// Remove a body from the collision detection
|
||||
void removeBody(CollisionBody* body);
|
||||
|
||||
/// Add a pair of bodies that cannot collide with each other
|
||||
void addNoCollisionPair(CollisionBody* body1, CollisionBody* body2);
|
||||
|
||||
/// Remove a pair of bodies that cannot collide with each other
|
||||
void removeNoCollisionPair(CollisionBody *body1, CollisionBody *body2);
|
||||
|
||||
/// Compute the collision detection
|
||||
void computeCollisionDetection();
|
||||
|
||||
|
@ -153,6 +157,18 @@ inline void CollisionDetection::removeBody(CollisionBody* body) {
|
|||
mBroadPhaseAlgorithm->removeObject(body);
|
||||
}
|
||||
|
||||
// Add a pair of bodies that cannot collide with each other
|
||||
inline void CollisionDetection::addNoCollisionPair(CollisionBody* body1,
|
||||
CollisionBody* body2) {
|
||||
mNoCollisionPairs.insert(BroadPhasePair::computeBodiesIndexPair(body1, body2));
|
||||
}
|
||||
|
||||
// Remove a pair of bodies that cannot collide with each other
|
||||
inline void CollisionDetection::removeNoCollisionPair(CollisionBody* body1,
|
||||
CollisionBody* body2) {
|
||||
mNoCollisionPairs.erase(BroadPhasePair::computeBodiesIndexPair(body1, body2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef BROAD_PHASE_ALGORITHM_H
|
||||
#define BROAD_PHASE_ALGORITHM_H
|
||||
#ifndef REACTPHYSICS3D_BROAD_PHASE_ALGORITHM_H
|
||||
#define REACTPHYSICS3D_BROAD_PHASE_ALGORITHM_H
|
||||
|
||||
// Libraries
|
||||
#include <vector>
|
||||
|
|