Added Box2D
This commit is contained in:
92
external/Box2D-2.3.1/Box2D/Testbed/CMakeLists.txt
vendored
Normal file
92
external/Box2D-2.3.1/Box2D/Testbed/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
# Some flags for Freeglut and GLUI.
|
||||
add_definitions( -DFREEGLUT_EXPORTS -DFREEGLUT_STATIC -D_CRT_SECURE_NO_WARNINGS )
|
||||
|
||||
# Define the framework files.
|
||||
set(Testbed_Framework_SRCS
|
||||
Framework/Main.cpp
|
||||
Framework/Render.cpp
|
||||
Framework/Render.h
|
||||
Framework/Test.cpp
|
||||
Framework/Test.h
|
||||
)
|
||||
|
||||
#define the test files.
|
||||
set(Testbed_Tests_SRCS
|
||||
Tests/TestEntries.cpp
|
||||
Tests/AddPair.h
|
||||
Tests/ApplyForce.h
|
||||
Tests/BodyTypes.h
|
||||
Tests/Breakable.h
|
||||
Tests/Bridge.h
|
||||
Tests/BulletTest.h
|
||||
Tests/Cantilever.h
|
||||
Tests/Car.h
|
||||
Tests/Chain.h
|
||||
Tests/CharacterCollision.h
|
||||
Tests/CollisionFiltering.h
|
||||
Tests/CollisionProcessing.h
|
||||
Tests/CompoundShapes.h
|
||||
Tests/Confined.h
|
||||
Tests/ContinuousTest.h
|
||||
Tests/DistanceTest.h
|
||||
Tests/Dominos.h
|
||||
Tests/DumpShell.h
|
||||
Tests/DynamicTreeTest.h
|
||||
Tests/EdgeShapes.h
|
||||
Tests/EdgeTest.h
|
||||
Tests/Gears.h
|
||||
Tests/OneSidedPlatform.h
|
||||
Tests/Pinball.h
|
||||
Tests/PolyCollision.h
|
||||
Tests/PolyShapes.h
|
||||
Tests/Prismatic.h
|
||||
Tests/Pulleys.h
|
||||
Tests/Pyramid.h
|
||||
Tests/RayCast.h
|
||||
Tests/Revolute.h
|
||||
Tests/Rope.h
|
||||
Tests/RopeJoint.h
|
||||
Tests/SensorTest.h
|
||||
Tests/ShapeEditing.h
|
||||
Tests/SliderCrank.h
|
||||
Tests/SphereStack.h
|
||||
Tests/TheoJansen.h
|
||||
Tests/Tiles.h
|
||||
Tests/TimeOfImpact.h
|
||||
Tests/VaryingFriction.h
|
||||
Tests/VaryingRestitution.h
|
||||
Tests/VerticalStack.h
|
||||
Tests/Web.h
|
||||
)
|
||||
|
||||
# These are used to create visual studio folders.
|
||||
source_group(Framework FILES ${Testbed_Framework_SRCS})
|
||||
source_group(Tests FILES ${Testbed_Tests_SRCS})
|
||||
|
||||
include_directories (
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${Box2D_SOURCE_DIR}
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
# We are not using the Apple's framework version, but X11's
|
||||
include_directories( /usr/X11/include )
|
||||
link_directories( /usr/X11/lib )
|
||||
set (OPENGL_LIBRARIES GL GLU GLUT X11)
|
||||
elseif(WIN32)
|
||||
set (ADDITIONAL_LIBRARIES winmm)
|
||||
endif(APPLE)
|
||||
|
||||
add_executable(Testbed
|
||||
${Testbed_Framework_SRCS}
|
||||
${Testbed_Tests_SRCS}
|
||||
)
|
||||
|
||||
target_link_libraries (
|
||||
Testbed
|
||||
Box2D
|
||||
freeglut_static
|
||||
glui
|
||||
${ADDITIONAL_LIBRARIES}
|
||||
${OPENGL_LIBRARIES}
|
||||
)
|
||||
827
external/Box2D-2.3.1/Box2D/Testbed/Framework/DebugDraw.cpp
vendored
Normal file
827
external/Box2D-2.3.1/Box2D/Testbed/Framework/DebugDraw.cpp
vendored
Normal file
@@ -0,0 +1,827 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2013 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "DebugDraw.h"
|
||||
|
||||
#if defined(__APPLE_CC__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <glew/glew.h>
|
||||
#endif
|
||||
|
||||
#include <glfw/glfw3.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "RenderGL3.h"
|
||||
|
||||
#define BUFFER_OFFSET(x) ((const void*) (x))
|
||||
|
||||
DebugDraw g_debugDraw;
|
||||
Camera g_camera;
|
||||
|
||||
//
|
||||
b2Vec2 Camera::ConvertScreenToWorld(const b2Vec2& ps)
|
||||
{
|
||||
float32 w = float32(m_width);
|
||||
float32 h = float32(m_height);
|
||||
float32 u = ps.x / w;
|
||||
float32 v = (h - ps.y) / h;
|
||||
|
||||
float32 ratio = w / h;
|
||||
b2Vec2 extents(ratio * 25.0f, 25.0f);
|
||||
extents *= m_zoom;
|
||||
|
||||
b2Vec2 lower = m_center - extents;
|
||||
b2Vec2 upper = m_center + extents;
|
||||
|
||||
b2Vec2 pw;
|
||||
pw.x = (1.0f - u) * lower.x + u * upper.x;
|
||||
pw.y = (1.0f - v) * lower.y + v * upper.y;
|
||||
return pw;
|
||||
}
|
||||
|
||||
//
|
||||
b2Vec2 Camera::ConvertWorldToScreen(const b2Vec2& pw)
|
||||
{
|
||||
float32 w = float32(m_width);
|
||||
float32 h = float32(m_height);
|
||||
float32 ratio = w / h;
|
||||
b2Vec2 extents(ratio * 25.0f, 25.0f);
|
||||
extents *= m_zoom;
|
||||
|
||||
b2Vec2 lower = m_center - extents;
|
||||
b2Vec2 upper = m_center + extents;
|
||||
|
||||
float32 u = (pw.x - lower.x) / (upper.x - lower.x);
|
||||
float32 v = (pw.y - lower.y) / (upper.y - lower.y);
|
||||
|
||||
b2Vec2 ps;
|
||||
ps.x = u * w;
|
||||
ps.y = (1.0f - v) * h;
|
||||
return ps;
|
||||
}
|
||||
|
||||
// Convert from world coordinates to normalized device coordinates.
|
||||
// http://www.songho.ca/opengl/gl_projectionmatrix.html
|
||||
void Camera::BuildProjectionMatrix(float32* m, float32 zBias)
|
||||
{
|
||||
float32 w = float32(m_width);
|
||||
float32 h = float32(m_height);
|
||||
float32 ratio = w / h;
|
||||
b2Vec2 extents(ratio * 25.0f, 25.0f);
|
||||
extents *= m_zoom;
|
||||
|
||||
b2Vec2 lower = m_center - extents;
|
||||
b2Vec2 upper = m_center + extents;
|
||||
|
||||
m[0] = 2.0f / (upper.x - lower.x);
|
||||
m[1] = 0.0f;
|
||||
m[2] = 0.0f;
|
||||
m[3] = 0.0f;
|
||||
|
||||
m[4] = 0.0f;
|
||||
m[5] = 2.0f / (upper.y - lower.y);
|
||||
m[6] = 0.0f;
|
||||
m[7] = 0.0f;
|
||||
|
||||
m[8] = 0.0f;
|
||||
m[9] = 0.0f;
|
||||
m[10] = 1.0f;
|
||||
m[11] = 0.0f;
|
||||
|
||||
m[12] = -(upper.x + lower.x) / (upper.x - lower.x);
|
||||
m[13] = -(upper.y + lower.y) / (upper.y - lower.y);
|
||||
m[14] = zBias;
|
||||
m[15] = 1.0f;
|
||||
}
|
||||
|
||||
//
|
||||
static void sCheckGLError()
|
||||
{
|
||||
GLenum errCode = glGetError();
|
||||
if (errCode != GL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenGL error = %d\n", errCode);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Prints shader compilation errors
|
||||
static void sPrintLog(GLuint object)
|
||||
{
|
||||
GLint log_length = 0;
|
||||
if (glIsShader(object))
|
||||
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
|
||||
else if (glIsProgram(object))
|
||||
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "printlog: Not a shader or a program\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char* log = (char*)malloc(log_length);
|
||||
|
||||
if (glIsShader(object))
|
||||
glGetShaderInfoLog(object, log_length, NULL, log);
|
||||
else if (glIsProgram(object))
|
||||
glGetProgramInfoLog(object, log_length, NULL, log);
|
||||
|
||||
fprintf(stderr, "%s", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
static GLuint sCreateShaderFromString(const char* source, GLenum type)
|
||||
{
|
||||
GLuint res = glCreateShader(type);
|
||||
const char* sources[] = { source };
|
||||
glShaderSource(res, 1, sources, NULL);
|
||||
glCompileShader(res);
|
||||
GLint compile_ok = GL_FALSE;
|
||||
glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
|
||||
if (compile_ok == GL_FALSE)
|
||||
{
|
||||
fprintf(stderr, "Error compiling shader of type %d!\n", type);
|
||||
sPrintLog(res);
|
||||
glDeleteShader(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//
|
||||
static GLuint sCreateShaderProgram(const char* vs, const char* fs)
|
||||
{
|
||||
GLuint vsId = sCreateShaderFromString(vs, GL_VERTEX_SHADER);
|
||||
GLuint fsId = sCreateShaderFromString(fs, GL_FRAGMENT_SHADER);
|
||||
assert(vsId != 0 && fsId != 0);
|
||||
|
||||
GLuint programId = glCreateProgram();
|
||||
glAttachShader(programId, vsId);
|
||||
glAttachShader(programId, fsId);
|
||||
glBindFragDataLocation(programId, 0, "color");
|
||||
glLinkProgram(programId);
|
||||
|
||||
glDeleteShader(vsId);
|
||||
glDeleteShader(fsId);
|
||||
|
||||
GLint status = GL_FALSE;
|
||||
glGetProgramiv(programId, GL_LINK_STATUS, &status);
|
||||
assert(status != GL_FALSE);
|
||||
|
||||
return programId;
|
||||
}
|
||||
|
||||
//
|
||||
struct GLRenderPoints
|
||||
{
|
||||
void Create()
|
||||
{
|
||||
const char* vs = \
|
||||
"#version 400\n"
|
||||
"uniform mat4 projectionMatrix;\n"
|
||||
"layout(location = 0) in vec2 v_position;\n"
|
||||
"layout(location = 1) in vec4 v_color;\n"
|
||||
"layout(location = 2) in float v_size;\n"
|
||||
"out vec4 f_color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" f_color = v_color;\n"
|
||||
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
|
||||
" gl_PointSize = v_size;\n"
|
||||
"}\n";
|
||||
|
||||
const char* fs = \
|
||||
"#version 400\n"
|
||||
"in vec4 f_color;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" color = f_color;\n"
|
||||
"}\n";
|
||||
|
||||
m_programId = sCreateShaderProgram(vs, fs);
|
||||
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
|
||||
m_vertexAttribute = 0;
|
||||
m_colorAttribute = 1;
|
||||
m_sizeAttribute = 2;
|
||||
|
||||
// Generate
|
||||
glGenVertexArrays(1, &m_vaoId);
|
||||
glGenBuffers(3, m_vboIds);
|
||||
|
||||
glBindVertexArray(m_vaoId);
|
||||
glEnableVertexAttribArray(m_vertexAttribute);
|
||||
glEnableVertexAttribArray(m_colorAttribute);
|
||||
glEnableVertexAttribArray(m_sizeAttribute);
|
||||
|
||||
// Vertex buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
|
||||
glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
|
||||
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
|
||||
glVertexAttribPointer(m_sizeAttribute, 1, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_sizes), m_sizes, GL_DYNAMIC_DRAW);
|
||||
|
||||
sCheckGLError();
|
||||
|
||||
// Cleanup
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
if (m_vaoId)
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_vaoId);
|
||||
glDeleteBuffers(2, m_vboIds);
|
||||
m_vaoId = 0;
|
||||
}
|
||||
|
||||
if (m_programId)
|
||||
{
|
||||
glDeleteProgram(m_programId);
|
||||
m_programId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Vertex(const b2Vec2& v, const b2Color& c, float32 size)
|
||||
{
|
||||
if (m_count == e_maxVertices)
|
||||
Flush();
|
||||
|
||||
m_vertices[m_count] = v;
|
||||
m_colors[m_count] = c;
|
||||
m_sizes[m_count] = size;
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
if (m_count == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(m_programId);
|
||||
|
||||
float32 proj[16] = { 0.0f };
|
||||
g_camera.BuildProjectionMatrix(proj, 0.0f);
|
||||
|
||||
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, proj);
|
||||
|
||||
glBindVertexArray(m_vaoId);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Vec2), m_vertices);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Color), m_colors);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(float32), m_sizes);
|
||||
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
glDrawArrays(GL_POINTS, 0, m_count);
|
||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||
|
||||
sCheckGLError();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
enum { e_maxVertices = 512 };
|
||||
b2Vec2 m_vertices[e_maxVertices];
|
||||
b2Color m_colors[e_maxVertices];
|
||||
float32 m_sizes[e_maxVertices];
|
||||
|
||||
int32 m_count;
|
||||
|
||||
GLuint m_vaoId;
|
||||
GLuint m_vboIds[3];
|
||||
GLuint m_programId;
|
||||
GLint m_projectionUniform;
|
||||
GLint m_vertexAttribute;
|
||||
GLint m_colorAttribute;
|
||||
GLint m_sizeAttribute;
|
||||
};
|
||||
|
||||
//
|
||||
struct GLRenderLines
|
||||
{
|
||||
void Create()
|
||||
{
|
||||
const char* vs = \
|
||||
"#version 400\n"
|
||||
"uniform mat4 projectionMatrix;\n"
|
||||
"layout(location = 0) in vec2 v_position;\n"
|
||||
"layout(location = 1) in vec4 v_color;\n"
|
||||
"out vec4 f_color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" f_color = v_color;\n"
|
||||
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
|
||||
"}\n";
|
||||
|
||||
const char* fs = \
|
||||
"#version 400\n"
|
||||
"in vec4 f_color;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" color = f_color;\n"
|
||||
"}\n";
|
||||
|
||||
m_programId = sCreateShaderProgram(vs, fs);
|
||||
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
|
||||
m_vertexAttribute = 0;
|
||||
m_colorAttribute = 1;
|
||||
|
||||
// Generate
|
||||
glGenVertexArrays(1, &m_vaoId);
|
||||
glGenBuffers(2, m_vboIds);
|
||||
|
||||
glBindVertexArray(m_vaoId);
|
||||
glEnableVertexAttribArray(m_vertexAttribute);
|
||||
glEnableVertexAttribArray(m_colorAttribute);
|
||||
|
||||
// Vertex buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
|
||||
glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
|
||||
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_DRAW);
|
||||
|
||||
sCheckGLError();
|
||||
|
||||
// Cleanup
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
if (m_vaoId)
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_vaoId);
|
||||
glDeleteBuffers(2, m_vboIds);
|
||||
m_vaoId = 0;
|
||||
}
|
||||
|
||||
if (m_programId)
|
||||
{
|
||||
glDeleteProgram(m_programId);
|
||||
m_programId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Vertex(const b2Vec2& v, const b2Color& c)
|
||||
{
|
||||
if (m_count == e_maxVertices)
|
||||
Flush();
|
||||
|
||||
m_vertices[m_count] = v;
|
||||
m_colors[m_count] = c;
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
if (m_count == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(m_programId);
|
||||
|
||||
float32 proj[16] = { 0.0f };
|
||||
g_camera.BuildProjectionMatrix(proj, 0.1f);
|
||||
|
||||
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, proj);
|
||||
|
||||
glBindVertexArray(m_vaoId);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Vec2), m_vertices);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Color), m_colors);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, m_count);
|
||||
|
||||
sCheckGLError();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
enum { e_maxVertices = 2 * 512 };
|
||||
b2Vec2 m_vertices[e_maxVertices];
|
||||
b2Color m_colors[e_maxVertices];
|
||||
|
||||
int32 m_count;
|
||||
|
||||
GLuint m_vaoId;
|
||||
GLuint m_vboIds[2];
|
||||
GLuint m_programId;
|
||||
GLint m_projectionUniform;
|
||||
GLint m_vertexAttribute;
|
||||
GLint m_colorAttribute;
|
||||
};
|
||||
|
||||
//
|
||||
struct GLRenderTriangles
|
||||
{
|
||||
void Create()
|
||||
{
|
||||
const char* vs = \
|
||||
"#version 400\n"
|
||||
"uniform mat4 projectionMatrix;\n"
|
||||
"layout(location = 0) in vec2 v_position;\n"
|
||||
"layout(location = 1) in vec4 v_color;\n"
|
||||
"out vec4 f_color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" f_color = v_color;\n"
|
||||
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
|
||||
"}\n";
|
||||
|
||||
const char* fs = \
|
||||
"#version 400\n"
|
||||
"in vec4 f_color;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" color = f_color;\n"
|
||||
"}\n";
|
||||
|
||||
m_programId = sCreateShaderProgram(vs, fs);
|
||||
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
|
||||
m_vertexAttribute = 0;
|
||||
m_colorAttribute = 1;
|
||||
|
||||
// Generate
|
||||
glGenVertexArrays(1, &m_vaoId);
|
||||
glGenBuffers(2, m_vboIds);
|
||||
|
||||
glBindVertexArray(m_vaoId);
|
||||
glEnableVertexAttribArray(m_vertexAttribute);
|
||||
glEnableVertexAttribArray(m_colorAttribute);
|
||||
|
||||
// Vertex buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
|
||||
glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
|
||||
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_DRAW);
|
||||
|
||||
sCheckGLError();
|
||||
|
||||
// Cleanup
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
if (m_vaoId)
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_vaoId);
|
||||
glDeleteBuffers(2, m_vboIds);
|
||||
m_vaoId = 0;
|
||||
}
|
||||
|
||||
if (m_programId)
|
||||
{
|
||||
glDeleteProgram(m_programId);
|
||||
m_programId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Vertex(const b2Vec2& v, const b2Color& c)
|
||||
{
|
||||
if (m_count == e_maxVertices)
|
||||
Flush();
|
||||
|
||||
m_vertices[m_count] = v;
|
||||
m_colors[m_count] = c;
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
if (m_count == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(m_programId);
|
||||
|
||||
float32 proj[16] = { 0.0f };
|
||||
g_camera.BuildProjectionMatrix(proj, 0.2f);
|
||||
|
||||
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, proj);
|
||||
|
||||
glBindVertexArray(m_vaoId);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Vec2), m_vertices);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b2Color), m_colors);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_count);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
sCheckGLError();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
enum { e_maxVertices = 3 * 512 };
|
||||
b2Vec2 m_vertices[e_maxVertices];
|
||||
b2Color m_colors[e_maxVertices];
|
||||
|
||||
int32 m_count;
|
||||
|
||||
GLuint m_vaoId;
|
||||
GLuint m_vboIds[2];
|
||||
GLuint m_programId;
|
||||
GLint m_projectionUniform;
|
||||
GLint m_vertexAttribute;
|
||||
GLint m_colorAttribute;
|
||||
};
|
||||
|
||||
//
|
||||
DebugDraw::DebugDraw()
|
||||
{
|
||||
m_points = NULL;
|
||||
m_lines = NULL;
|
||||
m_triangles = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
DebugDraw::~DebugDraw()
|
||||
{
|
||||
b2Assert(m_points == NULL);
|
||||
b2Assert(m_lines == NULL);
|
||||
b2Assert(m_triangles == NULL);
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::Create()
|
||||
{
|
||||
m_points = new GLRenderPoints;
|
||||
m_points->Create();
|
||||
m_lines = new GLRenderLines;
|
||||
m_lines->Create();
|
||||
m_triangles = new GLRenderTriangles;
|
||||
m_triangles->Create();
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::Destroy()
|
||||
{
|
||||
m_points->Destroy();
|
||||
delete m_points;
|
||||
m_points = NULL;
|
||||
|
||||
m_lines->Destroy();
|
||||
delete m_lines;
|
||||
m_lines = NULL;
|
||||
|
||||
m_triangles->Destroy();
|
||||
delete m_triangles;
|
||||
m_triangles = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
|
||||
{
|
||||
b2Vec2 p1 = vertices[vertexCount - 1];
|
||||
for (int32 i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
b2Vec2 p2 = vertices[i];
|
||||
m_lines->Vertex(p1, color);
|
||||
m_lines->Vertex(p2, color);
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
|
||||
{
|
||||
b2Color fillColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f);
|
||||
|
||||
for (int32 i = 1; i < vertexCount - 1; ++i)
|
||||
{
|
||||
m_triangles->Vertex(vertices[0], fillColor);
|
||||
m_triangles->Vertex(vertices[i], fillColor);
|
||||
m_triangles->Vertex(vertices[i+1], fillColor);
|
||||
}
|
||||
|
||||
b2Vec2 p1 = vertices[vertexCount - 1];
|
||||
for (int32 i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
b2Vec2 p2 = vertices[i];
|
||||
m_lines->Vertex(p1, color);
|
||||
m_lines->Vertex(p2, color);
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color)
|
||||
{
|
||||
const float32 k_segments = 16.0f;
|
||||
const float32 k_increment = 2.0f * b2_pi / k_segments;
|
||||
float32 sinInc = sinf(k_increment);
|
||||
float32 cosInc = cosf(k_increment);
|
||||
b2Vec2 r1(1.0f, 0.0f);
|
||||
b2Vec2 v1 = center + radius * r1;
|
||||
for (int32 i = 0; i < k_segments; ++i)
|
||||
{
|
||||
// Perform rotation to avoid additional trigonometry.
|
||||
b2Vec2 r2;
|
||||
r2.x = cosInc * r1.x - sinInc * r1.y;
|
||||
r2.y = sinInc * r1.x + cosInc * r1.y;
|
||||
b2Vec2 v2 = center + radius * r2;
|
||||
m_lines->Vertex(v1, color);
|
||||
m_lines->Vertex(v2, color);
|
||||
r1 = r2;
|
||||
v1 = v2;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color)
|
||||
{
|
||||
const float32 k_segments = 16.0f;
|
||||
const float32 k_increment = 2.0f * b2_pi / k_segments;
|
||||
float32 sinInc = sinf(k_increment);
|
||||
float32 cosInc = cosf(k_increment);
|
||||
b2Vec2 v0 = center;
|
||||
b2Vec2 r1(cosInc, sinInc);
|
||||
b2Vec2 v1 = center + radius * r1;
|
||||
b2Color fillColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f);
|
||||
for (int32 i = 0; i < k_segments; ++i)
|
||||
{
|
||||
// Perform rotation to avoid additional trigonometry.
|
||||
b2Vec2 r2;
|
||||
r2.x = cosInc * r1.x - sinInc * r1.y;
|
||||
r2.y = sinInc * r1.x + cosInc * r1.y;
|
||||
b2Vec2 v2 = center + radius * r2;
|
||||
m_triangles->Vertex(v0, fillColor);
|
||||
m_triangles->Vertex(v1, fillColor);
|
||||
m_triangles->Vertex(v2, fillColor);
|
||||
r1 = r2;
|
||||
v1 = v2;
|
||||
}
|
||||
|
||||
r1.Set(1.0f, 0.0f);
|
||||
v1 = center + radius * r1;
|
||||
for (int32 i = 0; i < k_segments; ++i)
|
||||
{
|
||||
b2Vec2 r2;
|
||||
r2.x = cosInc * r1.x - sinInc * r1.y;
|
||||
r2.y = sinInc * r1.x + cosInc * r1.y;
|
||||
b2Vec2 v2 = center + radius * r2;
|
||||
m_lines->Vertex(v1, color);
|
||||
m_lines->Vertex(v2, color);
|
||||
r1 = r2;
|
||||
v1 = v2;
|
||||
}
|
||||
|
||||
// Draw a line fixed in the circle to animate rotation.
|
||||
b2Vec2 p = center + radius * axis;
|
||||
m_lines->Vertex(center, color);
|
||||
m_lines->Vertex(p, color);
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
|
||||
{
|
||||
m_lines->Vertex(p1, color);
|
||||
m_lines->Vertex(p2, color);
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::DrawTransform(const b2Transform& xf)
|
||||
{
|
||||
const float32 k_axisScale = 0.4f;
|
||||
b2Color red(1.0f, 0.0f, 0.0f);
|
||||
b2Color green(0.0f, 1.0f, 0.0f);
|
||||
b2Vec2 p1 = xf.p, p2;
|
||||
|
||||
m_lines->Vertex(p1, red);
|
||||
p2 = p1 + k_axisScale * xf.q.GetXAxis();
|
||||
m_lines->Vertex(p2, red);
|
||||
|
||||
m_lines->Vertex(p1, green);
|
||||
p2 = p1 + k_axisScale * xf.q.GetYAxis();
|
||||
m_lines->Vertex(p2, green);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawPoint(const b2Vec2& p, float32 size, const b2Color& color)
|
||||
{
|
||||
m_points->Vertex(p, color, size);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawString(int x, int y, const char *string, ...)
|
||||
{
|
||||
float32 h = float32(g_camera.m_height);
|
||||
|
||||
char buffer[128];
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, string);
|
||||
vsprintf(buffer, string, arg);
|
||||
va_end(arg);
|
||||
|
||||
AddGfxCmdText(float(x), h - float(y), TEXT_ALIGN_LEFT, buffer, SetRGBA(230, 153, 153, 255));
|
||||
}
|
||||
|
||||
void DebugDraw::DrawString(const b2Vec2& pw, const char *string, ...)
|
||||
{
|
||||
b2Vec2 ps = g_camera.ConvertWorldToScreen(pw);
|
||||
float32 h = float32(g_camera.m_height);
|
||||
|
||||
char buffer[128];
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, string);
|
||||
vsprintf(buffer, string, arg);
|
||||
va_end(arg);
|
||||
|
||||
AddGfxCmdText(ps.x, h - ps.y, TEXT_ALIGN_LEFT, buffer, SetRGBA(230, 153, 153, 255));
|
||||
}
|
||||
|
||||
void DebugDraw::DrawAABB(b2AABB* aabb, const b2Color& c)
|
||||
{
|
||||
b2Vec2 p1 = aabb->lowerBound;
|
||||
b2Vec2 p2 = b2Vec2(aabb->upperBound.x, aabb->lowerBound.y);
|
||||
b2Vec2 p3 = aabb->upperBound;
|
||||
b2Vec2 p4 = b2Vec2(aabb->lowerBound.x, aabb->upperBound.y);
|
||||
|
||||
m_lines->Vertex(p1, c);
|
||||
m_lines->Vertex(p2, c);
|
||||
|
||||
m_lines->Vertex(p2, c);
|
||||
m_lines->Vertex(p3, c);
|
||||
|
||||
m_lines->Vertex(p3, c);
|
||||
m_lines->Vertex(p4, c);
|
||||
|
||||
m_lines->Vertex(p4, c);
|
||||
m_lines->Vertex(p1, c);
|
||||
}
|
||||
|
||||
//
|
||||
void DebugDraw::Flush()
|
||||
{
|
||||
m_triangles->Flush();
|
||||
m_lines->Flush();
|
||||
m_points->Flush();
|
||||
}
|
||||
94
external/Box2D-2.3.1/Box2D/Testbed/Framework/DebugDraw.h
vendored
Normal file
94
external/Box2D-2.3.1/Box2D/Testbed/Framework/DebugDraw.h
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2013 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 DEBUGDRAW_H
|
||||
#define DEBUGDRAW_H
|
||||
|
||||
#include <Box2D/Box2D.h>
|
||||
|
||||
struct b2AABB;
|
||||
struct GLRenderPoints;
|
||||
struct GLRenderLines;
|
||||
struct GLRenderTriangles;
|
||||
|
||||
//
|
||||
struct Camera
|
||||
{
|
||||
Camera()
|
||||
{
|
||||
m_center.Set(0.0f, 20.0f);
|
||||
m_extent = 25.0f;
|
||||
m_zoom = 1.0f;
|
||||
m_width = 1280;
|
||||
m_height = 800;
|
||||
}
|
||||
|
||||
b2Vec2 ConvertScreenToWorld(const b2Vec2& screenPoint);
|
||||
b2Vec2 ConvertWorldToScreen(const b2Vec2& worldPoint);
|
||||
void BuildProjectionMatrix(float32* m, float32 zBias);
|
||||
|
||||
b2Vec2 m_center;
|
||||
float32 m_extent;
|
||||
float32 m_zoom;
|
||||
int32 m_width;
|
||||
int32 m_height;
|
||||
};
|
||||
|
||||
// This class implements debug drawing callbacks that are invoked
|
||||
// inside b2World::Step.
|
||||
class DebugDraw : public b2Draw
|
||||
{
|
||||
public:
|
||||
DebugDraw();
|
||||
~DebugDraw();
|
||||
|
||||
void Create();
|
||||
void Destroy();
|
||||
|
||||
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
|
||||
|
||||
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
|
||||
|
||||
void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color);
|
||||
|
||||
void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color);
|
||||
|
||||
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color);
|
||||
|
||||
void DrawTransform(const b2Transform& xf);
|
||||
|
||||
void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color);
|
||||
|
||||
void DrawString(int x, int y, const char* string, ...);
|
||||
|
||||
void DrawString(const b2Vec2& p, const char* string, ...);
|
||||
|
||||
void DrawAABB(b2AABB* aabb, const b2Color& color);
|
||||
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
GLRenderPoints* m_points;
|
||||
GLRenderLines* m_lines;
|
||||
GLRenderTriangles* m_triangles;
|
||||
};
|
||||
|
||||
extern DebugDraw g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
|
||||
#endif
|
||||
561
external/Box2D-2.3.1/Box2D/Testbed/Framework/Main.cpp
vendored
Normal file
561
external/Box2D-2.3.1/Box2D/Testbed/Framework/Main.cpp
vendored
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2013 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "imgui.h"
|
||||
#include "RenderGL3.h"
|
||||
#include "DebugDraw.h"
|
||||
#include "Test.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <glew/glew.h>
|
||||
#endif
|
||||
|
||||
#include <glfw/glfw3.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
//
|
||||
struct UIState
|
||||
{
|
||||
bool showMenu;
|
||||
int scroll;
|
||||
int scrollarea1;
|
||||
bool mouseOverMenu;
|
||||
bool chooseTest;
|
||||
};
|
||||
|
||||
//
|
||||
namespace
|
||||
{
|
||||
GLFWwindow* mainWindow = NULL;
|
||||
UIState ui;
|
||||
|
||||
int32 testIndex = 0;
|
||||
int32 testSelection = 0;
|
||||
int32 testCount = 0;
|
||||
TestEntry* entry;
|
||||
Test* test;
|
||||
Settings settings;
|
||||
bool rightMouseDown;
|
||||
b2Vec2 lastp;
|
||||
}
|
||||
|
||||
//
|
||||
static void sCreateUI()
|
||||
{
|
||||
ui.showMenu = true;
|
||||
ui.scroll = 0;
|
||||
ui.scrollarea1 = 0;
|
||||
ui.chooseTest = false;
|
||||
ui.mouseOverMenu = false;
|
||||
|
||||
// Init UI
|
||||
const char* fontPath = "../Data/DroidSans.ttf";
|
||||
|
||||
if (RenderGLInit(fontPath) == false)
|
||||
{
|
||||
fprintf(stderr, "Could not init GUI renderer.\n");
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void sResizeWindow(GLFWwindow*, int width, int height)
|
||||
{
|
||||
g_camera.m_width = width;
|
||||
g_camera.m_height = height;
|
||||
}
|
||||
|
||||
//
|
||||
static void sKeyCallback(GLFWwindow*, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_ESCAPE:
|
||||
// Quit
|
||||
glfwSetWindowShouldClose(mainWindow, GL_TRUE);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT:
|
||||
// Pan left
|
||||
if (mods == GLFW_MOD_CONTROL)
|
||||
{
|
||||
b2Vec2 newOrigin(2.0f, 0.0f);
|
||||
test->ShiftOrigin(newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_camera.m_center.x -= 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT:
|
||||
// Pan right
|
||||
if (mods == GLFW_MOD_CONTROL)
|
||||
{
|
||||
b2Vec2 newOrigin(-2.0f, 0.0f);
|
||||
test->ShiftOrigin(newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_camera.m_center.x += 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_DOWN:
|
||||
// Pan down
|
||||
if (mods == GLFW_MOD_CONTROL)
|
||||
{
|
||||
b2Vec2 newOrigin(0.0f, 2.0f);
|
||||
test->ShiftOrigin(newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_camera.m_center.y -= 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_UP:
|
||||
// Pan up
|
||||
if (mods == GLFW_MOD_CONTROL)
|
||||
{
|
||||
b2Vec2 newOrigin(0.0f, -2.0f);
|
||||
test->ShiftOrigin(newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_camera.m_center.y += 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_HOME:
|
||||
// Reset view
|
||||
g_camera.m_zoom = 1.0f;
|
||||
g_camera.m_center.Set(0.0f, 20.0f);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_Z:
|
||||
// Zoom out
|
||||
g_camera.m_zoom = b2Min(1.1f * g_camera.m_zoom, 20.0f);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_X:
|
||||
// Zoom in
|
||||
g_camera.m_zoom = b2Max(0.9f * g_camera.m_zoom, 0.02f);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_R:
|
||||
// Reset test
|
||||
delete test;
|
||||
test = entry->createFcn();
|
||||
break;
|
||||
|
||||
case GLFW_KEY_SPACE:
|
||||
// Launch a bomb.
|
||||
if (test)
|
||||
{
|
||||
test->LaunchBomb();
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_P:
|
||||
// Pause
|
||||
settings.pause = !settings.pause;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_BRACKET:
|
||||
// Switch to previous test
|
||||
--testSelection;
|
||||
if (testSelection < 0)
|
||||
{
|
||||
testSelection = testCount - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_RIGHT_BRACKET:
|
||||
// Switch to next test
|
||||
++testSelection;
|
||||
if (testSelection == testCount)
|
||||
{
|
||||
testSelection = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_TAB:
|
||||
ui.showMenu = !ui.showMenu;
|
||||
|
||||
default:
|
||||
if (test)
|
||||
{
|
||||
test->Keyboard(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (action == GLFW_RELEASE)
|
||||
{
|
||||
test->KeyboardUp(key);
|
||||
}
|
||||
// else GLFW_REPEAT
|
||||
}
|
||||
|
||||
//
|
||||
static void sMouseButton(GLFWwindow*, int32 button, int32 action, int32 mods)
|
||||
{
|
||||
double xd, yd;
|
||||
glfwGetCursorPos(mainWindow, &xd, &yd);
|
||||
b2Vec2 ps((float32)xd, (float32)yd);
|
||||
|
||||
// Use the mouse to move things around.
|
||||
if (button == GLFW_MOUSE_BUTTON_1)
|
||||
{
|
||||
//<##>
|
||||
//ps.Set(0, 0);
|
||||
b2Vec2 pw = g_camera.ConvertScreenToWorld(ps);
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
if (mods == GLFW_MOD_SHIFT)
|
||||
{
|
||||
test->ShiftMouseDown(pw);
|
||||
}
|
||||
else
|
||||
{
|
||||
test->MouseDown(pw);
|
||||
}
|
||||
}
|
||||
|
||||
if (action == GLFW_RELEASE)
|
||||
{
|
||||
test->MouseUp(pw);
|
||||
}
|
||||
}
|
||||
else if (button == GLFW_MOUSE_BUTTON_2)
|
||||
{
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
lastp = g_camera.ConvertScreenToWorld(ps);
|
||||
rightMouseDown = true;
|
||||
}
|
||||
|
||||
if (action == GLFW_RELEASE)
|
||||
{
|
||||
rightMouseDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void sMouseMotion(GLFWwindow*, double xd, double yd)
|
||||
{
|
||||
b2Vec2 ps((float)xd, (float)yd);
|
||||
|
||||
b2Vec2 pw = g_camera.ConvertScreenToWorld(ps);
|
||||
test->MouseMove(pw);
|
||||
|
||||
if (rightMouseDown)
|
||||
{
|
||||
b2Vec2 diff = pw - lastp;
|
||||
g_camera.m_center.x -= diff.x;
|
||||
g_camera.m_center.y -= diff.y;
|
||||
lastp = g_camera.ConvertScreenToWorld(ps);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void sScrollCallback(GLFWwindow*, double, double dy)
|
||||
{
|
||||
if (ui.mouseOverMenu)
|
||||
{
|
||||
ui.scroll = -int(dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dy > 0)
|
||||
{
|
||||
g_camera.m_zoom /= 1.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_camera.m_zoom *= 1.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void sRestart()
|
||||
{
|
||||
delete test;
|
||||
entry = g_testEntries + testIndex;
|
||||
test = entry->createFcn();
|
||||
}
|
||||
|
||||
//
|
||||
static void sSimulate()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
test->Step(&settings);
|
||||
|
||||
test->DrawTitle(entry->name);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
if (testSelection != testIndex)
|
||||
{
|
||||
testIndex = testSelection;
|
||||
delete test;
|
||||
entry = g_testEntries + testIndex;
|
||||
test = entry->createFcn();
|
||||
g_camera.m_zoom = 1.0f;
|
||||
g_camera.m_center.Set(0.0f, 20.0f);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void sInterface()
|
||||
{
|
||||
int menuWidth = 200;
|
||||
ui.mouseOverMenu = false;
|
||||
if (ui.showMenu)
|
||||
{
|
||||
bool over = imguiBeginScrollArea("Testbed Controls", g_camera.m_width - menuWidth - 10, 10, menuWidth, g_camera.m_height - 20, &ui.scrollarea1);
|
||||
if (over) ui.mouseOverMenu = true;
|
||||
|
||||
imguiSeparatorLine();
|
||||
|
||||
imguiLabel("Test");
|
||||
if (imguiButton(entry->name, true))
|
||||
{
|
||||
ui.chooseTest = !ui.chooseTest;
|
||||
}
|
||||
|
||||
imguiSeparatorLine();
|
||||
|
||||
imguiSlider("Vel Iters", &settings.velocityIterations, 0, 50, 1, true);
|
||||
imguiSlider("Pos Iters", &settings.positionIterations, 0, 50, 1, true);
|
||||
imguiSlider("Hertz", &settings.hz, 5.0f, 120.0f, 5.0f, true);
|
||||
|
||||
if (imguiCheck("Sleep", settings.enableSleep, true))
|
||||
settings.enableSleep = !settings.enableSleep;
|
||||
if (imguiCheck("Warm Starting", settings.enableWarmStarting, true))
|
||||
settings.enableWarmStarting = !settings.enableWarmStarting;
|
||||
if (imguiCheck("Time of Impact", settings.enableContinuous, true))
|
||||
settings.enableContinuous = !settings.enableContinuous;
|
||||
if (imguiCheck("Sub-Stepping", settings.enableSubStepping, true))
|
||||
settings.enableSubStepping = !settings.enableSubStepping;
|
||||
|
||||
imguiSeparatorLine();
|
||||
|
||||
if (imguiCheck("Shapes", settings.drawShapes, true))
|
||||
settings.drawShapes = !settings.drawShapes;
|
||||
if (imguiCheck("Joints", settings.drawJoints, true))
|
||||
settings.drawJoints = !settings.drawJoints;
|
||||
if (imguiCheck("AABBs", settings.drawAABBs, true))
|
||||
settings.drawAABBs = !settings.drawAABBs;
|
||||
if (imguiCheck("Contact Points", settings.drawContactPoints, true))
|
||||
settings.drawContactPoints = !settings.drawContactPoints;
|
||||
if (imguiCheck("Contact Normals", settings.drawContactNormals, true))
|
||||
settings.drawContactNormals = !settings.drawContactNormals;
|
||||
if (imguiCheck("Contact Impulses", settings.drawContactImpulse, true))
|
||||
settings.drawContactImpulse = !settings.drawContactImpulse;
|
||||
if (imguiCheck("Friction Impulses", settings.drawFrictionImpulse, true))
|
||||
settings.drawFrictionImpulse = !settings.drawFrictionImpulse;
|
||||
if (imguiCheck("Center of Masses", settings.drawCOMs, true))
|
||||
settings.drawCOMs = !settings.drawCOMs;
|
||||
if (imguiCheck("Statistics", settings.drawStats, true))
|
||||
settings.drawStats = !settings.drawStats;
|
||||
if (imguiCheck("Profile", settings.drawProfile, true))
|
||||
settings.drawProfile = !settings.drawProfile;
|
||||
|
||||
if (imguiButton("Pause", true))
|
||||
settings.pause = !settings.pause;
|
||||
|
||||
if (imguiButton("Single Step", true))
|
||||
settings.singleStep = !settings.singleStep;
|
||||
|
||||
if (imguiButton("Restart", true))
|
||||
sRestart();
|
||||
|
||||
if (imguiButton("Quit", true))
|
||||
glfwSetWindowShouldClose(mainWindow, GL_TRUE);
|
||||
|
||||
imguiEndScrollArea();
|
||||
}
|
||||
|
||||
int testMenuWidth = 200;
|
||||
if (ui.chooseTest)
|
||||
{
|
||||
static int testScroll = 0;
|
||||
bool over = imguiBeginScrollArea("Choose Sample", g_camera.m_width - menuWidth - testMenuWidth - 20, 10, testMenuWidth, g_camera.m_height - 20, &testScroll);
|
||||
if (over) ui.mouseOverMenu = true;
|
||||
|
||||
for (int i = 0; i < testCount; ++i)
|
||||
{
|
||||
if (imguiItem(g_testEntries[i].name, true))
|
||||
{
|
||||
delete test;
|
||||
entry = g_testEntries + i;
|
||||
test = entry->createFcn();
|
||||
ui.chooseTest = false;
|
||||
}
|
||||
}
|
||||
|
||||
imguiEndScrollArea();
|
||||
}
|
||||
|
||||
imguiEndFrame();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// Enable memory-leak reports
|
||||
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
|
||||
#endif
|
||||
|
||||
g_camera.m_width = 1024;
|
||||
g_camera.m_height = 640;
|
||||
|
||||
if (glfwInit() == 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize GLFW\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char title[64];
|
||||
sprintf(title, "Box2D Testbed Version %d.%d.%d", b2_version.major, b2_version.minor, b2_version.revision);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// Not sure why, but these settings cause glewInit below to crash.
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
#endif
|
||||
|
||||
mainWindow = glfwCreateWindow(g_camera.m_width, g_camera.m_height, title, NULL, NULL);
|
||||
if (mainWindow == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to open GLFW mainWindow.\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(mainWindow);
|
||||
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
glfwSetScrollCallback(mainWindow, sScrollCallback);
|
||||
glfwSetWindowSizeCallback(mainWindow, sResizeWindow);
|
||||
glfwSetKeyCallback(mainWindow, sKeyCallback);
|
||||
glfwSetMouseButtonCallback(mainWindow, sMouseButton);
|
||||
glfwSetCursorPosCallback(mainWindow, sMouseMotion);
|
||||
glfwSetScrollCallback(mainWindow, sScrollCallback);
|
||||
|
||||
#if defined(__APPLE__) == FALSE
|
||||
//glewExperimental = GL_TRUE;
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_debugDraw.Create();
|
||||
|
||||
sCreateUI();
|
||||
|
||||
testCount = 0;
|
||||
while (g_testEntries[testCount].createFcn != NULL)
|
||||
{
|
||||
++testCount;
|
||||
}
|
||||
|
||||
testIndex = b2Clamp(testIndex, 0, testCount - 1);
|
||||
testSelection = testIndex;
|
||||
|
||||
entry = g_testEntries + testIndex;
|
||||
test = entry->createFcn();
|
||||
|
||||
// Control the frame rate. One draw per monitor refresh.
|
||||
glfwSwapInterval(1);
|
||||
|
||||
double time1 = glfwGetTime();
|
||||
double frameTime = 0.0;
|
||||
|
||||
glClearColor(0.3f, 0.3f, 0.3f, 1.f);
|
||||
|
||||
while (!glfwWindowShouldClose(mainWindow))
|
||||
{
|
||||
glfwGetWindowSize(mainWindow, &g_camera.m_width, &g_camera.m_height);
|
||||
glViewport(0, 0, g_camera.m_width, g_camera.m_height);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
unsigned char mousebutton = 0;
|
||||
int mscroll = ui.scroll;
|
||||
ui.scroll = 0;
|
||||
|
||||
double xd, yd;
|
||||
glfwGetCursorPos(mainWindow, &xd, &yd);
|
||||
int mousex = int(xd);
|
||||
int mousey = int(yd);
|
||||
|
||||
mousey = g_camera.m_height - mousey;
|
||||
int leftButton = glfwGetMouseButton(mainWindow, GLFW_MOUSE_BUTTON_LEFT);
|
||||
if (leftButton == GLFW_PRESS)
|
||||
mousebutton |= IMGUI_MBUT_LEFT;
|
||||
|
||||
imguiBeginFrame(mousex, mousey, mousebutton, mscroll);
|
||||
|
||||
sSimulate();
|
||||
sInterface();
|
||||
|
||||
// Measure speed
|
||||
double time2 = glfwGetTime();
|
||||
double alpha = 0.9f;
|
||||
frameTime = alpha * frameTime + (1.0 - alpha) * (time2 - time1);
|
||||
time1 = time2;
|
||||
|
||||
char buffer[32];
|
||||
snprintf(buffer, 32, "%.1f ms", 1000.0 * frameTime);
|
||||
AddGfxCmdText(5, 5, TEXT_ALIGN_LEFT, buffer, WHITE);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
RenderGLFlush(g_camera.m_width, g_camera.m_height);
|
||||
|
||||
glfwSwapBuffers(mainWindow);
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
g_debugDraw.Destroy();
|
||||
RenderGLDestroy();
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
832
external/Box2D-2.3.1/Box2D/Testbed/Framework/RenderGL3.cpp
vendored
Normal file
832
external/Box2D-2.3.1/Box2D/Testbed/Framework/RenderGL3.cpp
vendored
Normal file
@@ -0,0 +1,832 @@
|
||||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Source altered and distributed from https://github.com/AdrienHerubel/imgui
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <glew/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include "RenderGL3.h"
|
||||
|
||||
// Some math headers don't have PI defined.
|
||||
static const float PI = 3.14159265f;
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
|
||||
// Pull render interface.
|
||||
enum GfxCmdType
|
||||
{
|
||||
GFXCMD_RECT,
|
||||
GFXCMD_TRIANGLE,
|
||||
GFXCMD_LINE,
|
||||
GFXCMD_TEXT,
|
||||
GFXCMD_SCISSOR,
|
||||
};
|
||||
|
||||
struct GfxRect
|
||||
{
|
||||
short x, y, w, h, r;
|
||||
};
|
||||
|
||||
struct GfxText
|
||||
{
|
||||
float x, y;
|
||||
TextAlign align;
|
||||
const char* text;
|
||||
};
|
||||
|
||||
struct GfxLine
|
||||
{
|
||||
short x0, y0, x1, y1, r;
|
||||
};
|
||||
|
||||
struct GfxCmd
|
||||
{
|
||||
char type;
|
||||
char flags;
|
||||
char pad[2];
|
||||
unsigned int col;
|
||||
union
|
||||
{
|
||||
GfxLine line;
|
||||
GfxRect rect;
|
||||
GfxText text;
|
||||
};
|
||||
};
|
||||
|
||||
static const unsigned TEMP_COORD_COUNT = 100;
|
||||
static float g_tempCoords[TEMP_COORD_COUNT * 2];
|
||||
static float g_tempNormals[TEMP_COORD_COUNT * 2];
|
||||
static float g_tempVertices[TEMP_COORD_COUNT * 12 + (TEMP_COORD_COUNT - 2) * 6];
|
||||
static float g_tempTextureCoords[TEMP_COORD_COUNT * 12 + (TEMP_COORD_COUNT - 2) * 6];
|
||||
static float g_tempColors[TEMP_COORD_COUNT * 24 + (TEMP_COORD_COUNT - 2) * 12];
|
||||
|
||||
static const int CIRCLE_VERTS = 8 * 4;
|
||||
static float g_circleVerts[CIRCLE_VERTS * 2];
|
||||
|
||||
static stbtt_bakedchar g_cdata[96]; // ASCII 32..126 is 95 glyphs
|
||||
static GLuint g_ftex = 0;
|
||||
static GLuint g_whitetex = 0;
|
||||
static GLuint g_vao = 0;
|
||||
static GLuint g_vbos[3] = { 0, 0, 0 };
|
||||
static GLuint g_program = 0;
|
||||
static GLuint g_programViewportLocation = 0;
|
||||
static GLuint g_programTextureLocation = 0;
|
||||
|
||||
static const unsigned TEXT_POOL_SIZE = 8000;
|
||||
static char g_textPool[TEXT_POOL_SIZE];
|
||||
static unsigned g_textPoolSize = 0;
|
||||
static const char* allocText(const char* text)
|
||||
{
|
||||
unsigned len = (unsigned)strlen(text) + 1;
|
||||
if (g_textPoolSize + len >= TEXT_POOL_SIZE)
|
||||
return 0;
|
||||
char* dst = &g_textPool[g_textPoolSize];
|
||||
memcpy(dst, text, len);
|
||||
g_textPoolSize += len;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static const unsigned GFXCMD_QUEUE_SIZE = 5000;
|
||||
static GfxCmd g_gfxCmdQueue[GFXCMD_QUEUE_SIZE];
|
||||
static unsigned g_gfxCmdQueueSize = 0;
|
||||
|
||||
static void ResetGfxCmdQueue()
|
||||
{
|
||||
g_gfxCmdQueueSize = 0;
|
||||
g_textPoolSize = 0;
|
||||
}
|
||||
|
||||
void AddGfxCmdScissor(int x, int y, int w, int h)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
GfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = GFXCMD_SCISSOR;
|
||||
cmd.flags = x < 0 ? 0 : 1; // on/off flag.
|
||||
cmd.col = 0;
|
||||
cmd.rect.x = (short)x;
|
||||
cmd.rect.y = (short)y;
|
||||
cmd.rect.w = (short)w;
|
||||
cmd.rect.h = (short)h;
|
||||
}
|
||||
|
||||
void AddGfxCmdRect(float x, float y, float w, float h, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
GfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = GFXCMD_RECT;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.rect.x = (short)(x*8.0f);
|
||||
cmd.rect.y = (short)(y*8.0f);
|
||||
cmd.rect.w = (short)(w*8.0f);
|
||||
cmd.rect.h = (short)(h*8.0f);
|
||||
cmd.rect.r = 0;
|
||||
}
|
||||
|
||||
void AddGfxCmdLine(float x0, float y0, float x1, float y1, float r, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
GfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = GFXCMD_LINE;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.line.x0 = (short)(x0*8.0f);
|
||||
cmd.line.y0 = (short)(y0*8.0f);
|
||||
cmd.line.x1 = (short)(x1*8.0f);
|
||||
cmd.line.y1 = (short)(y1*8.0f);
|
||||
cmd.line.r = (short)(r*8.0f);
|
||||
}
|
||||
|
||||
void AddGfxCmdRoundedRect(float x, float y, float w, float h, float r, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
GfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = GFXCMD_RECT;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.rect.x = (short)(x*8.0f);
|
||||
cmd.rect.y = (short)(y*8.0f);
|
||||
cmd.rect.w = (short)(w*8.0f);
|
||||
cmd.rect.h = (short)(h*8.0f);
|
||||
cmd.rect.r = (short)(r*8.0f);
|
||||
}
|
||||
|
||||
void AddGfxCmdTriangle(int x, int y, int w, int h, int flags, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
GfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = GFXCMD_TRIANGLE;
|
||||
cmd.flags = (char)flags;
|
||||
cmd.col = color;
|
||||
cmd.rect.x = (short)(x*8.0f);
|
||||
cmd.rect.y = (short)(y*8.0f);
|
||||
cmd.rect.w = (short)(w*8.0f);
|
||||
cmd.rect.h = (short)(h*8.0f);
|
||||
}
|
||||
|
||||
//
|
||||
void AddGfxCmdText(float x, float y, TextAlign align, const char* text, unsigned int color)
|
||||
{
|
||||
if (g_gfxCmdQueueSize >= GFXCMD_QUEUE_SIZE)
|
||||
return;
|
||||
GfxCmd& cmd = g_gfxCmdQueue[g_gfxCmdQueueSize++];
|
||||
cmd.type = GFXCMD_TEXT;
|
||||
cmd.flags = 0;
|
||||
cmd.col = color;
|
||||
cmd.text.x = x;
|
||||
cmd.text.y = y;
|
||||
cmd.text.align = align;
|
||||
cmd.text.text = allocText(text);
|
||||
}
|
||||
|
||||
//
|
||||
void AddGfxCmdText(int x, int y, TextAlign align, const char* text, unsigned int color)
|
||||
{
|
||||
AddGfxCmdText(float(x), float(y), align, text, color);
|
||||
}
|
||||
|
||||
//
|
||||
static void sDrawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col)
|
||||
{
|
||||
if (numCoords > TEMP_COORD_COUNT) numCoords = TEMP_COORD_COUNT;
|
||||
|
||||
for (unsigned i = 0, j = numCoords - 1; i < numCoords; j = i++)
|
||||
{
|
||||
const float* v0 = &coords[j * 2];
|
||||
const float* v1 = &coords[i * 2];
|
||||
float dx = v1[0] - v0[0];
|
||||
float dy = v1[1] - v0[1];
|
||||
float d = sqrtf(dx*dx + dy*dy);
|
||||
if (d > 0)
|
||||
{
|
||||
d = 1.0f / d;
|
||||
dx *= d;
|
||||
dy *= d;
|
||||
}
|
||||
g_tempNormals[j * 2 + 0] = dy;
|
||||
g_tempNormals[j * 2 + 1] = -dx;
|
||||
}
|
||||
|
||||
float colf[4] = { (float)(col & 0xff) / 255.f, (float)((col >> 8) & 0xff) / 255.f, (float)((col >> 16) & 0xff) / 255.f, (float)((col >> 24) & 0xff) / 255.f };
|
||||
float colTransf[4] = { (float)(col & 0xff) / 255.f, (float)((col >> 8) & 0xff) / 255.f, (float)((col >> 16) & 0xff) / 255.f, 0 };
|
||||
|
||||
for (unsigned i = 0, j = numCoords - 1; i < numCoords; j = i++)
|
||||
{
|
||||
float dlx0 = g_tempNormals[j * 2 + 0];
|
||||
float dly0 = g_tempNormals[j * 2 + 1];
|
||||
float dlx1 = g_tempNormals[i * 2 + 0];
|
||||
float dly1 = g_tempNormals[i * 2 + 1];
|
||||
float dmx = (dlx0 + dlx1) * 0.5f;
|
||||
float dmy = (dly0 + dly1) * 0.5f;
|
||||
float dmr2 = dmx*dmx + dmy*dmy;
|
||||
if (dmr2 > 0.000001f)
|
||||
{
|
||||
float scale = 1.0f / dmr2;
|
||||
if (scale > 10.0f) scale = 10.0f;
|
||||
dmx *= scale;
|
||||
dmy *= scale;
|
||||
}
|
||||
g_tempCoords[i * 2 + 0] = coords[i * 2 + 0] + dmx*r;
|
||||
g_tempCoords[i * 2 + 1] = coords[i * 2 + 1] + dmy*r;
|
||||
}
|
||||
|
||||
int vSize = numCoords * 12 + (numCoords - 2) * 6;
|
||||
int uvSize = numCoords * 2 * 6 + (numCoords - 2) * 2 * 3;
|
||||
int cSize = numCoords * 4 * 6 + (numCoords - 2) * 4 * 3;
|
||||
float * v = g_tempVertices;
|
||||
float * uv = g_tempTextureCoords;
|
||||
memset(uv, 0, uvSize * sizeof(float));
|
||||
float * c = g_tempColors;
|
||||
memset(c, 1, cSize * sizeof(float));
|
||||
|
||||
float * ptrV = v;
|
||||
float * ptrC = c;
|
||||
for (unsigned i = 0, j = numCoords - 1; i < numCoords; j = i++)
|
||||
{
|
||||
*ptrV = coords[i * 2];
|
||||
*(ptrV + 1) = coords[i * 2 + 1];
|
||||
ptrV += 2;
|
||||
*ptrV = coords[j * 2];
|
||||
*(ptrV + 1) = coords[j * 2 + 1];
|
||||
ptrV += 2;
|
||||
*ptrV = g_tempCoords[j * 2];
|
||||
*(ptrV + 1) = g_tempCoords[j * 2 + 1];
|
||||
ptrV += 2;
|
||||
*ptrV = g_tempCoords[j * 2];
|
||||
*(ptrV + 1) = g_tempCoords[j * 2 + 1];
|
||||
ptrV += 2;
|
||||
*ptrV = g_tempCoords[i * 2];
|
||||
*(ptrV + 1) = g_tempCoords[i * 2 + 1];
|
||||
ptrV += 2;
|
||||
*ptrV = coords[i * 2];
|
||||
*(ptrV + 1) = coords[i * 2 + 1];
|
||||
ptrV += 2;
|
||||
|
||||
*ptrC = colf[0];
|
||||
*(ptrC + 1) = colf[1];
|
||||
*(ptrC + 2) = colf[2];
|
||||
*(ptrC + 3) = colf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colf[0];
|
||||
*(ptrC + 1) = colf[1];
|
||||
*(ptrC + 2) = colf[2];
|
||||
*(ptrC + 3) = colf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colTransf[0];
|
||||
*(ptrC + 1) = colTransf[1];
|
||||
*(ptrC + 2) = colTransf[2];
|
||||
*(ptrC + 3) = colTransf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colTransf[0];
|
||||
*(ptrC + 1) = colTransf[1];
|
||||
*(ptrC + 2) = colTransf[2];
|
||||
*(ptrC + 3) = colTransf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colTransf[0];
|
||||
*(ptrC + 1) = colTransf[1];
|
||||
*(ptrC + 2) = colTransf[2];
|
||||
*(ptrC + 3) = colTransf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colf[0];
|
||||
*(ptrC + 1) = colf[1];
|
||||
*(ptrC + 2) = colf[2];
|
||||
*(ptrC + 3) = colf[3];
|
||||
ptrC += 4;
|
||||
}
|
||||
|
||||
for (unsigned i = 2; i < numCoords; ++i)
|
||||
{
|
||||
*ptrV = coords[0];
|
||||
*(ptrV + 1) = coords[1];
|
||||
ptrV += 2;
|
||||
*ptrV = coords[(i - 1) * 2];
|
||||
*(ptrV + 1) = coords[(i - 1) * 2 + 1];
|
||||
ptrV += 2;
|
||||
*ptrV = coords[i * 2];
|
||||
*(ptrV + 1) = coords[i * 2 + 1];
|
||||
ptrV += 2;
|
||||
|
||||
*ptrC = colf[0];
|
||||
*(ptrC + 1) = colf[1];
|
||||
*(ptrC + 2) = colf[2];
|
||||
*(ptrC + 3) = colf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colf[0];
|
||||
*(ptrC + 1) = colf[1];
|
||||
*(ptrC + 2) = colf[2];
|
||||
*(ptrC + 3) = colf[3];
|
||||
ptrC += 4;
|
||||
*ptrC = colf[0];
|
||||
*(ptrC + 1) = colf[1];
|
||||
*(ptrC + 2) = colf[2];
|
||||
*(ptrC + 3) = colf[3];
|
||||
ptrC += 4;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, g_whitetex);
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, vSize*sizeof(float), v, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, uvSize*sizeof(float), uv, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, cSize*sizeof(float), c, GL_STATIC_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, (numCoords * 2 + numCoords - 2) * 3);
|
||||
}
|
||||
|
||||
static void sDrawRect(float x, float y, float w, float h, float fth, unsigned int col)
|
||||
{
|
||||
float verts[4 * 2] =
|
||||
{
|
||||
x + 0.5f, y + 0.5f,
|
||||
x + w - 0.5f, y + 0.5f,
|
||||
x + w - 0.5f, y + h - 0.5f,
|
||||
x + 0.5f, y + h - 0.5f,
|
||||
};
|
||||
sDrawPolygon(verts, 4, fth, col);
|
||||
}
|
||||
|
||||
/*
|
||||
static void drawEllipse(float x, float y, float w, float h, float fth, unsigned int col)
|
||||
{
|
||||
float verts[CIRCLE_VERTS*2];
|
||||
const float* cverts = g_circleVerts;
|
||||
float* v = verts;
|
||||
|
||||
for (int i = 0; i < CIRCLE_VERTS; ++i)
|
||||
{
|
||||
*v++ = x + cverts[i*2]*w;
|
||||
*v++ = y + cverts[i*2+1]*h;
|
||||
}
|
||||
|
||||
drawPolygon(verts, CIRCLE_VERTS, fth, col);
|
||||
}
|
||||
*/
|
||||
|
||||
static void sDrawRoundedRect(float x, float y, float w, float h, float r, float fth, unsigned int col)
|
||||
{
|
||||
const unsigned n = CIRCLE_VERTS / 4;
|
||||
float verts[(n + 1) * 4 * 2];
|
||||
const float* cverts = g_circleVerts;
|
||||
float* v = verts;
|
||||
|
||||
for (unsigned i = 0; i <= n; ++i)
|
||||
{
|
||||
*v++ = x + w - r + cverts[i * 2] * r;
|
||||
*v++ = y + h - r + cverts[i * 2 + 1] * r;
|
||||
}
|
||||
|
||||
for (unsigned i = n; i <= n * 2; ++i)
|
||||
{
|
||||
*v++ = x + r + cverts[i * 2] * r;
|
||||
*v++ = y + h - r + cverts[i * 2 + 1] * r;
|
||||
}
|
||||
|
||||
for (unsigned i = n * 2; i <= n * 3; ++i)
|
||||
{
|
||||
*v++ = x + r + cverts[i * 2] * r;
|
||||
*v++ = y + r + cverts[i * 2 + 1] * r;
|
||||
}
|
||||
|
||||
for (unsigned i = n * 3; i < n * 4; ++i)
|
||||
{
|
||||
*v++ = x + w - r + cverts[i * 2] * r;
|
||||
*v++ = y + r + cverts[i * 2 + 1] * r;
|
||||
}
|
||||
*v++ = x + w - r + cverts[0] * r;
|
||||
*v++ = y + r + cverts[1] * r;
|
||||
|
||||
sDrawPolygon(verts, (n + 1) * 4, fth, col);
|
||||
}
|
||||
|
||||
//
|
||||
void sRenderLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col)
|
||||
{
|
||||
float dx = x1 - x0;
|
||||
float dy = y1 - y0;
|
||||
float d = sqrtf(dx*dx + dy*dy);
|
||||
if (d > 0.0001f)
|
||||
{
|
||||
d = 1.0f / d;
|
||||
dx *= d;
|
||||
dy *= d;
|
||||
}
|
||||
float nx = dy;
|
||||
float ny = -dx;
|
||||
float verts[4 * 2];
|
||||
r -= fth;
|
||||
r *= 0.5f;
|
||||
if (r < 0.01f) r = 0.01f;
|
||||
dx *= r;
|
||||
dy *= r;
|
||||
nx *= r;
|
||||
ny *= r;
|
||||
|
||||
verts[0] = x0 - dx - nx;
|
||||
verts[1] = y0 - dy - ny;
|
||||
|
||||
verts[2] = x0 - dx + nx;
|
||||
verts[3] = y0 - dy + ny;
|
||||
|
||||
verts[4] = x1 + dx + nx;
|
||||
verts[5] = y1 + dy + ny;
|
||||
|
||||
verts[6] = x1 + dx - nx;
|
||||
verts[7] = y1 + dy - ny;
|
||||
|
||||
sDrawPolygon(verts, 4, fth, col);
|
||||
}
|
||||
|
||||
//
|
||||
bool RenderGLInit(const char* fontpath)
|
||||
{
|
||||
for (int i = 0; i < CIRCLE_VERTS; ++i)
|
||||
{
|
||||
float a = (float)i / (float)CIRCLE_VERTS * PI * 2;
|
||||
g_circleVerts[i * 2 + 0] = cosf(a);
|
||||
g_circleVerts[i * 2 + 1] = sinf(a);
|
||||
}
|
||||
|
||||
// Load font.
|
||||
FILE* fp = fopen(fontpath, "rb");
|
||||
if (!fp) return false;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = (int)ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
unsigned char* ttfBuffer = (unsigned char*)malloc(size);
|
||||
if (!ttfBuffer)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
fread(ttfBuffer, 1, size, fp);
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
|
||||
unsigned char* bmap = (unsigned char*)malloc(512 * 512);
|
||||
if (!bmap)
|
||||
{
|
||||
free(ttfBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
stbtt_BakeFontBitmap(ttfBuffer, 0, 15.0f, bmap, 512, 512, 32, 96, g_cdata);
|
||||
|
||||
// can free ttf_buffer at this point
|
||||
glGenTextures(1, &g_ftex);
|
||||
glBindTexture(GL_TEXTURE_2D, g_ftex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512, 512, 0, GL_RED, GL_UNSIGNED_BYTE, bmap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// can free ttf_buffer at this point
|
||||
unsigned char white_alpha = 255;
|
||||
glGenTextures(1, &g_whitetex);
|
||||
glBindTexture(GL_TEXTURE_2D, g_whitetex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &white_alpha);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glGenVertexArrays(1, &g_vao);
|
||||
glGenBuffers(3, g_vbos);
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[0]);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)* 2, (void*)0);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[1]);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)* 2, (void*)0);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[2]);
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)* 4, (void*)0);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW);
|
||||
g_program = glCreateProgram();
|
||||
|
||||
const char * vs =
|
||||
"#version 150\n"
|
||||
"uniform vec2 Viewport;\n"
|
||||
"in vec2 VertexPosition;\n"
|
||||
"in vec2 VertexTexCoord;\n"
|
||||
"in vec4 VertexColor;\n"
|
||||
"out vec2 texCoord;\n"
|
||||
"out vec4 vertexColor;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" vertexColor = VertexColor;\n"
|
||||
" texCoord = VertexTexCoord;\n"
|
||||
" gl_Position = vec4(VertexPosition * 2.0 / Viewport - 1.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
GLuint vso = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vso, 1, (const char **)&vs, NULL);
|
||||
glCompileShader(vso);
|
||||
glAttachShader(g_program, vso);
|
||||
|
||||
const char * fs =
|
||||
"#version 150\n"
|
||||
"in vec2 texCoord;\n"
|
||||
"in vec4 vertexColor;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"out vec4 Color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" float alpha = texture(Texture, texCoord).r;\n"
|
||||
" Color = vec4(vertexColor.rgb, vertexColor.a * alpha);\n"
|
||||
"}\n";
|
||||
GLuint fso = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
glShaderSource(fso, 1, (const char **)&fs, NULL);
|
||||
glCompileShader(fso);
|
||||
glAttachShader(g_program, fso);
|
||||
|
||||
glBindAttribLocation(g_program, 0, "VertexPosition");
|
||||
glBindAttribLocation(g_program, 1, "VertexTexCoord");
|
||||
glBindAttribLocation(g_program, 2, "VertexColor");
|
||||
glBindFragDataLocation(g_program, 0, "Color");
|
||||
glLinkProgram(g_program);
|
||||
glDeleteShader(vso);
|
||||
glDeleteShader(fso);
|
||||
|
||||
glUseProgram(g_program);
|
||||
g_programViewportLocation = glGetUniformLocation(g_program, "Viewport");
|
||||
g_programTextureLocation = glGetUniformLocation(g_program, "Texture");
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
free(ttfBuffer);
|
||||
free(bmap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
void RenderGLDestroy()
|
||||
{
|
||||
if (g_ftex)
|
||||
{
|
||||
glDeleteTextures(1, &g_ftex);
|
||||
g_ftex = 0;
|
||||
}
|
||||
|
||||
if (g_vao)
|
||||
{
|
||||
glDeleteVertexArrays(1, &g_vao);
|
||||
glDeleteBuffers(3, g_vbos);
|
||||
g_vao = 0;
|
||||
}
|
||||
|
||||
if (g_program)
|
||||
{
|
||||
glDeleteProgram(g_program);
|
||||
g_program = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void sGetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index,
|
||||
float *xpos, float *ypos, stbtt_aligned_quad *q)
|
||||
{
|
||||
stbtt_bakedchar *b = chardata + char_index;
|
||||
int round_x = STBTT_ifloor(*xpos + b->xoff);
|
||||
int round_y = STBTT_ifloor(*ypos - b->yoff);
|
||||
|
||||
q->x0 = (float)round_x;
|
||||
q->y0 = (float)round_y;
|
||||
q->x1 = (float)round_x + b->x1 - b->x0;
|
||||
q->y1 = (float)round_y - b->y1 + b->y0;
|
||||
|
||||
q->s0 = b->x0 / (float)pw;
|
||||
q->t0 = b->y0 / (float)pw;
|
||||
q->s1 = b->x1 / (float)ph;
|
||||
q->t1 = b->y1 / (float)ph;
|
||||
|
||||
*xpos += b->xadvance;
|
||||
}
|
||||
|
||||
static const float g_tabStops[4] = { 150, 210, 270, 330 };
|
||||
|
||||
static float sGetTextLength(stbtt_bakedchar *chardata, const char* text)
|
||||
{
|
||||
float xpos = 0;
|
||||
float len = 0;
|
||||
while (*text)
|
||||
{
|
||||
int c = (unsigned char)*text;
|
||||
if (c == '\t')
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (xpos < g_tabStops[i])
|
||||
{
|
||||
xpos = g_tabStops[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c >= 32 && c < 128)
|
||||
{
|
||||
stbtt_bakedchar *b = chardata + c - 32;
|
||||
int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5);
|
||||
len = round_x + b->x1 - b->x0 + 0.5f;
|
||||
xpos += b->xadvance;
|
||||
}
|
||||
++text;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
//
|
||||
void sRenderString(float x, float y, const char *text, TextAlign align, unsigned int col)
|
||||
{
|
||||
if (!g_ftex) return;
|
||||
if (!text) return;
|
||||
|
||||
if (align == TEXT_ALIGN_CENTER)
|
||||
x -= sGetTextLength(g_cdata, text) / 2;
|
||||
else if (align == TEXT_ALIGN_RIGHT)
|
||||
x -= sGetTextLength(g_cdata, text);
|
||||
|
||||
float r = (float)(col & 0xff) / 255.f;
|
||||
float g = (float)((col >> 8) & 0xff) / 255.f;
|
||||
float b = (float)((col >> 16) & 0xff) / 255.f;
|
||||
float a = (float)((col >> 24) & 0xff) / 255.f;
|
||||
|
||||
// assume orthographic projection with units = screen pixels, origin at top left
|
||||
glBindTexture(GL_TEXTURE_2D, g_ftex);
|
||||
|
||||
const float ox = x;
|
||||
|
||||
while (*text)
|
||||
{
|
||||
int c = (unsigned char)*text;
|
||||
if (c == '\t')
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (x < g_tabStops[i] + ox)
|
||||
{
|
||||
x = g_tabStops[i] + ox;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c >= 32 && c < 128)
|
||||
{
|
||||
stbtt_aligned_quad q;
|
||||
sGetBakedQuad(g_cdata, 512, 512, c - 32, &x, &y, &q);
|
||||
|
||||
float v[12] = {
|
||||
q.x0, q.y0,
|
||||
q.x1, q.y1,
|
||||
q.x1, q.y0,
|
||||
q.x0, q.y0,
|
||||
q.x0, q.y1,
|
||||
q.x1, q.y1,
|
||||
};
|
||||
float uv[12] = {
|
||||
q.s0, q.t0,
|
||||
q.s1, q.t1,
|
||||
q.s1, q.t0,
|
||||
q.s0, q.t0,
|
||||
q.s0, q.t1,
|
||||
q.s1, q.t1,
|
||||
};
|
||||
float color[24] = {
|
||||
r, g, b, a,
|
||||
r, g, b, a,
|
||||
r, g, b, a,
|
||||
r, g, b, a,
|
||||
r, g, b, a,
|
||||
r, g, b, a,
|
||||
};
|
||||
glBindVertexArray(g_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), v, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), uv, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vbos[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), color, GL_STATIC_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
}
|
||||
++text;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void RenderGLFlush(int width, int height)
|
||||
{
|
||||
const GfxCmd* q = g_gfxCmdQueue;
|
||||
int nq = g_gfxCmdQueueSize;
|
||||
|
||||
const float s = 1.0f / 8.0f;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glUseProgram(g_program);
|
||||
glUniform2f(g_programViewportLocation, (float)width, (float)height);
|
||||
glUniform1i(g_programTextureLocation, 0);
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
for (int i = 0; i < nq; ++i)
|
||||
{
|
||||
const GfxCmd& cmd = q[i];
|
||||
if (cmd.type == GFXCMD_RECT)
|
||||
{
|
||||
if (cmd.rect.r == 0)
|
||||
{
|
||||
sDrawRect((float)cmd.rect.x*s + 0.5f, (float)cmd.rect.y*s + 0.5f,
|
||||
(float)cmd.rect.w*s - 1, (float)cmd.rect.h*s - 1,
|
||||
1.0f, cmd.col);
|
||||
}
|
||||
else
|
||||
{
|
||||
sDrawRoundedRect((float)cmd.rect.x*s + 0.5f, (float)cmd.rect.y*s + 0.5f,
|
||||
(float)cmd.rect.w*s - 1, (float)cmd.rect.h*s - 1,
|
||||
(float)cmd.rect.r*s, 1.0f, cmd.col);
|
||||
}
|
||||
}
|
||||
else if (cmd.type == GFXCMD_LINE)
|
||||
{
|
||||
sRenderLine(cmd.line.x0*s, cmd.line.y0*s, cmd.line.x1*s, cmd.line.y1*s, cmd.line.r*s, 1.0f, cmd.col);
|
||||
}
|
||||
else if (cmd.type == GFXCMD_TRIANGLE)
|
||||
{
|
||||
if (cmd.flags == 1)
|
||||
{
|
||||
const float verts[3 * 2] =
|
||||
{
|
||||
(float)cmd.rect.x*s + 0.5f, (float)cmd.rect.y*s + 0.5f,
|
||||
(float)cmd.rect.x*s + 0.5f + (float)cmd.rect.w*s - 1, (float)cmd.rect.y*s + 0.5f + (float)cmd.rect.h*s / 2 - 0.5f,
|
||||
(float)cmd.rect.x*s + 0.5f, (float)cmd.rect.y*s + 0.5f + (float)cmd.rect.h*s - 1,
|
||||
};
|
||||
sDrawPolygon(verts, 3, 1.0f, cmd.col);
|
||||
}
|
||||
if (cmd.flags == 2)
|
||||
{
|
||||
const float verts[3 * 2] =
|
||||
{
|
||||
(float)cmd.rect.x*s + 0.5f, (float)cmd.rect.y*s + 0.5f + (float)cmd.rect.h*s - 1,
|
||||
(float)cmd.rect.x*s + 0.5f + (float)cmd.rect.w*s / 2 - 0.5f, (float)cmd.rect.y*s + 0.5f,
|
||||
(float)cmd.rect.x*s + 0.5f + (float)cmd.rect.w*s - 1, (float)cmd.rect.y*s + 0.5f + (float)cmd.rect.h*s - 1,
|
||||
};
|
||||
sDrawPolygon(verts, 3, 1.0f, cmd.col);
|
||||
}
|
||||
}
|
||||
else if (cmd.type == GFXCMD_TEXT)
|
||||
{
|
||||
sRenderString(cmd.text.x, cmd.text.y, cmd.text.text, cmd.text.align, cmd.col);
|
||||
}
|
||||
else if (cmd.type == GFXCMD_SCISSOR)
|
||||
{
|
||||
if (cmd.flags)
|
||||
{
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glUseProgram(0);
|
||||
|
||||
ResetGfxCmdQueue();
|
||||
}
|
||||
|
||||
53
external/Box2D-2.3.1/Box2D/Testbed/Framework/RenderGL3.h
vendored
Normal file
53
external/Box2D-2.3.1/Box2D/Testbed/Framework/RenderGL3.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Source altered and distributed from https://github.com/AdrienHerubel/imgui
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Box2D/Common/b2Math.h>
|
||||
|
||||
#define SILVER (220 | (220 << 8) | (220 << 16) | (255 << 24))
|
||||
#define WHITE (255 | (255 << 8) | (255 << 16) | (255 << 24))
|
||||
#define RED (255 | (0 << 8) | (0 << 16) | (255 << 24))
|
||||
#define GREEN (0 | (255 << 8) | (0 << 16) | (255 << 24))
|
||||
#define BLUE (0 | (0 << 8) | (255 << 16) | (255 << 24))
|
||||
|
||||
enum TextAlign
|
||||
{
|
||||
TEXT_ALIGN_LEFT,
|
||||
TEXT_ALIGN_CENTER,
|
||||
TEXT_ALIGN_RIGHT,
|
||||
};
|
||||
|
||||
inline unsigned int SetRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
||||
{
|
||||
return (r) | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
bool RenderGLInit(const char* fontpath);
|
||||
void RenderGLDestroy();
|
||||
void RenderGLFlush(int width, int height);
|
||||
|
||||
void AddGfxCmdScissor(int x, int y, int w, int h);
|
||||
void AddGfxCmdRect(float x, float y, float w, float h, unsigned int color);
|
||||
void AddGfxCmdRoundedRect(float x, float y, float w, float h, float r, unsigned int color);
|
||||
void AddGfxCmdLine(float x0, float y0, float x1, float y1, float r, unsigned int color);
|
||||
void AddGfxCmdTriangle(int x, int y, int w, int h, int flags, unsigned int color);
|
||||
void AddGfxCmdText(float x, float y, TextAlign align, const char* text, unsigned int color);
|
||||
void AddGfxCmdText(int x, int y, TextAlign align, const char* text, unsigned int color);
|
||||
456
external/Box2D-2.3.1/Box2D/Testbed/Framework/Test.cpp
vendored
Normal file
456
external/Box2D-2.3.1/Box2D/Testbed/Framework/Test.cpp
vendored
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "Test.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void DestructionListener::SayGoodbye(b2Joint* joint)
|
||||
{
|
||||
if (test->m_mouseJoint == joint)
|
||||
{
|
||||
test->m_mouseJoint = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
test->JointDestroyed(joint);
|
||||
}
|
||||
}
|
||||
|
||||
Test::Test()
|
||||
{
|
||||
b2Vec2 gravity;
|
||||
gravity.Set(0.0f, -10.0f);
|
||||
m_world = new b2World(gravity);
|
||||
m_bomb = NULL;
|
||||
m_textLine = 30;
|
||||
m_mouseJoint = NULL;
|
||||
m_pointCount = 0;
|
||||
|
||||
m_destructionListener.test = this;
|
||||
m_world->SetDestructionListener(&m_destructionListener);
|
||||
m_world->SetContactListener(this);
|
||||
m_world->SetDebugDraw(&g_debugDraw);
|
||||
|
||||
m_bombSpawning = false;
|
||||
|
||||
m_stepCount = 0;
|
||||
|
||||
b2BodyDef bodyDef;
|
||||
m_groundBody = m_world->CreateBody(&bodyDef);
|
||||
|
||||
memset(&m_maxProfile, 0, sizeof(b2Profile));
|
||||
memset(&m_totalProfile, 0, sizeof(b2Profile));
|
||||
}
|
||||
|
||||
Test::~Test()
|
||||
{
|
||||
// By deleting the world, we delete the bomb, mouse joint, etc.
|
||||
delete m_world;
|
||||
m_world = NULL;
|
||||
}
|
||||
|
||||
void Test::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
|
||||
{
|
||||
const b2Manifold* manifold = contact->GetManifold();
|
||||
|
||||
if (manifold->pointCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
b2Fixture* fixtureA = contact->GetFixtureA();
|
||||
b2Fixture* fixtureB = contact->GetFixtureB();
|
||||
|
||||
b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints];
|
||||
b2GetPointStates(state1, state2, oldManifold, manifold);
|
||||
|
||||
b2WorldManifold worldManifold;
|
||||
contact->GetWorldManifold(&worldManifold);
|
||||
|
||||
for (int32 i = 0; i < manifold->pointCount && m_pointCount < k_maxContactPoints; ++i)
|
||||
{
|
||||
ContactPoint* cp = m_points + m_pointCount;
|
||||
cp->fixtureA = fixtureA;
|
||||
cp->fixtureB = fixtureB;
|
||||
cp->position = worldManifold.points[i];
|
||||
cp->normal = worldManifold.normal;
|
||||
cp->state = state2[i];
|
||||
cp->normalImpulse = manifold->points[i].normalImpulse;
|
||||
cp->tangentImpulse = manifold->points[i].tangentImpulse;
|
||||
cp->separation = worldManifold.separations[i];
|
||||
++m_pointCount;
|
||||
}
|
||||
}
|
||||
|
||||
void Test::DrawTitle(const char *string)
|
||||
{
|
||||
g_debugDraw.DrawString(5, DRAW_STRING_NEW_LINE, string);
|
||||
m_textLine = 3 * DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
class QueryCallback : public b2QueryCallback
|
||||
{
|
||||
public:
|
||||
QueryCallback(const b2Vec2& point)
|
||||
{
|
||||
m_point = point;
|
||||
m_fixture = NULL;
|
||||
}
|
||||
|
||||
bool ReportFixture(b2Fixture* fixture)
|
||||
{
|
||||
b2Body* body = fixture->GetBody();
|
||||
if (body->GetType() == b2_dynamicBody)
|
||||
{
|
||||
bool inside = fixture->TestPoint(m_point);
|
||||
if (inside)
|
||||
{
|
||||
m_fixture = fixture;
|
||||
|
||||
// We are done, terminate the query.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Continue the query.
|
||||
return true;
|
||||
}
|
||||
|
||||
b2Vec2 m_point;
|
||||
b2Fixture* m_fixture;
|
||||
};
|
||||
|
||||
void Test::MouseDown(const b2Vec2& p)
|
||||
{
|
||||
m_mouseWorld = p;
|
||||
|
||||
if (m_mouseJoint != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a small box.
|
||||
b2AABB aabb;
|
||||
b2Vec2 d;
|
||||
d.Set(0.001f, 0.001f);
|
||||
aabb.lowerBound = p - d;
|
||||
aabb.upperBound = p + d;
|
||||
|
||||
// Query the world for overlapping shapes.
|
||||
QueryCallback callback(p);
|
||||
m_world->QueryAABB(&callback, aabb);
|
||||
|
||||
if (callback.m_fixture)
|
||||
{
|
||||
b2Body* body = callback.m_fixture->GetBody();
|
||||
b2MouseJointDef md;
|
||||
md.bodyA = m_groundBody;
|
||||
md.bodyB = body;
|
||||
md.target = p;
|
||||
md.maxForce = 1000.0f * body->GetMass();
|
||||
m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
|
||||
body->SetAwake(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Test::SpawnBomb(const b2Vec2& worldPt)
|
||||
{
|
||||
m_bombSpawnPoint = worldPt;
|
||||
m_bombSpawning = true;
|
||||
}
|
||||
|
||||
void Test::CompleteBombSpawn(const b2Vec2& p)
|
||||
{
|
||||
if (m_bombSpawning == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float multiplier = 30.0f;
|
||||
b2Vec2 vel = m_bombSpawnPoint - p;
|
||||
vel *= multiplier;
|
||||
LaunchBomb(m_bombSpawnPoint,vel);
|
||||
m_bombSpawning = false;
|
||||
}
|
||||
|
||||
void Test::ShiftMouseDown(const b2Vec2& p)
|
||||
{
|
||||
m_mouseWorld = p;
|
||||
|
||||
if (m_mouseJoint != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnBomb(p);
|
||||
}
|
||||
|
||||
void Test::MouseUp(const b2Vec2& p)
|
||||
{
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
m_world->DestroyJoint(m_mouseJoint);
|
||||
m_mouseJoint = NULL;
|
||||
}
|
||||
|
||||
if (m_bombSpawning)
|
||||
{
|
||||
CompleteBombSpawn(p);
|
||||
}
|
||||
}
|
||||
|
||||
void Test::MouseMove(const b2Vec2& p)
|
||||
{
|
||||
m_mouseWorld = p;
|
||||
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
m_mouseJoint->SetTarget(p);
|
||||
}
|
||||
}
|
||||
|
||||
void Test::LaunchBomb()
|
||||
{
|
||||
b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f);
|
||||
b2Vec2 v = -5.0f * p;
|
||||
LaunchBomb(p, v);
|
||||
}
|
||||
|
||||
void Test::LaunchBomb(const b2Vec2& position, const b2Vec2& velocity)
|
||||
{
|
||||
if (m_bomb)
|
||||
{
|
||||
m_world->DestroyBody(m_bomb);
|
||||
m_bomb = NULL;
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = position;
|
||||
bd.bullet = true;
|
||||
m_bomb = m_world->CreateBody(&bd);
|
||||
m_bomb->SetLinearVelocity(velocity);
|
||||
|
||||
b2CircleShape circle;
|
||||
circle.m_radius = 0.3f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &circle;
|
||||
fd.density = 20.0f;
|
||||
fd.restitution = 0.0f;
|
||||
|
||||
b2Vec2 minV = position - b2Vec2(0.3f,0.3f);
|
||||
b2Vec2 maxV = position + b2Vec2(0.3f,0.3f);
|
||||
|
||||
b2AABB aabb;
|
||||
aabb.lowerBound = minV;
|
||||
aabb.upperBound = maxV;
|
||||
|
||||
m_bomb->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
void Test::Step(Settings* settings)
|
||||
{
|
||||
float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
|
||||
|
||||
if (settings->pause)
|
||||
{
|
||||
if (settings->singleStep)
|
||||
{
|
||||
settings->singleStep = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeStep = 0.0f;
|
||||
}
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
uint32 flags = 0;
|
||||
flags += settings->drawShapes * b2Draw::e_shapeBit;
|
||||
flags += settings->drawJoints * b2Draw::e_jointBit;
|
||||
flags += settings->drawAABBs * b2Draw::e_aabbBit;
|
||||
flags += settings->drawCOMs * b2Draw::e_centerOfMassBit;
|
||||
g_debugDraw.SetFlags(flags);
|
||||
|
||||
m_world->SetAllowSleeping(settings->enableSleep);
|
||||
m_world->SetWarmStarting(settings->enableWarmStarting);
|
||||
m_world->SetContinuousPhysics(settings->enableContinuous);
|
||||
m_world->SetSubStepping(settings->enableSubStepping);
|
||||
|
||||
m_pointCount = 0;
|
||||
|
||||
m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations);
|
||||
|
||||
m_world->DrawDebugData();
|
||||
g_debugDraw.Flush();
|
||||
|
||||
if (timeStep > 0.0f)
|
||||
{
|
||||
++m_stepCount;
|
||||
}
|
||||
|
||||
if (settings->drawStats)
|
||||
{
|
||||
int32 bodyCount = m_world->GetBodyCount();
|
||||
int32 contactCount = m_world->GetContactCount();
|
||||
int32 jointCount = m_world->GetJointCount();
|
||||
g_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints = %d/%d/%d", bodyCount, contactCount, jointCount);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
int32 proxyCount = m_world->GetProxyCount();
|
||||
int32 height = m_world->GetTreeHeight();
|
||||
int32 balance = m_world->GetTreeBalance();
|
||||
float32 quality = m_world->GetTreeQuality();
|
||||
g_debugDraw.DrawString(5, m_textLine, "proxies/height/balance/quality = %d/%d/%d/%g", proxyCount, height, balance, quality);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
// Track maximum profile times
|
||||
{
|
||||
const b2Profile& p = m_world->GetProfile();
|
||||
m_maxProfile.step = b2Max(m_maxProfile.step, p.step);
|
||||
m_maxProfile.collide = b2Max(m_maxProfile.collide, p.collide);
|
||||
m_maxProfile.solve = b2Max(m_maxProfile.solve, p.solve);
|
||||
m_maxProfile.solveInit = b2Max(m_maxProfile.solveInit, p.solveInit);
|
||||
m_maxProfile.solveVelocity = b2Max(m_maxProfile.solveVelocity, p.solveVelocity);
|
||||
m_maxProfile.solvePosition = b2Max(m_maxProfile.solvePosition, p.solvePosition);
|
||||
m_maxProfile.solveTOI = b2Max(m_maxProfile.solveTOI, p.solveTOI);
|
||||
m_maxProfile.broadphase = b2Max(m_maxProfile.broadphase, p.broadphase);
|
||||
|
||||
m_totalProfile.step += p.step;
|
||||
m_totalProfile.collide += p.collide;
|
||||
m_totalProfile.solve += p.solve;
|
||||
m_totalProfile.solveInit += p.solveInit;
|
||||
m_totalProfile.solveVelocity += p.solveVelocity;
|
||||
m_totalProfile.solvePosition += p.solvePosition;
|
||||
m_totalProfile.solveTOI += p.solveTOI;
|
||||
m_totalProfile.broadphase += p.broadphase;
|
||||
}
|
||||
|
||||
if (settings->drawProfile)
|
||||
{
|
||||
const b2Profile& p = m_world->GetProfile();
|
||||
|
||||
b2Profile aveProfile;
|
||||
memset(&aveProfile, 0, sizeof(b2Profile));
|
||||
if (m_stepCount > 0)
|
||||
{
|
||||
float32 scale = 1.0f / m_stepCount;
|
||||
aveProfile.step = scale * m_totalProfile.step;
|
||||
aveProfile.collide = scale * m_totalProfile.collide;
|
||||
aveProfile.solve = scale * m_totalProfile.solve;
|
||||
aveProfile.solveInit = scale * m_totalProfile.solveInit;
|
||||
aveProfile.solveVelocity = scale * m_totalProfile.solveVelocity;
|
||||
aveProfile.solvePosition = scale * m_totalProfile.solvePosition;
|
||||
aveProfile.solveTOI = scale * m_totalProfile.solveTOI;
|
||||
aveProfile.broadphase = scale * m_totalProfile.broadphase;
|
||||
}
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "step [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.step, aveProfile.step, m_maxProfile.step);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "collide [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.collide, aveProfile.collide, m_maxProfile.collide);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "solve [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solve, aveProfile.solve, m_maxProfile.solve);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "solve init [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveInit, aveProfile.solveInit, m_maxProfile.solveInit);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "solve velocity [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveVelocity, aveProfile.solveVelocity, m_maxProfile.solveVelocity);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "solve position [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solvePosition, aveProfile.solvePosition, m_maxProfile.solvePosition);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "solveTOI [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveTOI, aveProfile.solveTOI, m_maxProfile.solveTOI);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "broad-phase [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.broadphase, aveProfile.broadphase, m_maxProfile.broadphase);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
b2Vec2 p1 = m_mouseJoint->GetAnchorB();
|
||||
b2Vec2 p2 = m_mouseJoint->GetTarget();
|
||||
|
||||
b2Color c;
|
||||
c.Set(0.0f, 1.0f, 0.0f);
|
||||
g_debugDraw.DrawPoint(p1, 4.0f, c);
|
||||
g_debugDraw.DrawPoint(p2, 4.0f, c);
|
||||
|
||||
c.Set(0.8f, 0.8f, 0.8f);
|
||||
g_debugDraw.DrawSegment(p1, p2, c);
|
||||
}
|
||||
|
||||
if (m_bombSpawning)
|
||||
{
|
||||
b2Color c;
|
||||
c.Set(0.0f, 0.0f, 1.0f);
|
||||
g_debugDraw.DrawPoint(m_bombSpawnPoint, 4.0f, c);
|
||||
|
||||
c.Set(0.8f, 0.8f, 0.8f);
|
||||
g_debugDraw.DrawSegment(m_mouseWorld, m_bombSpawnPoint, c);
|
||||
}
|
||||
|
||||
if (settings->drawContactPoints)
|
||||
{
|
||||
const float32 k_impulseScale = 0.1f;
|
||||
const float32 k_axisScale = 0.3f;
|
||||
|
||||
for (int32 i = 0; i < m_pointCount; ++i)
|
||||
{
|
||||
ContactPoint* point = m_points + i;
|
||||
|
||||
if (point->state == b2_addState)
|
||||
{
|
||||
// Add
|
||||
g_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
|
||||
}
|
||||
else if (point->state == b2_persistState)
|
||||
{
|
||||
// Persist
|
||||
g_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
|
||||
}
|
||||
|
||||
if (settings->drawContactNormals == 1)
|
||||
{
|
||||
b2Vec2 p1 = point->position;
|
||||
b2Vec2 p2 = p1 + k_axisScale * point->normal;
|
||||
g_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f));
|
||||
}
|
||||
else if (settings->drawContactImpulse == 1)
|
||||
{
|
||||
b2Vec2 p1 = point->position;
|
||||
b2Vec2 p2 = p1 + k_impulseScale * point->normalImpulse * point->normal;
|
||||
g_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
|
||||
}
|
||||
|
||||
if (settings->drawFrictionImpulse == 1)
|
||||
{
|
||||
b2Vec2 tangent = b2Cross(point->normal, 1.0f);
|
||||
b2Vec2 p1 = point->position;
|
||||
b2Vec2 p2 = p1 + k_impulseScale * point->tangentImpulse * tangent;
|
||||
g_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Test::ShiftOrigin(const b2Vec2& newOrigin)
|
||||
{
|
||||
m_world->ShiftOrigin(newOrigin);
|
||||
}
|
||||
199
external/Box2D-2.3.1/Box2D/Testbed/Framework/Test.h
vendored
Normal file
199
external/Box2D-2.3.1/Box2D/Testbed/Framework/Test.h
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 TEST_H
|
||||
#define TEST_H
|
||||
|
||||
#include <Box2D/Box2D.h>
|
||||
#include "DebugDraw.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <glew/glew.h>
|
||||
#endif
|
||||
#include <glfw/glfw3.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class Test;
|
||||
struct Settings;
|
||||
|
||||
typedef Test* TestCreateFcn();
|
||||
|
||||
#define RAND_LIMIT 32767
|
||||
#define DRAW_STRING_NEW_LINE 16
|
||||
|
||||
/// Random number in range [-1,1]
|
||||
inline float32 RandomFloat()
|
||||
{
|
||||
float32 r = (float32)(std::rand() & (RAND_LIMIT));
|
||||
r /= RAND_LIMIT;
|
||||
r = 2.0f * r - 1.0f;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Random floating point number in range [lo, hi]
|
||||
inline float32 RandomFloat(float32 lo, float32 hi)
|
||||
{
|
||||
float32 r = (float32)(std::rand() & (RAND_LIMIT));
|
||||
r /= RAND_LIMIT;
|
||||
r = (hi - lo) * r + lo;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Test settings. Some can be controlled in the GUI.
|
||||
struct Settings
|
||||
{
|
||||
Settings()
|
||||
{
|
||||
hz = 60.0f;
|
||||
velocityIterations = 8;
|
||||
positionIterations = 3;
|
||||
drawShapes = true;
|
||||
drawJoints = true;
|
||||
drawAABBs = false;
|
||||
drawContactPoints = false;
|
||||
drawContactNormals = false;
|
||||
drawContactImpulse = false;
|
||||
drawFrictionImpulse = false;
|
||||
drawCOMs = false;
|
||||
drawStats = false;
|
||||
drawProfile = false;
|
||||
enableWarmStarting = true;
|
||||
enableContinuous = true;
|
||||
enableSubStepping = false;
|
||||
enableSleep = true;
|
||||
pause = false;
|
||||
singleStep = false;
|
||||
}
|
||||
|
||||
float32 hz;
|
||||
int32 velocityIterations;
|
||||
int32 positionIterations;
|
||||
bool drawShapes;
|
||||
bool drawJoints;
|
||||
bool drawAABBs;
|
||||
bool drawContactPoints;
|
||||
bool drawContactNormals;
|
||||
bool drawContactImpulse;
|
||||
bool drawFrictionImpulse;
|
||||
bool drawCOMs;
|
||||
bool drawStats;
|
||||
bool drawProfile;
|
||||
bool enableWarmStarting;
|
||||
bool enableContinuous;
|
||||
bool enableSubStepping;
|
||||
bool enableSleep;
|
||||
bool pause;
|
||||
bool singleStep;
|
||||
};
|
||||
|
||||
struct TestEntry
|
||||
{
|
||||
const char *name;
|
||||
TestCreateFcn *createFcn;
|
||||
};
|
||||
|
||||
extern TestEntry g_testEntries[];
|
||||
// This is called when a joint in the world is implicitly destroyed
|
||||
// because an attached body is destroyed. This gives us a chance to
|
||||
// nullify the mouse joint.
|
||||
class DestructionListener : public b2DestructionListener
|
||||
{
|
||||
public:
|
||||
void SayGoodbye(b2Fixture* fixture) { B2_NOT_USED(fixture); }
|
||||
void SayGoodbye(b2Joint* joint);
|
||||
|
||||
Test* test;
|
||||
};
|
||||
|
||||
const int32 k_maxContactPoints = 2048;
|
||||
|
||||
struct ContactPoint
|
||||
{
|
||||
b2Fixture* fixtureA;
|
||||
b2Fixture* fixtureB;
|
||||
b2Vec2 normal;
|
||||
b2Vec2 position;
|
||||
b2PointState state;
|
||||
float32 normalImpulse;
|
||||
float32 tangentImpulse;
|
||||
float32 separation;
|
||||
};
|
||||
|
||||
class Test : public b2ContactListener
|
||||
{
|
||||
public:
|
||||
|
||||
Test();
|
||||
virtual ~Test();
|
||||
|
||||
void DrawTitle(const char *string);
|
||||
virtual void Step(Settings* settings);
|
||||
virtual void Keyboard(int key) { B2_NOT_USED(key); }
|
||||
virtual void KeyboardUp(int key) { B2_NOT_USED(key); }
|
||||
void ShiftMouseDown(const b2Vec2& p);
|
||||
virtual void MouseDown(const b2Vec2& p);
|
||||
virtual void MouseUp(const b2Vec2& p);
|
||||
void MouseMove(const b2Vec2& p);
|
||||
void LaunchBomb();
|
||||
void LaunchBomb(const b2Vec2& position, const b2Vec2& velocity);
|
||||
|
||||
void SpawnBomb(const b2Vec2& worldPt);
|
||||
void CompleteBombSpawn(const b2Vec2& p);
|
||||
|
||||
// Let derived tests know that a joint was destroyed.
|
||||
virtual void JointDestroyed(b2Joint* joint) { B2_NOT_USED(joint); }
|
||||
|
||||
// Callbacks for derived classes.
|
||||
virtual void BeginContact(b2Contact* contact) { B2_NOT_USED(contact); }
|
||||
virtual void EndContact(b2Contact* contact) { B2_NOT_USED(contact); }
|
||||
virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
|
||||
virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
|
||||
{
|
||||
B2_NOT_USED(contact);
|
||||
B2_NOT_USED(impulse);
|
||||
}
|
||||
|
||||
void ShiftOrigin(const b2Vec2& newOrigin);
|
||||
|
||||
protected:
|
||||
friend class DestructionListener;
|
||||
friend class BoundaryListener;
|
||||
friend class ContactListener;
|
||||
|
||||
b2Body* m_groundBody;
|
||||
b2AABB m_worldAABB;
|
||||
ContactPoint m_points[k_maxContactPoints];
|
||||
int32 m_pointCount;
|
||||
DestructionListener m_destructionListener;
|
||||
int32 m_textLine;
|
||||
b2World* m_world;
|
||||
b2Body* m_bomb;
|
||||
b2MouseJoint* m_mouseJoint;
|
||||
b2Vec2 m_bombSpawnPoint;
|
||||
bool m_bombSpawning;
|
||||
b2Vec2 m_mouseWorld;
|
||||
int32 m_stepCount;
|
||||
|
||||
b2Profile m_maxProfile;
|
||||
b2Profile m_totalProfile;
|
||||
};
|
||||
|
||||
#endif
|
||||
616
external/Box2D-2.3.1/Box2D/Testbed/Framework/imgui.cpp
vendored
Normal file
616
external/Box2D-2.3.1/Box2D/Testbed/Framework/imgui.cpp
vendored
Normal file
@@ -0,0 +1,616 @@
|
||||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Source altered and distributed from https://github.com/AdrienHerubel/imgui
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include "imgui.h"
|
||||
#include "RenderGL3.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct GuiState
|
||||
{
|
||||
GuiState()
|
||||
{
|
||||
left = false;
|
||||
leftPressed = false;
|
||||
leftReleased = false;
|
||||
mx = -1;
|
||||
my = -1;
|
||||
scroll = 0;
|
||||
active = 0;
|
||||
hot = 0;
|
||||
hotToBe = 0;
|
||||
isHot = false;
|
||||
isActive = false;
|
||||
wentActive = false;
|
||||
dragX = 0;
|
||||
dragY = 0;
|
||||
dragOrig = 0;
|
||||
widgetX = 0;
|
||||
widgetY = 0;
|
||||
widgetW = 100;
|
||||
insideCurrentScroll = false;
|
||||
areaId = 0;
|
||||
widgetId = 0;
|
||||
}
|
||||
|
||||
bool left;
|
||||
bool leftPressed, leftReleased;
|
||||
int mx, my;
|
||||
int scroll;
|
||||
unsigned int active;
|
||||
unsigned int hot;
|
||||
unsigned int hotToBe;
|
||||
bool isHot;
|
||||
bool isActive;
|
||||
bool wentActive;
|
||||
int dragX, dragY;
|
||||
float dragOrig;
|
||||
int widgetX, widgetY, widgetW;
|
||||
bool insideCurrentScroll;
|
||||
|
||||
unsigned int areaId;
|
||||
unsigned int widgetId;
|
||||
};
|
||||
|
||||
static GuiState s_state;
|
||||
|
||||
inline bool anyActive()
|
||||
{
|
||||
return s_state.active != 0;
|
||||
}
|
||||
|
||||
inline bool isActive(unsigned int id)
|
||||
{
|
||||
return s_state.active == id;
|
||||
}
|
||||
|
||||
inline bool isHot(unsigned int id)
|
||||
{
|
||||
return s_state.hot == id;
|
||||
}
|
||||
|
||||
inline bool inRect(int x, int y, int w, int h, bool checkScroll = true)
|
||||
{
|
||||
return (!checkScroll || s_state.insideCurrentScroll) && s_state.mx >= x && s_state.mx <= x + w && s_state.my >= y && s_state.my <= y + h;
|
||||
}
|
||||
|
||||
inline void clearInput()
|
||||
{
|
||||
s_state.leftPressed = false;
|
||||
s_state.leftReleased = false;
|
||||
s_state.scroll = 0;
|
||||
}
|
||||
|
||||
inline void clearActive()
|
||||
{
|
||||
s_state.active = 0;
|
||||
// mark all UI for this frame as processed
|
||||
clearInput();
|
||||
}
|
||||
|
||||
inline void setActive(unsigned int id)
|
||||
{
|
||||
s_state.active = id;
|
||||
s_state.wentActive = true;
|
||||
}
|
||||
|
||||
inline void setHot(unsigned int id)
|
||||
{
|
||||
s_state.hotToBe = id;
|
||||
}
|
||||
|
||||
|
||||
static bool buttonLogic(unsigned int id, bool over)
|
||||
{
|
||||
bool res = false;
|
||||
// process down
|
||||
if (!anyActive())
|
||||
{
|
||||
if (over)
|
||||
setHot(id);
|
||||
if (isHot(id) && s_state.leftPressed)
|
||||
setActive(id);
|
||||
}
|
||||
|
||||
// if button is active, then react on left up
|
||||
if (isActive(id))
|
||||
{
|
||||
s_state.isActive = true;
|
||||
if (over)
|
||||
setHot(id);
|
||||
if (s_state.leftReleased)
|
||||
{
|
||||
if (isHot(id))
|
||||
res = true;
|
||||
clearActive();
|
||||
}
|
||||
}
|
||||
|
||||
if (isHot(id))
|
||||
s_state.isHot = true;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void updateInput(int mx, int my, unsigned char mbut, int scroll)
|
||||
{
|
||||
bool left = (mbut & IMGUI_MBUT_LEFT) != 0;
|
||||
|
||||
s_state.mx = mx;
|
||||
s_state.my = my;
|
||||
s_state.leftPressed = !s_state.left && left;
|
||||
s_state.leftReleased = s_state.left && !left;
|
||||
s_state.left = left;
|
||||
|
||||
s_state.scroll = scroll;
|
||||
}
|
||||
|
||||
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll)
|
||||
{
|
||||
updateInput(mx, my, mbut, scroll);
|
||||
|
||||
s_state.hot = s_state.hotToBe;
|
||||
s_state.hotToBe = 0;
|
||||
|
||||
s_state.wentActive = false;
|
||||
s_state.isActive = false;
|
||||
s_state.isHot = false;
|
||||
|
||||
s_state.widgetX = 0;
|
||||
s_state.widgetY = 0;
|
||||
s_state.widgetW = 0;
|
||||
|
||||
s_state.areaId = 1;
|
||||
s_state.widgetId = 1;
|
||||
}
|
||||
|
||||
void imguiEndFrame()
|
||||
{
|
||||
clearInput();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static const int BUTTON_HEIGHT = 20;
|
||||
static const int SLIDER_HEIGHT = 20;
|
||||
static const int SLIDER_MARKER_WIDTH = 10;
|
||||
static const int CHECK_SIZE = 8;
|
||||
static const int DEFAULT_SPACING = 4;
|
||||
static const int TEXT_HEIGHT = 8;
|
||||
static const int SCROLL_AREA_PADDING = 6;
|
||||
static const int INDENT_SIZE = 16;
|
||||
static const int AREA_HEADER = 28;
|
||||
|
||||
static int g_scrollTop = 0;
|
||||
static int g_scrollBottom = 0;
|
||||
static int g_scrollRight = 0;
|
||||
static int g_scrollAreaTop = 0;
|
||||
static int* g_scrollVal = 0;
|
||||
static int g_focusTop = 0;
|
||||
static int g_focusBottom = 0;
|
||||
static unsigned int g_scrollId = 0;
|
||||
static bool g_insideScrollArea = false;
|
||||
|
||||
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll)
|
||||
{
|
||||
s_state.areaId++;
|
||||
s_state.widgetId = 0;
|
||||
g_scrollId = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
s_state.widgetX = x + SCROLL_AREA_PADDING;
|
||||
s_state.widgetY = y + h - AREA_HEADER + (*scroll);
|
||||
s_state.widgetW = w - SCROLL_AREA_PADDING * 4;
|
||||
g_scrollTop = y - AREA_HEADER + h;
|
||||
g_scrollBottom = y + SCROLL_AREA_PADDING;
|
||||
g_scrollRight = x + w - SCROLL_AREA_PADDING * 3;
|
||||
g_scrollVal = scroll;
|
||||
|
||||
g_scrollAreaTop = s_state.widgetY;
|
||||
|
||||
g_focusTop = y - AREA_HEADER;
|
||||
g_focusBottom = y - AREA_HEADER + h;
|
||||
|
||||
g_insideScrollArea = inRect(x, y, w, h, false);
|
||||
s_state.insideCurrentScroll = g_insideScrollArea;
|
||||
|
||||
AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, SetRGBA(0, 0, 0, 192));
|
||||
|
||||
AddGfxCmdText(x + AREA_HEADER / 2, y + h - AREA_HEADER / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, name, SetRGBA(255, 255, 255, 128));
|
||||
|
||||
AddGfxCmdScissor(x + SCROLL_AREA_PADDING, y + SCROLL_AREA_PADDING, w - SCROLL_AREA_PADDING * 4, h - AREA_HEADER - SCROLL_AREA_PADDING);
|
||||
|
||||
return g_insideScrollArea;
|
||||
}
|
||||
|
||||
void imguiEndScrollArea()
|
||||
{
|
||||
// Disable scissoring.
|
||||
AddGfxCmdScissor(-1, -1, -1, -1);
|
||||
|
||||
// Draw scroll bar
|
||||
int x = g_scrollRight + SCROLL_AREA_PADDING / 2;
|
||||
int y = g_scrollBottom;
|
||||
int w = SCROLL_AREA_PADDING * 2;
|
||||
int h = g_scrollTop - g_scrollBottom;
|
||||
|
||||
int stop = g_scrollAreaTop;
|
||||
int sbot = s_state.widgetY;
|
||||
int sh = stop - sbot; // The scrollable area height.
|
||||
|
||||
float barHeight = (float)h / (float)sh;
|
||||
|
||||
if (barHeight < 1)
|
||||
{
|
||||
float barY = (float)(y - sbot) / (float)sh;
|
||||
if (barY < 0) barY = 0;
|
||||
if (barY > 1) barY = 1;
|
||||
|
||||
// Handle scroll bar logic.
|
||||
unsigned int hid = g_scrollId;
|
||||
int hx = x;
|
||||
int hy = y + (int)(barY*h);
|
||||
int hw = w;
|
||||
int hh = (int)(barHeight*h);
|
||||
|
||||
const int range = h - (hh - 1);
|
||||
bool over = inRect(hx, hy, hw, hh);
|
||||
buttonLogic(hid, over);
|
||||
if (isActive(hid))
|
||||
{
|
||||
float u = (float)(hy - y) / (float)range;
|
||||
if (s_state.wentActive)
|
||||
{
|
||||
s_state.dragY = s_state.my;
|
||||
s_state.dragOrig = u;
|
||||
}
|
||||
if (s_state.dragY != s_state.my)
|
||||
{
|
||||
u = s_state.dragOrig + (s_state.my - s_state.dragY) / (float)range;
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
*g_scrollVal = (int)((1 - u) * (sh - h));
|
||||
}
|
||||
}
|
||||
|
||||
// BG
|
||||
AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)w / 2 - 1, SetRGBA(0, 0, 0, 196));
|
||||
// Bar
|
||||
if (isActive(hid))
|
||||
AddGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w / 2 - 1, SetRGBA(255, 196, 0, 196));
|
||||
else
|
||||
AddGfxCmdRoundedRect((float)hx, (float)hy, (float)hw, (float)hh, (float)w / 2 - 1, isHot(hid) ? SetRGBA(255, 196, 0, 96) : SetRGBA(255, 255, 255, 64));
|
||||
|
||||
// Handle mouse scrolling.
|
||||
if (g_insideScrollArea) // && !anyActive())
|
||||
{
|
||||
if (s_state.scroll)
|
||||
{
|
||||
*g_scrollVal += 20 * s_state.scroll;
|
||||
if (*g_scrollVal < 0) *g_scrollVal = 0;
|
||||
if (*g_scrollVal >(sh - h)) *g_scrollVal = (sh - h);
|
||||
}
|
||||
}
|
||||
}
|
||||
s_state.insideCurrentScroll = false;
|
||||
}
|
||||
|
||||
bool imguiButton(const char* text, bool enabled)
|
||||
{
|
||||
s_state.widgetId++;
|
||||
unsigned int id = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = s_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
s_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)BUTTON_HEIGHT / 2 - 1, SetRGBA(128, 128, 128, isActive(id) ? 196 : 96));
|
||||
if (enabled)
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
else
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool imguiItem(const char* text, bool enabled)
|
||||
{
|
||||
s_state.widgetId++;
|
||||
unsigned int id = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = s_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
s_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
if (isHot(id))
|
||||
AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 2.0f, SetRGBA(255, 196, 0, isActive(id) ? 196 : 96));
|
||||
|
||||
if (enabled)
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(255, 255, 255, 200));
|
||||
else
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool imguiCheck(const char* text, bool checked, bool enabled)
|
||||
{
|
||||
s_state.widgetId++;
|
||||
unsigned int id = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = s_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
s_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
const int cx = x + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2;
|
||||
const int cy = y + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2;
|
||||
AddGfxCmdRoundedRect((float)cx - 3, (float)cy - 3, (float)CHECK_SIZE + 6, (float)CHECK_SIZE + 6, 4, SetRGBA(128, 128, 128, isActive(id) ? 196 : 96));
|
||||
if (checked)
|
||||
{
|
||||
if (enabled)
|
||||
AddGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE / 2 - 1, SetRGBA(255, 255, 255, isActive(id) ? 255 : 200));
|
||||
else
|
||||
AddGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE / 2 - 1, SetRGBA(128, 128, 128, 200));
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
else
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled)
|
||||
{
|
||||
s_state.widgetId++;
|
||||
unsigned int id = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = s_state.widgetW;
|
||||
int h = BUTTON_HEIGHT;
|
||||
s_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING;
|
||||
|
||||
const int cx = x + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2;
|
||||
const int cy = y + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2;
|
||||
|
||||
bool over = enabled && inRect(x, y, w, h);
|
||||
bool res = buttonLogic(id, over);
|
||||
|
||||
if (checked)
|
||||
AddGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 2, SetRGBA(255, 255, 255, isActive(id) ? 255 : 200));
|
||||
else
|
||||
AddGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 1, SetRGBA(255, 255, 255, isActive(id) ? 255 : 200));
|
||||
|
||||
if (enabled)
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
else
|
||||
AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200));
|
||||
|
||||
if (subtext)
|
||||
AddGfxCmdText(x + w - BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, subtext, SetRGBA(255, 255, 255, 128));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void imguiLabel(const char* text)
|
||||
{
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
s_state.widgetY -= BUTTON_HEIGHT;
|
||||
AddGfxCmdText(x, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
void imguiValue(const char* text)
|
||||
{
|
||||
const int x = s_state.widgetX;
|
||||
const int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
const int w = s_state.widgetW;
|
||||
s_state.widgetY -= BUTTON_HEIGHT;
|
||||
|
||||
AddGfxCmdText(x + w - BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, text, SetRGBA(255, 255, 255, 200));
|
||||
}
|
||||
|
||||
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled)
|
||||
{
|
||||
s_state.widgetId++;
|
||||
unsigned int id = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = s_state.widgetW;
|
||||
int h = SLIDER_HEIGHT;
|
||||
s_state.widgetY -= SLIDER_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, SetRGBA(0, 0, 0, 128));
|
||||
|
||||
const int range = w - SLIDER_MARKER_WIDTH;
|
||||
|
||||
float u = (*val - vmin) / (vmax - vmin);
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
int m = (int)(u * range);
|
||||
|
||||
bool over = enabled && inRect(x + m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT);
|
||||
bool res = buttonLogic(id, over);
|
||||
bool valChanged = false;
|
||||
|
||||
if (isActive(id))
|
||||
{
|
||||
if (s_state.wentActive)
|
||||
{
|
||||
s_state.dragX = s_state.mx;
|
||||
s_state.dragOrig = u;
|
||||
}
|
||||
if (s_state.dragX != s_state.mx)
|
||||
{
|
||||
u = s_state.dragOrig + (float)(s_state.mx - s_state.dragX) / (float)range;
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
*val = vmin + u*(vmax - vmin);
|
||||
*val = floorf(*val / vinc + 0.5f)*vinc; // Snap to vinc
|
||||
m = (int)(u * range);
|
||||
valChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isActive(id))
|
||||
AddGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, SetRGBA(255, 255, 255, 255));
|
||||
else
|
||||
AddGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? SetRGBA(255, 196, 0, 128) : SetRGBA(255, 255, 255, 64));
|
||||
|
||||
// TODO: fix this, take a look at 'nicenum'.
|
||||
int digits = (int)(ceilf(log10f(vinc)));
|
||||
char fmt[16];
|
||||
snprintf(fmt, 16, "%%.%df", digits >= 0 ? 0 : -digits);
|
||||
char msg[128];
|
||||
snprintf(msg, 128, fmt, *val);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
AddGfxCmdText(x + SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
AddGfxCmdText(x + w - SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, msg, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddGfxCmdText(x + SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200));
|
||||
AddGfxCmdText(x + w - SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, msg, SetRGBA(128, 128, 128, 200));
|
||||
}
|
||||
|
||||
return res || valChanged;
|
||||
}
|
||||
|
||||
|
||||
bool imguiSlider(const char* text, int* val, int vmin, int vmax, int vinc, bool enabled)
|
||||
{
|
||||
s_state.widgetId++;
|
||||
unsigned int id = (s_state.areaId << 16) | s_state.widgetId;
|
||||
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - BUTTON_HEIGHT;
|
||||
int w = s_state.widgetW;
|
||||
int h = SLIDER_HEIGHT;
|
||||
s_state.widgetY -= SLIDER_HEIGHT + DEFAULT_SPACING;
|
||||
|
||||
AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, SetRGBA(0, 0, 0, 128));
|
||||
|
||||
const int range = w - SLIDER_MARKER_WIDTH;
|
||||
|
||||
float u = (*val - vmin) / float(vmax - vmin);
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
int m = (int)(u * range);
|
||||
|
||||
bool over = enabled && inRect(x + m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT);
|
||||
bool res = buttonLogic(id, over);
|
||||
bool valChanged = false;
|
||||
|
||||
if (isActive(id))
|
||||
{
|
||||
if (s_state.wentActive)
|
||||
{
|
||||
s_state.dragX = s_state.mx;
|
||||
s_state.dragOrig = u;
|
||||
}
|
||||
if (s_state.dragX != s_state.mx)
|
||||
{
|
||||
u = s_state.dragOrig + (float)(s_state.mx - s_state.dragX) / (float)range;
|
||||
if (u < 0) u = 0;
|
||||
if (u > 1) u = 1;
|
||||
*val = int(vmin + u*(vmax - vmin));
|
||||
*val = int(floorf(*val / float(vinc) + 0.5f))*vinc; // Snap to vinc
|
||||
m = (int)(u * range);
|
||||
valChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isActive(id))
|
||||
AddGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, SetRGBA(255, 255, 255, 255));
|
||||
else
|
||||
AddGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? SetRGBA(255, 196, 0, 128) : SetRGBA(255, 255, 255, 64));
|
||||
|
||||
char msg[128];
|
||||
snprintf(msg, 128, "%d", *val);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
AddGfxCmdText(x + SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
AddGfxCmdText(x + w - SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, msg, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddGfxCmdText(x + SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200));
|
||||
AddGfxCmdText(x + w - SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, msg, SetRGBA(128, 128, 128, 200));
|
||||
}
|
||||
|
||||
return res || valChanged;
|
||||
}
|
||||
|
||||
|
||||
void imguiIndent()
|
||||
{
|
||||
s_state.widgetX += INDENT_SIZE;
|
||||
s_state.widgetW -= INDENT_SIZE;
|
||||
}
|
||||
|
||||
void imguiUnindent()
|
||||
{
|
||||
s_state.widgetX -= INDENT_SIZE;
|
||||
s_state.widgetW += INDENT_SIZE;
|
||||
}
|
||||
|
||||
void imguiSeparator()
|
||||
{
|
||||
s_state.widgetY -= DEFAULT_SPACING * 3;
|
||||
}
|
||||
|
||||
void imguiSeparatorLine()
|
||||
{
|
||||
int x = s_state.widgetX;
|
||||
int y = s_state.widgetY - DEFAULT_SPACING * 2;
|
||||
int w = s_state.widgetW;
|
||||
int h = 1;
|
||||
s_state.widgetY -= DEFAULT_SPACING * 4;
|
||||
|
||||
AddGfxCmdRect((float)x, (float)y, (float)w, (float)h, SetRGBA(255, 255, 255, 32));
|
||||
}
|
||||
51
external/Box2D-2.3.1/Box2D/Testbed/Framework/imgui.h
vendored
Normal file
51
external/Box2D-2.3.1/Box2D/Testbed/Framework/imgui.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Source altered and distributed from https://github.com/AdrienHerubel/imgui
|
||||
|
||||
#ifndef IMGUI_H
|
||||
#define IMGUI_H
|
||||
|
||||
enum imguiMouseButton
|
||||
{
|
||||
IMGUI_MBUT_LEFT = 0x01,
|
||||
IMGUI_MBUT_RIGHT = 0x02,
|
||||
};
|
||||
|
||||
void imguiBeginFrame(int mx, int my, unsigned char mbut, int scroll);
|
||||
void imguiEndFrame();
|
||||
|
||||
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll);
|
||||
void imguiEndScrollArea();
|
||||
|
||||
void imguiIndent();
|
||||
void imguiUnindent();
|
||||
void imguiSeparator();
|
||||
void imguiSeparatorLine();
|
||||
|
||||
bool imguiButton(const char* text, bool enabled);
|
||||
bool imguiItem(const char* text, bool enabled);
|
||||
bool imguiCheck(const char* text, bool checked, bool enabled);
|
||||
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled);
|
||||
void imguiLabel(const char* text);
|
||||
void imguiValue(const char* text);
|
||||
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled);
|
||||
bool imguiSlider(const char* text, int* val, int vmin, int vmax, int vinc, bool enabled);
|
||||
|
||||
#endif // IMGUI_H
|
||||
2066
external/Box2D-2.3.1/Box2D/Testbed/Framework/stb_truetype.h
vendored
Normal file
2066
external/Box2D-2.3.1/Box2D/Testbed/Framework/stb_truetype.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
68
external/Box2D-2.3.1/Box2D/Testbed/Tests/AddPair.h
vendored
Normal file
68
external/Box2D-2.3.1/Box2D/Testbed/Tests/AddPair.h
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2012 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 AddPair_H
|
||||
#define AddPair_H
|
||||
|
||||
class AddPair : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
AddPair()
|
||||
{
|
||||
m_world->SetGravity(b2Vec2(0.0f,0.0f));
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_p.SetZero();
|
||||
shape.m_radius = 0.1f;
|
||||
|
||||
float minX = -6.0f;
|
||||
float maxX = 0.0f;
|
||||
float minY = 4.0f;
|
||||
float maxY = 6.0f;
|
||||
|
||||
for (int32 i = 0; i < 400; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = b2Vec2(RandomFloat(minX,maxX),RandomFloat(minY,maxY));
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.5f, 1.5f);
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-40.0f,5.0f);
|
||||
bd.bullet = true;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
body->SetLinearVelocity(b2Vec2(150.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new AddPair;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
180
external/Box2D-2.3.1/Box2D/Testbed/Tests/ApplyForce.h
vendored
Normal file
180
external/Box2D-2.3.1/Box2D/Testbed/Tests/ApplyForce.h
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 APPLY_FORCE_H
|
||||
#define APPLY_FORCE_H
|
||||
|
||||
class ApplyForce : public Test
|
||||
{
|
||||
public:
|
||||
ApplyForce()
|
||||
{
|
||||
m_world->SetGravity(b2Vec2(0.0f, 0.0f));
|
||||
|
||||
const float32 k_restitution = 0.4f;
|
||||
|
||||
b2Body* ground;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(0.0f, 20.0f);
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
|
||||
b2FixtureDef sd;
|
||||
sd.shape = &shape;
|
||||
sd.density = 0.0f;
|
||||
sd.restitution = k_restitution;
|
||||
|
||||
// Left vertical
|
||||
shape.Set(b2Vec2(-20.0f, -20.0f), b2Vec2(-20.0f, 20.0f));
|
||||
ground->CreateFixture(&sd);
|
||||
|
||||
// Right vertical
|
||||
shape.Set(b2Vec2(20.0f, -20.0f), b2Vec2(20.0f, 20.0f));
|
||||
ground->CreateFixture(&sd);
|
||||
|
||||
// Top horizontal
|
||||
shape.Set(b2Vec2(-20.0f, 20.0f), b2Vec2(20.0f, 20.0f));
|
||||
ground->CreateFixture(&sd);
|
||||
|
||||
// Bottom horizontal
|
||||
shape.Set(b2Vec2(-20.0f, -20.0f), b2Vec2(20.0f, -20.0f));
|
||||
ground->CreateFixture(&sd);
|
||||
}
|
||||
|
||||
{
|
||||
b2Transform xf1;
|
||||
xf1.q.Set(0.3524f * b2_pi);
|
||||
xf1.p = xf1.q.GetXAxis();
|
||||
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0] = b2Mul(xf1, b2Vec2(-1.0f, 0.0f));
|
||||
vertices[1] = b2Mul(xf1, b2Vec2(1.0f, 0.0f));
|
||||
vertices[2] = b2Mul(xf1, b2Vec2(0.0f, 0.5f));
|
||||
|
||||
b2PolygonShape poly1;
|
||||
poly1.Set(vertices, 3);
|
||||
|
||||
b2FixtureDef sd1;
|
||||
sd1.shape = &poly1;
|
||||
sd1.density = 4.0f;
|
||||
|
||||
b2Transform xf2;
|
||||
xf2.q.Set(-0.3524f * b2_pi);
|
||||
xf2.p = -xf2.q.GetXAxis();
|
||||
|
||||
vertices[0] = b2Mul(xf2, b2Vec2(-1.0f, 0.0f));
|
||||
vertices[1] = b2Mul(xf2, b2Vec2(1.0f, 0.0f));
|
||||
vertices[2] = b2Mul(xf2, b2Vec2(0.0f, 0.5f));
|
||||
|
||||
b2PolygonShape poly2;
|
||||
poly2.Set(vertices, 3);
|
||||
|
||||
b2FixtureDef sd2;
|
||||
sd2.shape = &poly2;
|
||||
sd2.density = 2.0f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.angularDamping = 2.0f;
|
||||
bd.linearDamping = 0.5f;
|
||||
|
||||
bd.position.Set(0.0f, 2.0);
|
||||
bd.angle = b2_pi;
|
||||
bd.allowSleep = false;
|
||||
m_body = m_world->CreateBody(&bd);
|
||||
m_body->CreateFixture(&sd1);
|
||||
m_body->CreateFixture(&sd2);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.3f;
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
bd.position.Set(0.0f, 5.0f + 1.54f * i);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
float32 gravity = 10.0f;
|
||||
float32 I = body->GetInertia();
|
||||
float32 mass = body->GetMass();
|
||||
|
||||
// For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m)
|
||||
float32 radius = b2Sqrt(2.0f * I / mass);
|
||||
|
||||
b2FrictionJointDef jd;
|
||||
jd.localAnchorA.SetZero();
|
||||
jd.localAnchorB.SetZero();
|
||||
jd.bodyA = ground;
|
||||
jd.bodyB = body;
|
||||
jd.collideConnected = true;
|
||||
jd.maxForce = mass * gravity;
|
||||
jd.maxTorque = mass * radius * gravity;
|
||||
|
||||
m_world->CreateJoint(&jd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_W:
|
||||
{
|
||||
b2Vec2 f = m_body->GetWorldVector(b2Vec2(0.0f, -200.0f));
|
||||
b2Vec2 p = m_body->GetWorldPoint(b2Vec2(0.0f, 2.0f));
|
||||
m_body->ApplyForce(f, p, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_A:
|
||||
{
|
||||
m_body->ApplyTorque(50.0f, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
{
|
||||
m_body->ApplyTorque(-50.0f, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new ApplyForce;
|
||||
}
|
||||
|
||||
b2Body* m_body;
|
||||
};
|
||||
|
||||
#endif
|
||||
103
external/Box2D-2.3.1/Box2D/Testbed/Tests/BasicSliderCrank.h
vendored
Normal file
103
external/Box2D-2.3.1/Box2D/Testbed/Tests/BasicSliderCrank.h
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 BASIC_SLIDER_CRANK_H
|
||||
#define BASIC_SLIDER_CRANK_H
|
||||
|
||||
// A basic slider crank created for GDC tutorial: Understanding Constraints
|
||||
class BasicSliderCrank : public Test
|
||||
{
|
||||
public:
|
||||
BasicSliderCrank()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(0.0f, 17.0f);
|
||||
ground = m_world->CreateBody(&bd);
|
||||
}
|
||||
|
||||
{
|
||||
b2Body* prevBody = ground;
|
||||
|
||||
// Define crank.
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(4.0f, 1.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-8.0f, 20.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(prevBody, body, b2Vec2(-12.0f, 20.0f));
|
||||
m_world->CreateJoint(&rjd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
// Define connecting rod
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(8.0f, 1.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(4.0f, 20.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(prevBody, body, b2Vec2(-4.0f, 20.0f));
|
||||
m_world->CreateJoint(&rjd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
// Define piston
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(3.0f, 3.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.fixedRotation = true;
|
||||
bd.position.Set(12.0f, 20.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(prevBody, body, b2Vec2(12.0f, 20.0f));
|
||||
m_world->CreateJoint(&rjd);
|
||||
|
||||
b2PrismaticJointDef pjd;
|
||||
pjd.Initialize(ground, body, b2Vec2(12.0f, 17.0f), b2Vec2(1.0f, 0.0f));
|
||||
m_world->CreateJoint(&pjd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new BasicSliderCrank;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
159
external/Box2D-2.3.1/Box2D/Testbed/Tests/BodyTypes.h
vendored
Normal file
159
external/Box2D-2.3.1/Box2D/Testbed/Tests/BodyTypes.h
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 BODY_TYPES_H
|
||||
#define BODY_TYPES_H
|
||||
|
||||
class BodyTypes : public Test
|
||||
{
|
||||
public:
|
||||
BodyTypes()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
|
||||
ground->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Define attachment
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 3.0f);
|
||||
m_attachment = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 2.0f);
|
||||
m_attachment->CreateFixture(&shape, 2.0f);
|
||||
}
|
||||
|
||||
// Define platform
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-4.0f, 5.0f);
|
||||
m_platform = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 4.0f, b2Vec2(4.0f, 0.0f), 0.5f * b2_pi);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.friction = 0.6f;
|
||||
fd.density = 2.0f;
|
||||
m_platform->CreateFixture(&fd);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(m_attachment, m_platform, b2Vec2(0.0f, 5.0f));
|
||||
rjd.maxMotorTorque = 50.0f;
|
||||
rjd.enableMotor = true;
|
||||
m_world->CreateJoint(&rjd);
|
||||
|
||||
b2PrismaticJointDef pjd;
|
||||
pjd.Initialize(ground, m_platform, b2Vec2(0.0f, 5.0f), b2Vec2(1.0f, 0.0f));
|
||||
|
||||
pjd.maxMotorForce = 1000.0f;
|
||||
pjd.enableMotor = true;
|
||||
pjd.lowerTranslation = -10.0f;
|
||||
pjd.upperTranslation = 10.0f;
|
||||
pjd.enableLimit = true;
|
||||
|
||||
m_world->CreateJoint(&pjd);
|
||||
|
||||
m_speed = 3.0f;
|
||||
}
|
||||
|
||||
// Create a payload
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 8.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.75f, 0.75f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.friction = 0.6f;
|
||||
fd.density = 2.0f;
|
||||
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_D:
|
||||
m_platform->SetType(b2_dynamicBody);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
m_platform->SetType(b2_staticBody);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_K:
|
||||
m_platform->SetType(b2_kinematicBody);
|
||||
m_platform->SetLinearVelocity(b2Vec2(-m_speed, 0.0f));
|
||||
m_platform->SetAngularVelocity(0.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
// Drive the kinematic body.
|
||||
if (m_platform->GetType() == b2_kinematicBody)
|
||||
{
|
||||
b2Vec2 p = m_platform->GetTransform().p;
|
||||
b2Vec2 v = m_platform->GetLinearVelocity();
|
||||
|
||||
if ((p.x < -10.0f && v.x < 0.0f) ||
|
||||
(p.x > 10.0f && v.x > 0.0f))
|
||||
{
|
||||
v.x = -v.x;
|
||||
m_platform->SetLinearVelocity(v);
|
||||
}
|
||||
}
|
||||
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: (d) dynamic, (s) static, (k) kinematic");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new BodyTypes;
|
||||
}
|
||||
|
||||
b2Body* m_attachment;
|
||||
b2Body* m_platform;
|
||||
float32 m_speed;
|
||||
};
|
||||
|
||||
#endif
|
||||
155
external/Box2D-2.3.1/Box2D/Testbed/Tests/Breakable.h
vendored
Normal file
155
external/Box2D-2.3.1/Box2D/Testbed/Tests/Breakable.h
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 BREAKABLE_TEST_H
|
||||
#define BREAKABLE_TEST_H
|
||||
|
||||
// This is used to test sensor shapes.
|
||||
class Breakable : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_count = 7
|
||||
};
|
||||
|
||||
Breakable()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Breakable dynamic body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 40.0f);
|
||||
bd.angle = 0.25f * b2_pi;
|
||||
m_body1 = m_world->CreateBody(&bd);
|
||||
|
||||
m_shape1.SetAsBox(0.5f, 0.5f, b2Vec2(-0.5f, 0.0f), 0.0f);
|
||||
m_piece1 = m_body1->CreateFixture(&m_shape1, 1.0f);
|
||||
|
||||
m_shape2.SetAsBox(0.5f, 0.5f, b2Vec2(0.5f, 0.0f), 0.0f);
|
||||
m_piece2 = m_body1->CreateFixture(&m_shape2, 1.0f);
|
||||
}
|
||||
|
||||
m_break = false;
|
||||
m_broke = false;
|
||||
}
|
||||
|
||||
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
|
||||
{
|
||||
if (m_broke)
|
||||
{
|
||||
// The body already broke.
|
||||
return;
|
||||
}
|
||||
|
||||
// Should the body break?
|
||||
int32 count = contact->GetManifold()->pointCount;
|
||||
|
||||
float32 maxImpulse = 0.0f;
|
||||
for (int32 i = 0; i < count; ++i)
|
||||
{
|
||||
maxImpulse = b2Max(maxImpulse, impulse->normalImpulses[i]);
|
||||
}
|
||||
|
||||
if (maxImpulse > 40.0f)
|
||||
{
|
||||
// Flag the body for breaking.
|
||||
m_break = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Break()
|
||||
{
|
||||
// Create two bodies from one.
|
||||
b2Body* body1 = m_piece1->GetBody();
|
||||
b2Vec2 center = body1->GetWorldCenter();
|
||||
|
||||
body1->DestroyFixture(m_piece2);
|
||||
m_piece2 = NULL;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = body1->GetPosition();
|
||||
bd.angle = body1->GetAngle();
|
||||
|
||||
b2Body* body2 = m_world->CreateBody(&bd);
|
||||
m_piece2 = body2->CreateFixture(&m_shape2, 1.0f);
|
||||
|
||||
// Compute consistent velocities for new bodies based on
|
||||
// cached velocity.
|
||||
b2Vec2 center1 = body1->GetWorldCenter();
|
||||
b2Vec2 center2 = body2->GetWorldCenter();
|
||||
|
||||
b2Vec2 velocity1 = m_velocity + b2Cross(m_angularVelocity, center1 - center);
|
||||
b2Vec2 velocity2 = m_velocity + b2Cross(m_angularVelocity, center2 - center);
|
||||
|
||||
body1->SetAngularVelocity(m_angularVelocity);
|
||||
body1->SetLinearVelocity(velocity1);
|
||||
|
||||
body2->SetAngularVelocity(m_angularVelocity);
|
||||
body2->SetLinearVelocity(velocity2);
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
if (m_break)
|
||||
{
|
||||
Break();
|
||||
m_broke = true;
|
||||
m_break = false;
|
||||
}
|
||||
|
||||
// Cache velocities to improve movement on breakage.
|
||||
if (m_broke == false)
|
||||
{
|
||||
m_velocity = m_body1->GetLinearVelocity();
|
||||
m_angularVelocity = m_body1->GetAngularVelocity();
|
||||
}
|
||||
|
||||
Test::Step(settings);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Breakable;
|
||||
}
|
||||
|
||||
b2Body* m_body1;
|
||||
b2Vec2 m_velocity;
|
||||
float32 m_angularVelocity;
|
||||
b2PolygonShape m_shape1;
|
||||
b2PolygonShape m_shape2;
|
||||
b2Fixture* m_piece1;
|
||||
b2Fixture* m_piece2;
|
||||
|
||||
bool m_broke;
|
||||
bool m_break;
|
||||
};
|
||||
|
||||
#endif
|
||||
125
external/Box2D-2.3.1/Box2D/Testbed/Tests/Bridge.h
vendored
Normal file
125
external/Box2D-2.3.1/Box2D/Testbed/Tests/Bridge.h
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 BRIDGE_H
|
||||
#define BRIDGE_H
|
||||
|
||||
class Bridge : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_count = 30
|
||||
};
|
||||
|
||||
Bridge()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
fd.friction = 0.2f;
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-14.5f + 1.0f * i, 5.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(-15.0f + 1.0f * i, 5.0f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
if (i == (e_count >> 1))
|
||||
{
|
||||
m_middle = body;
|
||||
}
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
b2Vec2 anchor(-15.0f + 1.0f * e_count, 5.0f);
|
||||
jd.Initialize(prevBody, ground, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < 2; ++i)
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.5f, 0.0f);
|
||||
vertices[1].Set(0.5f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.Set(vertices, 3);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-8.0f + 8.0f * i, 12.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < 3; ++i)
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-6.0f + 6.0f * i, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Bridge;
|
||||
}
|
||||
|
||||
b2Body* m_middle;
|
||||
};
|
||||
|
||||
#endif
|
||||
136
external/Box2D-2.3.1/Box2D/Testbed/Tests/BulletTest.h
vendored
Normal file
136
external/Box2D-2.3.1/Box2D/Testbed/Tests/BulletTest.h
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 BULLET_TEST_H
|
||||
#define BULLET_TEST_H
|
||||
|
||||
class BulletTest : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
BulletTest()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(0.0f, 0.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape edge;
|
||||
|
||||
edge.Set(b2Vec2(-10.0f, 0.0f), b2Vec2(10.0f, 0.0f));
|
||||
body->CreateFixture(&edge, 0.0f);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.2f, 1.0f, b2Vec2(0.5f, 1.0f), 0.0f);
|
||||
body->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 4.0f);
|
||||
|
||||
b2PolygonShape box;
|
||||
box.SetAsBox(2.0f, 0.1f);
|
||||
|
||||
m_body = m_world->CreateBody(&bd);
|
||||
m_body->CreateFixture(&box, 1.0f);
|
||||
|
||||
box.SetAsBox(0.25f, 0.25f);
|
||||
|
||||
//m_x = RandomFloat(-1.0f, 1.0f);
|
||||
m_x = 0.20352793f;
|
||||
bd.position.Set(m_x, 10.0f);
|
||||
bd.bullet = true;
|
||||
|
||||
m_bullet = m_world->CreateBody(&bd);
|
||||
m_bullet->CreateFixture(&box, 100.0f);
|
||||
|
||||
m_bullet->SetLinearVelocity(b2Vec2(0.0f, -50.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void Launch()
|
||||
{
|
||||
m_body->SetTransform(b2Vec2(0.0f, 4.0f), 0.0f);
|
||||
m_body->SetLinearVelocity(b2Vec2_zero);
|
||||
m_body->SetAngularVelocity(0.0f);
|
||||
|
||||
m_x = RandomFloat(-1.0f, 1.0f);
|
||||
m_bullet->SetTransform(b2Vec2(m_x, 10.0f), 0.0f);
|
||||
m_bullet->SetLinearVelocity(b2Vec2(0.0f, -50.0f));
|
||||
m_bullet->SetAngularVelocity(0.0f);
|
||||
|
||||
extern int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
|
||||
extern int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters;
|
||||
extern int32 b2_toiRootIters, b2_toiMaxRootIters;
|
||||
|
||||
b2_gjkCalls = 0;
|
||||
b2_gjkIters = 0;
|
||||
b2_gjkMaxIters = 0;
|
||||
|
||||
b2_toiCalls = 0;
|
||||
b2_toiIters = 0;
|
||||
b2_toiMaxIters = 0;
|
||||
b2_toiRootIters = 0;
|
||||
b2_toiMaxRootIters = 0;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
extern int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
|
||||
extern int32 b2_toiCalls, b2_toiIters;
|
||||
extern int32 b2_toiRootIters, b2_toiMaxRootIters;
|
||||
|
||||
if (b2_gjkCalls > 0)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "gjk calls = %d, ave gjk iters = %3.1f, max gjk iters = %d",
|
||||
b2_gjkCalls, b2_gjkIters / float32(b2_gjkCalls), b2_gjkMaxIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
if (b2_toiCalls > 0)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "toi calls = %d, ave toi iters = %3.1f, max toi iters = %d",
|
||||
b2_toiCalls, b2_toiIters / float32(b2_toiCalls), b2_toiMaxRootIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "ave toi root iters = %3.1f, max toi root iters = %d",
|
||||
b2_toiRootIters / float32(b2_toiCalls), b2_toiMaxRootIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
if (m_stepCount % 60 == 0)
|
||||
{
|
||||
Launch();
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new BulletTest;
|
||||
}
|
||||
|
||||
b2Body* m_body;
|
||||
b2Body* m_bullet;
|
||||
float32 m_x;
|
||||
};
|
||||
|
||||
#endif
|
||||
211
external/Box2D-2.3.1/Box2D/Testbed/Tests/Cantilever.h
vendored
Normal file
211
external/Box2D-2.3.1/Box2D/Testbed/Tests/Cantilever.h
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CANTILEVER_H
|
||||
#define CANTILEVER_H
|
||||
|
||||
// It is difficult to make a cantilever made of links completely rigid with weld joints.
|
||||
// You will have to use a high number of iterations to make them stiff.
|
||||
// So why not go ahead and use soft weld joints? They behave like a revolute
|
||||
// joint with a rotational spring.
|
||||
class Cantilever : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_count = 8
|
||||
};
|
||||
|
||||
Cantilever()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
|
||||
b2WeldJointDef jd;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-14.5f + 1.0f * i, 5.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(-15.0f + 1.0f * i, 5.0f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.0f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
|
||||
b2WeldJointDef jd;
|
||||
jd.frequencyHz = 5.0f;
|
||||
jd.dampingRatio = 0.7f;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < 3; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-14.0f + 2.0f * i, 15.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(-15.0f + 2.0f * i, 15.0f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
|
||||
b2WeldJointDef jd;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-4.5f + 1.0f * i, 5.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
b2Vec2 anchor(-5.0f + 1.0f * i, 5.0f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
|
||||
b2WeldJointDef jd;
|
||||
jd.frequencyHz = 8.0f;
|
||||
jd.dampingRatio = 0.7f;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(5.5f + 1.0f * i, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
b2Vec2 anchor(5.0f + 1.0f * i, 10.0f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < 2; ++i)
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.5f, 0.0f);
|
||||
vertices[1].Set(0.5f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.Set(vertices, 3);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-8.0f + 8.0f * i, 12.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < 2; ++i)
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-6.0f + 6.0f * i, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Cantilever;
|
||||
}
|
||||
|
||||
b2Body* m_middle;
|
||||
};
|
||||
|
||||
#endif
|
||||
286
external/Box2D-2.3.1/Box2D/Testbed/Tests/Car.h
vendored
Normal file
286
external/Box2D-2.3.1/Box2D/Testbed/Tests/Car.h
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CAR_H
|
||||
#define CAR_H
|
||||
|
||||
// This is a fun demo that shows off the wheel joint
|
||||
class Car : public Test
|
||||
{
|
||||
public:
|
||||
Car()
|
||||
{
|
||||
m_hz = 4.0f;
|
||||
m_zeta = 0.7f;
|
||||
m_speed = 50.0f;
|
||||
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 0.0f;
|
||||
fd.friction = 0.6f;
|
||||
|
||||
shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
|
||||
ground->CreateFixture(&fd);
|
||||
|
||||
float32 hs[10] = {0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f};
|
||||
|
||||
float32 x = 20.0f, y1 = 0.0f, dx = 5.0f;
|
||||
|
||||
for (int32 i = 0; i < 10; ++i)
|
||||
{
|
||||
float32 y2 = hs[i];
|
||||
shape.Set(b2Vec2(x, y1), b2Vec2(x + dx, y2));
|
||||
ground->CreateFixture(&fd);
|
||||
y1 = y2;
|
||||
x += dx;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < 10; ++i)
|
||||
{
|
||||
float32 y2 = hs[i];
|
||||
shape.Set(b2Vec2(x, y1), b2Vec2(x + dx, y2));
|
||||
ground->CreateFixture(&fd);
|
||||
y1 = y2;
|
||||
x += dx;
|
||||
}
|
||||
|
||||
shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 40.0f, 0.0f));
|
||||
ground->CreateFixture(&fd);
|
||||
|
||||
x += 80.0f;
|
||||
shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 40.0f, 0.0f));
|
||||
ground->CreateFixture(&fd);
|
||||
|
||||
x += 40.0f;
|
||||
shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 10.0f, 5.0f));
|
||||
ground->CreateFixture(&fd);
|
||||
|
||||
x += 20.0f;
|
||||
shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 40.0f, 0.0f));
|
||||
ground->CreateFixture(&fd);
|
||||
|
||||
x += 40.0f;
|
||||
shape.Set(b2Vec2(x, 0.0f), b2Vec2(x, 20.0f));
|
||||
ground->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Teeter
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(140.0f, 1.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape box;
|
||||
box.SetAsBox(10.0f, 0.25f);
|
||||
body->CreateFixture(&box, 1.0f);
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
jd.Initialize(ground, body, body->GetPosition());
|
||||
jd.lowerAngle = -8.0f * b2_pi / 180.0f;
|
||||
jd.upperAngle = 8.0f * b2_pi / 180.0f;
|
||||
jd.enableLimit = true;
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
body->ApplyAngularImpulse(100.0f, true);
|
||||
}
|
||||
|
||||
// Bridge
|
||||
{
|
||||
int32 N = 20;
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.0f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.6f;
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < N; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(161.0f + 2.0f * i, -0.125f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(160.0f + 2.0f * i, -0.125f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
b2Vec2 anchor(160.0f + 2.0f * N, -0.125f);
|
||||
jd.Initialize(prevBody, ground, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
// Boxes
|
||||
{
|
||||
b2PolygonShape box;
|
||||
box.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
b2Body* body = NULL;
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
bd.position.Set(230.0f, 0.5f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&box, 0.5f);
|
||||
|
||||
bd.position.Set(230.0f, 1.5f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&box, 0.5f);
|
||||
|
||||
bd.position.Set(230.0f, 2.5f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&box, 0.5f);
|
||||
|
||||
bd.position.Set(230.0f, 3.5f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&box, 0.5f);
|
||||
|
||||
bd.position.Set(230.0f, 4.5f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&box, 0.5f);
|
||||
}
|
||||
|
||||
// Car
|
||||
{
|
||||
b2PolygonShape chassis;
|
||||
b2Vec2 vertices[8];
|
||||
vertices[0].Set(-1.5f, -0.5f);
|
||||
vertices[1].Set(1.5f, -0.5f);
|
||||
vertices[2].Set(1.5f, 0.0f);
|
||||
vertices[3].Set(0.0f, 0.9f);
|
||||
vertices[4].Set(-1.15f, 0.9f);
|
||||
vertices[5].Set(-1.5f, 0.2f);
|
||||
chassis.Set(vertices, 6);
|
||||
|
||||
b2CircleShape circle;
|
||||
circle.m_radius = 0.4f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 1.0f);
|
||||
m_car = m_world->CreateBody(&bd);
|
||||
m_car->CreateFixture(&chassis, 1.0f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &circle;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.9f;
|
||||
|
||||
bd.position.Set(-1.0f, 0.35f);
|
||||
m_wheel1 = m_world->CreateBody(&bd);
|
||||
m_wheel1->CreateFixture(&fd);
|
||||
|
||||
bd.position.Set(1.0f, 0.4f);
|
||||
m_wheel2 = m_world->CreateBody(&bd);
|
||||
m_wheel2->CreateFixture(&fd);
|
||||
|
||||
b2WheelJointDef jd;
|
||||
b2Vec2 axis(0.0f, 1.0f);
|
||||
|
||||
jd.Initialize(m_car, m_wheel1, m_wheel1->GetPosition(), axis);
|
||||
jd.motorSpeed = 0.0f;
|
||||
jd.maxMotorTorque = 20.0f;
|
||||
jd.enableMotor = true;
|
||||
jd.frequencyHz = m_hz;
|
||||
jd.dampingRatio = m_zeta;
|
||||
m_spring1 = (b2WheelJoint*)m_world->CreateJoint(&jd);
|
||||
|
||||
jd.Initialize(m_car, m_wheel2, m_wheel2->GetPosition(), axis);
|
||||
jd.motorSpeed = 0.0f;
|
||||
jd.maxMotorTorque = 10.0f;
|
||||
jd.enableMotor = false;
|
||||
jd.frequencyHz = m_hz;
|
||||
jd.dampingRatio = m_zeta;
|
||||
m_spring2 = (b2WheelJoint*)m_world->CreateJoint(&jd);
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_spring1->SetMotorSpeed(m_speed);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
m_spring1->SetMotorSpeed(0.0f);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
m_spring1->SetMotorSpeed(-m_speed);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_Q:
|
||||
m_hz = b2Max(0.0f, m_hz - 1.0f);
|
||||
m_spring1->SetSpringFrequencyHz(m_hz);
|
||||
m_spring2->SetSpringFrequencyHz(m_hz);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_E:
|
||||
m_hz += 1.0f;
|
||||
m_spring1->SetSpringFrequencyHz(m_hz);
|
||||
m_spring2->SetSpringFrequencyHz(m_hz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: left = a, brake = s, right = d, hz down = q, hz up = e");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "frequency = %g hz, damping ratio = %g", m_hz, m_zeta);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
g_camera.m_center.x = m_car->GetPosition().x;
|
||||
Test::Step(settings);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Car;
|
||||
}
|
||||
|
||||
b2Body* m_car;
|
||||
b2Body* m_wheel1;
|
||||
b2Body* m_wheel2;
|
||||
|
||||
float32 m_hz;
|
||||
float32 m_zeta;
|
||||
float32 m_speed;
|
||||
b2WheelJoint* m_spring1;
|
||||
b2WheelJoint* m_spring2;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
external/Box2D-2.3.1/Box2D/Testbed/Tests/Chain.h
vendored
Normal file
74
external/Box2D-2.3.1/Box2D/Testbed/Tests/Chain.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CHAIN_H
|
||||
#define CHAIN_H
|
||||
|
||||
class Chain : public Test
|
||||
{
|
||||
public:
|
||||
Chain()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.6f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
fd.friction = 0.2f;
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
jd.collideConnected = false;
|
||||
|
||||
const float32 y = 25.0f;
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < 30; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.5f + i, y);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(float32(i), y);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Chain;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
253
external/Box2D-2.3.1/Box2D/Testbed/Tests/CharacterCollision.h
vendored
Normal file
253
external/Box2D-2.3.1/Box2D/Testbed/Tests/CharacterCollision.h
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CHARACTER_COLLISION_H
|
||||
#define CHARACTER_COLLISION_H
|
||||
|
||||
/// This is a test of typical character collision scenarios. This does not
|
||||
/// show how you should implement a character in your application.
|
||||
/// Instead this is used to test smooth collision on edge chains.
|
||||
class CharacterCollision : public Test
|
||||
{
|
||||
public:
|
||||
CharacterCollision()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Collinear edges with no adjacency information.
|
||||
// This shows the problematic case where a box shape can hit
|
||||
// an internal vertex.
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-8.0f, 1.0f), b2Vec2(-6.0f, 1.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
shape.Set(b2Vec2(-6.0f, 1.0f), b2Vec2(-4.0f, 1.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
shape.Set(b2Vec2(-4.0f, 1.0f), b2Vec2(-2.0f, 1.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Chain shape
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.angle = 0.25f * b2_pi;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2Vec2 vs[4];
|
||||
vs[0].Set(5.0f, 7.0f);
|
||||
vs[1].Set(6.0f, 8.0f);
|
||||
vs[2].Set(7.0f, 8.0f);
|
||||
vs[3].Set(8.0f, 7.0f);
|
||||
b2ChainShape shape;
|
||||
shape.CreateChain(vs, 4);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Square tiles. This shows that adjacency shapes may
|
||||
// have non-smooth collision. There is no solution
|
||||
// to this problem.
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.0f, 1.0f, b2Vec2(4.0f, 3.0f), 0.0f);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
shape.SetAsBox(1.0f, 1.0f, b2Vec2(6.0f, 3.0f), 0.0f);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
shape.SetAsBox(1.0f, 1.0f, b2Vec2(8.0f, 3.0f), 0.0f);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Square made from an edge loop. Collision should be smooth.
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2Vec2 vs[4];
|
||||
vs[0].Set(-1.0f, 3.0f);
|
||||
vs[1].Set(1.0f, 3.0f);
|
||||
vs[2].Set(1.0f, 5.0f);
|
||||
vs[3].Set(-1.0f, 5.0f);
|
||||
b2ChainShape shape;
|
||||
shape.CreateLoop(vs, 4);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Edge loop. Collision should be smooth.
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-10.0f, 4.0f);
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2Vec2 vs[10];
|
||||
vs[0].Set(0.0f, 0.0f);
|
||||
vs[1].Set(6.0f, 0.0f);
|
||||
vs[2].Set(6.0f, 2.0f);
|
||||
vs[3].Set(4.0f, 1.0f);
|
||||
vs[4].Set(2.0f, 2.0f);
|
||||
vs[5].Set(0.0f, 2.0f);
|
||||
vs[6].Set(-2.0f, 2.0f);
|
||||
vs[7].Set(-4.0f, 3.0f);
|
||||
vs[8].Set(-6.0f, 2.0f);
|
||||
vs[9].Set(-6.0f, 0.0f);
|
||||
b2ChainShape shape;
|
||||
shape.CreateLoop(vs, 10);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Square character 1
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-3.0f, 8.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.fixedRotation = true;
|
||||
bd.allowSleep = false;
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Square character 2
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-5.0f, 5.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.fixedRotation = true;
|
||||
bd.allowSleep = false;
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f, 0.25f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Hexagon character
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-5.0f, 8.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.fixedRotation = true;
|
||||
bd.allowSleep = false;
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
float32 angle = 0.0f;
|
||||
float32 delta = b2_pi / 3.0f;
|
||||
b2Vec2 vertices[6];
|
||||
for (int32 i = 0; i < 6; ++i)
|
||||
{
|
||||
vertices[i].Set(0.5f * cosf(angle), 0.5f * sinf(angle));
|
||||
angle += delta;
|
||||
}
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.Set(vertices, 6);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Circle character
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(3.0f, 5.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.fixedRotation = true;
|
||||
bd.allowSleep = false;
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Circle character
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-7.0f, 6.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.allowSleep = false;
|
||||
|
||||
m_character = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.25f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
fd.friction = 1.0f;
|
||||
m_character->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
b2Vec2 v = m_character->GetLinearVelocity();
|
||||
v.x = -5.0f;
|
||||
m_character->SetLinearVelocity(v);
|
||||
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "This tests various character collision shapes.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "Limitation: square and hexagon can snag on aligned boxes.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "Feature: edge chains have smooth collision inside and out.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CharacterCollision;
|
||||
}
|
||||
|
||||
b2Body* m_character;
|
||||
};
|
||||
|
||||
#endif
|
||||
177
external/Box2D-2.3.1/Box2D/Testbed/Tests/CollisionFiltering.h
vendored
Normal file
177
external/Box2D-2.3.1/Box2D/Testbed/Tests/CollisionFiltering.h
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 COLLISION_FILTERING_H
|
||||
#define COLLISION_FILTERING_H
|
||||
|
||||
// This is a test of collision filtering.
|
||||
// There is a triangle, a box, and a circle.
|
||||
// There are 6 shapes. 3 large and 3 small.
|
||||
// The 3 small ones always collide.
|
||||
// The 3 large ones never collide.
|
||||
// The boxes don't collide with triangles (except if both are small).
|
||||
const int16 k_smallGroup = 1;
|
||||
const int16 k_largeGroup = -1;
|
||||
|
||||
const uint16 k_defaultCategory = 0x0001;
|
||||
const uint16 k_triangleCategory = 0x0002;
|
||||
const uint16 k_boxCategory = 0x0004;
|
||||
const uint16 k_circleCategory = 0x0008;
|
||||
|
||||
const uint16 k_triangleMask = 0xFFFF;
|
||||
const uint16 k_boxMask = 0xFFFF ^ k_triangleCategory;
|
||||
const uint16 k_circleMask = 0xFFFF;
|
||||
|
||||
class CollisionFiltering : public Test
|
||||
{
|
||||
public:
|
||||
CollisionFiltering()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
|
||||
b2FixtureDef sd;
|
||||
sd.shape = &shape;
|
||||
sd.friction = 0.3f;
|
||||
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&sd);
|
||||
}
|
||||
|
||||
// Small triangle
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-1.0f, 0.0f);
|
||||
vertices[1].Set(1.0f, 0.0f);
|
||||
vertices[2].Set(0.0f, 2.0f);
|
||||
b2PolygonShape polygon;
|
||||
polygon.Set(vertices, 3);
|
||||
|
||||
b2FixtureDef triangleShapeDef;
|
||||
triangleShapeDef.shape = &polygon;
|
||||
triangleShapeDef.density = 1.0f;
|
||||
|
||||
triangleShapeDef.filter.groupIndex = k_smallGroup;
|
||||
triangleShapeDef.filter.categoryBits = k_triangleCategory;
|
||||
triangleShapeDef.filter.maskBits = k_triangleMask;
|
||||
|
||||
b2BodyDef triangleBodyDef;
|
||||
triangleBodyDef.type = b2_dynamicBody;
|
||||
triangleBodyDef.position.Set(-5.0f, 2.0f);
|
||||
|
||||
b2Body* body1 = m_world->CreateBody(&triangleBodyDef);
|
||||
body1->CreateFixture(&triangleShapeDef);
|
||||
|
||||
// Large triangle (recycle definitions)
|
||||
vertices[0] *= 2.0f;
|
||||
vertices[1] *= 2.0f;
|
||||
vertices[2] *= 2.0f;
|
||||
polygon.Set(vertices, 3);
|
||||
triangleShapeDef.filter.groupIndex = k_largeGroup;
|
||||
triangleBodyDef.position.Set(-5.0f, 6.0f);
|
||||
triangleBodyDef.fixedRotation = true; // look at me!
|
||||
|
||||
b2Body* body2 = m_world->CreateBody(&triangleBodyDef);
|
||||
body2->CreateFixture(&triangleShapeDef);
|
||||
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-5.0f, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape p;
|
||||
p.SetAsBox(0.5f, 1.0f);
|
||||
body->CreateFixture(&p, 1.0f);
|
||||
|
||||
b2PrismaticJointDef jd;
|
||||
jd.bodyA = body2;
|
||||
jd.bodyB = body;
|
||||
jd.enableLimit = true;
|
||||
jd.localAnchorA.Set(0.0f, 4.0f);
|
||||
jd.localAnchorB.SetZero();
|
||||
jd.localAxisA.Set(0.0f, 1.0f);
|
||||
jd.lowerTranslation = -1.0f;
|
||||
jd.upperTranslation = 1.0f;
|
||||
|
||||
m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
// Small box
|
||||
polygon.SetAsBox(1.0f, 0.5f);
|
||||
b2FixtureDef boxShapeDef;
|
||||
boxShapeDef.shape = &polygon;
|
||||
boxShapeDef.density = 1.0f;
|
||||
boxShapeDef.restitution = 0.1f;
|
||||
|
||||
boxShapeDef.filter.groupIndex = k_smallGroup;
|
||||
boxShapeDef.filter.categoryBits = k_boxCategory;
|
||||
boxShapeDef.filter.maskBits = k_boxMask;
|
||||
|
||||
b2BodyDef boxBodyDef;
|
||||
boxBodyDef.type = b2_dynamicBody;
|
||||
boxBodyDef.position.Set(0.0f, 2.0f);
|
||||
|
||||
b2Body* body3 = m_world->CreateBody(&boxBodyDef);
|
||||
body3->CreateFixture(&boxShapeDef);
|
||||
|
||||
// Large box (recycle definitions)
|
||||
polygon.SetAsBox(2.0f, 1.0f);
|
||||
boxShapeDef.filter.groupIndex = k_largeGroup;
|
||||
boxBodyDef.position.Set(0.0f, 6.0f);
|
||||
|
||||
b2Body* body4 = m_world->CreateBody(&boxBodyDef);
|
||||
body4->CreateFixture(&boxShapeDef);
|
||||
|
||||
// Small circle
|
||||
b2CircleShape circle;
|
||||
circle.m_radius = 1.0f;
|
||||
|
||||
b2FixtureDef circleShapeDef;
|
||||
circleShapeDef.shape = &circle;
|
||||
circleShapeDef.density = 1.0f;
|
||||
|
||||
circleShapeDef.filter.groupIndex = k_smallGroup;
|
||||
circleShapeDef.filter.categoryBits = k_circleCategory;
|
||||
circleShapeDef.filter.maskBits = k_circleMask;
|
||||
|
||||
b2BodyDef circleBodyDef;
|
||||
circleBodyDef.type = b2_dynamicBody;
|
||||
circleBodyDef.position.Set(5.0f, 2.0f);
|
||||
|
||||
b2Body* body5 = m_world->CreateBody(&circleBodyDef);
|
||||
body5->CreateFixture(&circleShapeDef);
|
||||
|
||||
// Large circle
|
||||
circle.m_radius *= 2.0f;
|
||||
circleShapeDef.filter.groupIndex = k_largeGroup;
|
||||
circleBodyDef.position.Set(5.0f, 6.0f);
|
||||
|
||||
b2Body* body6 = m_world->CreateBody(&circleBodyDef);
|
||||
body6->CreateFixture(&circleShapeDef);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CollisionFiltering;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
188
external/Box2D-2.3.1/Box2D/Testbed/Tests/CollisionProcessing.h
vendored
Normal file
188
external/Box2D-2.3.1/Box2D/Testbed/Tests/CollisionProcessing.h
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 COLLISION_PROCESSING_H
|
||||
#define COLLISION_PROCESSING_H
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// This test shows collision processing and tests
|
||||
// deferred body destruction.
|
||||
class CollisionProcessing : public Test
|
||||
{
|
||||
public:
|
||||
CollisionProcessing()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-50.0f, 0.0f), b2Vec2(50.0f, 0.0f));
|
||||
|
||||
b2FixtureDef sd;
|
||||
sd.shape = &shape;;
|
||||
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&sd);
|
||||
}
|
||||
|
||||
float32 xLo = -5.0f, xHi = 5.0f;
|
||||
float32 yLo = 2.0f, yHi = 35.0f;
|
||||
|
||||
// Small triangle
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-1.0f, 0.0f);
|
||||
vertices[1].Set(1.0f, 0.0f);
|
||||
vertices[2].Set(0.0f, 2.0f);
|
||||
|
||||
b2PolygonShape polygon;
|
||||
polygon.Set(vertices, 3);
|
||||
|
||||
b2FixtureDef triangleShapeDef;
|
||||
triangleShapeDef.shape = &polygon;
|
||||
triangleShapeDef.density = 1.0f;
|
||||
|
||||
b2BodyDef triangleBodyDef;
|
||||
triangleBodyDef.type = b2_dynamicBody;
|
||||
triangleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
|
||||
|
||||
b2Body* body1 = m_world->CreateBody(&triangleBodyDef);
|
||||
body1->CreateFixture(&triangleShapeDef);
|
||||
|
||||
// Large triangle (recycle definitions)
|
||||
vertices[0] *= 2.0f;
|
||||
vertices[1] *= 2.0f;
|
||||
vertices[2] *= 2.0f;
|
||||
polygon.Set(vertices, 3);
|
||||
|
||||
triangleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
|
||||
|
||||
b2Body* body2 = m_world->CreateBody(&triangleBodyDef);
|
||||
body2->CreateFixture(&triangleShapeDef);
|
||||
|
||||
// Small box
|
||||
polygon.SetAsBox(1.0f, 0.5f);
|
||||
|
||||
b2FixtureDef boxShapeDef;
|
||||
boxShapeDef.shape = &polygon;
|
||||
boxShapeDef.density = 1.0f;
|
||||
|
||||
b2BodyDef boxBodyDef;
|
||||
boxBodyDef.type = b2_dynamicBody;
|
||||
boxBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
|
||||
|
||||
b2Body* body3 = m_world->CreateBody(&boxBodyDef);
|
||||
body3->CreateFixture(&boxShapeDef);
|
||||
|
||||
// Large box (recycle definitions)
|
||||
polygon.SetAsBox(2.0f, 1.0f);
|
||||
boxBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
|
||||
|
||||
b2Body* body4 = m_world->CreateBody(&boxBodyDef);
|
||||
body4->CreateFixture(&boxShapeDef);
|
||||
|
||||
// Small circle
|
||||
b2CircleShape circle;
|
||||
circle.m_radius = 1.0f;
|
||||
|
||||
b2FixtureDef circleShapeDef;
|
||||
circleShapeDef.shape = &circle;
|
||||
circleShapeDef.density = 1.0f;
|
||||
|
||||
b2BodyDef circleBodyDef;
|
||||
circleBodyDef.type = b2_dynamicBody;
|
||||
circleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
|
||||
|
||||
b2Body* body5 = m_world->CreateBody(&circleBodyDef);
|
||||
body5->CreateFixture(&circleShapeDef);
|
||||
|
||||
// Large circle
|
||||
circle.m_radius *= 2.0f;
|
||||
circleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
|
||||
|
||||
b2Body* body6 = m_world->CreateBody(&circleBodyDef);
|
||||
body6->CreateFixture(&circleShapeDef);
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
// We are going to destroy some bodies according to contact
|
||||
// points. We must buffer the bodies that should be destroyed
|
||||
// because they may belong to multiple contact points.
|
||||
const int32 k_maxNuke = 6;
|
||||
b2Body* nuke[k_maxNuke];
|
||||
int32 nukeCount = 0;
|
||||
|
||||
// Traverse the contact results. Destroy bodies that
|
||||
// are touching heavier bodies.
|
||||
for (int32 i = 0; i < m_pointCount; ++i)
|
||||
{
|
||||
ContactPoint* point = m_points + i;
|
||||
|
||||
b2Body* body1 = point->fixtureA->GetBody();
|
||||
b2Body* body2 = point->fixtureB->GetBody();
|
||||
float32 mass1 = body1->GetMass();
|
||||
float32 mass2 = body2->GetMass();
|
||||
|
||||
if (mass1 > 0.0f && mass2 > 0.0f)
|
||||
{
|
||||
if (mass2 > mass1)
|
||||
{
|
||||
nuke[nukeCount++] = body1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nuke[nukeCount++] = body2;
|
||||
}
|
||||
|
||||
if (nukeCount == k_maxNuke)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the nuke array to group duplicates.
|
||||
std::sort(nuke, nuke + nukeCount);
|
||||
|
||||
// Destroy the bodies, skipping duplicates.
|
||||
int32 i = 0;
|
||||
while (i < nukeCount)
|
||||
{
|
||||
b2Body* b = nuke[i++];
|
||||
while (i < nukeCount && nuke[i] == b)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
if (b != m_bomb)
|
||||
{
|
||||
m_world->DestroyBody(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CollisionProcessing;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
143
external/Box2D-2.3.1/Box2D/Testbed/Tests/CompoundShapes.h
vendored
Normal file
143
external/Box2D-2.3.1/Box2D/Testbed/Tests/CompoundShapes.h
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 COMPOUND_SHAPES_H
|
||||
#define COMPOUND_SHAPES_H
|
||||
|
||||
// TODO_ERIN test joints on compounds.
|
||||
class CompoundShapes : public Test
|
||||
{
|
||||
public:
|
||||
CompoundShapes()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(0.0f, 0.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(50.0f, 0.0f), b2Vec2(-50.0f, 0.0f));
|
||||
|
||||
body->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape circle1;
|
||||
circle1.m_radius = 0.5f;
|
||||
circle1.m_p.Set(-0.5f, 0.5f);
|
||||
|
||||
b2CircleShape circle2;
|
||||
circle2.m_radius = 0.5f;
|
||||
circle2.m_p.Set(0.5f, 0.5f);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
float32 x = RandomFloat(-0.1f, 0.1f);
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(x + 5.0f, 1.05f + 2.5f * i);
|
||||
bd.angle = RandomFloat(-b2_pi, b2_pi);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&circle1, 2.0f);
|
||||
body->CreateFixture(&circle2, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape polygon1;
|
||||
polygon1.SetAsBox(0.25f, 0.5f);
|
||||
|
||||
b2PolygonShape polygon2;
|
||||
polygon2.SetAsBox(0.25f, 0.5f, b2Vec2(0.0f, -0.5f), 0.5f * b2_pi);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
float32 x = RandomFloat(-0.1f, 0.1f);
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(x - 5.0f, 1.05f + 2.5f * i);
|
||||
bd.angle = RandomFloat(-b2_pi, b2_pi);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&polygon1, 2.0f);
|
||||
body->CreateFixture(&polygon2, 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2Transform xf1;
|
||||
xf1.q.Set(0.3524f * b2_pi);
|
||||
xf1.p = xf1.q.GetXAxis();
|
||||
|
||||
b2Vec2 vertices[3];
|
||||
|
||||
b2PolygonShape triangle1;
|
||||
vertices[0] = b2Mul(xf1, b2Vec2(-1.0f, 0.0f));
|
||||
vertices[1] = b2Mul(xf1, b2Vec2(1.0f, 0.0f));
|
||||
vertices[2] = b2Mul(xf1, b2Vec2(0.0f, 0.5f));
|
||||
triangle1.Set(vertices, 3);
|
||||
|
||||
b2Transform xf2;
|
||||
xf2.q.Set(-0.3524f * b2_pi);
|
||||
xf2.p = -xf2.q.GetXAxis();
|
||||
|
||||
b2PolygonShape triangle2;
|
||||
vertices[0] = b2Mul(xf2, b2Vec2(-1.0f, 0.0f));
|
||||
vertices[1] = b2Mul(xf2, b2Vec2(1.0f, 0.0f));
|
||||
vertices[2] = b2Mul(xf2, b2Vec2(0.0f, 0.5f));
|
||||
triangle2.Set(vertices, 3);
|
||||
|
||||
for (int32 i = 0; i < 10; ++i)
|
||||
{
|
||||
float32 x = RandomFloat(-0.1f, 0.1f);
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(x, 2.05f + 2.5f * i);
|
||||
bd.angle = 0.0f;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&triangle1, 2.0f);
|
||||
body->CreateFixture(&triangle2, 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape bottom;
|
||||
bottom.SetAsBox( 1.5f, 0.15f );
|
||||
|
||||
b2PolygonShape left;
|
||||
left.SetAsBox(0.15f, 2.7f, b2Vec2(-1.45f, 2.35f), 0.2f);
|
||||
|
||||
b2PolygonShape right;
|
||||
right.SetAsBox(0.15f, 2.7f, b2Vec2(1.45f, 2.35f), -0.2f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set( 0.0f, 2.0f );
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&bottom, 4.0f);
|
||||
body->CreateFixture(&left, 4.0f);
|
||||
body->CreateFixture(&right, 4.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CompoundShapes;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
167
external/Box2D-2.3.1/Box2D/Testbed/Tests/Confined.h
vendored
Normal file
167
external/Box2D-2.3.1/Box2D/Testbed/Tests/Confined.h
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CONFINED_H
|
||||
#define CONFINED_H
|
||||
|
||||
class Confined : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_columnCount = 0,
|
||||
e_rowCount = 0
|
||||
};
|
||||
|
||||
Confined()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
|
||||
// Floor
|
||||
shape.Set(b2Vec2(-10.0f, 0.0f), b2Vec2(10.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
// Left wall
|
||||
shape.Set(b2Vec2(-10.0f, 0.0f), b2Vec2(-10.0f, 20.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
// Right wall
|
||||
shape.Set(b2Vec2(10.0f, 0.0f), b2Vec2(10.0f, 20.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
// Roof
|
||||
shape.Set(b2Vec2(-10.0f, 20.0f), b2Vec2(10.0f, 20.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
float32 radius = 0.5f;
|
||||
b2CircleShape shape;
|
||||
shape.m_p.SetZero();
|
||||
shape.m_radius = radius;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.1f;
|
||||
|
||||
for (int32 j = 0; j < e_columnCount; ++j)
|
||||
{
|
||||
for (int i = 0; i < e_rowCount; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-10.0f + (2.1f * j + 1.0f + 0.01f * i) * radius, (2.0f * i + 1.0f) * radius);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
m_world->SetGravity(b2Vec2(0.0f, 0.0f));
|
||||
}
|
||||
|
||||
void CreateCircle()
|
||||
{
|
||||
float32 radius = 2.0f;
|
||||
b2CircleShape shape;
|
||||
shape.m_p.SetZero();
|
||||
shape.m_radius = radius;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.0f;
|
||||
|
||||
b2Vec2 p(RandomFloat(), 3.0f + RandomFloat());
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = p;
|
||||
//bd.allowSleep = false;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_C:
|
||||
CreateCircle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
bool sleeping = true;
|
||||
for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
|
||||
{
|
||||
if (b->GetType() != b2_dynamicBody)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (b->IsAwake())
|
||||
{
|
||||
sleeping = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_stepCount == 180)
|
||||
{
|
||||
m_stepCount += 0;
|
||||
}
|
||||
|
||||
//if (sleeping)
|
||||
//{
|
||||
// CreateCircle();
|
||||
//}
|
||||
|
||||
Test::Step(settings);
|
||||
|
||||
for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
|
||||
{
|
||||
if (b->GetType() != b2_dynamicBody)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
b2Vec2 p = b->GetPosition();
|
||||
if (p.x <= -10.0f || 10.0f <= p.x || p.y <= 0.0f || 20.0f <= p.y)
|
||||
{
|
||||
p.x += 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 'c' to create a circle.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Confined;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
157
external/Box2D-2.3.1/Box2D/Testbed/Tests/ContinuousTest.h
vendored
Normal file
157
external/Box2D-2.3.1/Box2D/Testbed/Tests/ContinuousTest.h
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CONTINUOUS_TEST_H
|
||||
#define CONTINUOUS_TEST_H
|
||||
|
||||
class ContinuousTest : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
ContinuousTest()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(0.0f, 0.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape edge;
|
||||
|
||||
edge.Set(b2Vec2(-10.0f, 0.0f), b2Vec2(10.0f, 0.0f));
|
||||
body->CreateFixture(&edge, 0.0f);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.2f, 1.0f, b2Vec2(0.5f, 1.0f), 0.0f);
|
||||
body->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
#if 1
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 20.0f);
|
||||
//bd.angle = 0.1f;
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(2.0f, 0.1f);
|
||||
|
||||
m_body = m_world->CreateBody(&bd);
|
||||
m_body->CreateFixture(&shape, 1.0f);
|
||||
|
||||
m_angularVelocity = RandomFloat(-50.0f, 50.0f);
|
||||
//m_angularVelocity = 46.661274f;
|
||||
m_body->SetLinearVelocity(b2Vec2(0.0f, -100.0f));
|
||||
m_body->SetAngularVelocity(m_angularVelocity);
|
||||
}
|
||||
#else
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 2.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_p.SetZero();
|
||||
shape.m_radius = 0.5f;
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
|
||||
bd.bullet = true;
|
||||
bd.position.Set(0.0f, 10.0f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
body->SetLinearVelocity(b2Vec2(0.0f, -100.0f));
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
|
||||
extern int32 b2_toiCalls, b2_toiIters;
|
||||
extern int32 b2_toiRootIters, b2_toiMaxRootIters;
|
||||
extern float32 b2_toiTime, b2_toiMaxTime;
|
||||
|
||||
b2_gjkCalls = 0; b2_gjkIters = 0; b2_gjkMaxIters = 0;
|
||||
b2_toiCalls = 0; b2_toiIters = 0;
|
||||
b2_toiRootIters = 0; b2_toiMaxRootIters = 0;
|
||||
b2_toiTime = 0.0f; b2_toiMaxTime = 0.0f;
|
||||
}
|
||||
|
||||
void Launch()
|
||||
{
|
||||
extern int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
|
||||
extern int32 b2_toiCalls, b2_toiIters;
|
||||
extern int32 b2_toiRootIters, b2_toiMaxRootIters;
|
||||
extern float32 b2_toiTime, b2_toiMaxTime;
|
||||
|
||||
b2_gjkCalls = 0; b2_gjkIters = 0; b2_gjkMaxIters = 0;
|
||||
b2_toiCalls = 0; b2_toiIters = 0;
|
||||
b2_toiRootIters = 0; b2_toiMaxRootIters = 0;
|
||||
b2_toiTime = 0.0f; b2_toiMaxTime = 0.0f;
|
||||
|
||||
m_body->SetTransform(b2Vec2(0.0f, 20.0f), 0.0f);
|
||||
m_angularVelocity = RandomFloat(-50.0f, 50.0f);
|
||||
m_body->SetLinearVelocity(b2Vec2(0.0f, -100.0f));
|
||||
m_body->SetAngularVelocity(m_angularVelocity);
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
extern int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
|
||||
|
||||
if (b2_gjkCalls > 0)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "gjk calls = %d, ave gjk iters = %3.1f, max gjk iters = %d",
|
||||
b2_gjkCalls, b2_gjkIters / float32(b2_gjkCalls), b2_gjkMaxIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
extern int32 b2_toiCalls, b2_toiIters;
|
||||
extern int32 b2_toiRootIters, b2_toiMaxRootIters;
|
||||
extern float32 b2_toiTime, b2_toiMaxTime;
|
||||
|
||||
if (b2_toiCalls > 0)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "toi calls = %d, ave [max] toi iters = %3.1f [%d]",
|
||||
b2_toiCalls, b2_toiIters / float32(b2_toiCalls), b2_toiMaxRootIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "ave [max] toi root iters = %3.1f [%d]",
|
||||
b2_toiRootIters / float32(b2_toiCalls), b2_toiMaxRootIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "ave [max] toi time = %.1f [%.1f] (microseconds)",
|
||||
1000.0f * b2_toiTime / float32(b2_toiCalls), 1000.0f * b2_toiMaxTime);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
if (m_stepCount % 60 == 0)
|
||||
{
|
||||
//Launch();
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new ContinuousTest;
|
||||
}
|
||||
|
||||
b2Body* m_body;
|
||||
float32 m_angularVelocity;
|
||||
};
|
||||
|
||||
#endif
|
||||
109
external/Box2D-2.3.1/Box2D/Testbed/Tests/ConvexHull.h
vendored
Normal file
109
external/Box2D-2.3.1/Box2D/Testbed/Tests/ConvexHull.h
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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_HULL_H
|
||||
#define CONVEX_HULL_H
|
||||
|
||||
class ConvexHull : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_count = b2_maxPolygonVertices
|
||||
};
|
||||
|
||||
ConvexHull()
|
||||
{
|
||||
Generate();
|
||||
m_auto = false;
|
||||
}
|
||||
|
||||
void Generate()
|
||||
{
|
||||
b2Vec2 lowerBound(-8.0f, -8.0f);
|
||||
b2Vec2 upperBound(8.0f, 8.0f);
|
||||
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
float32 x = 10.0f * RandomFloat();
|
||||
float32 y = 10.0f * RandomFloat();
|
||||
|
||||
// Clamp onto a square to help create collinearities.
|
||||
// This will stress the convex hull algorithm.
|
||||
b2Vec2 v(x, y);
|
||||
v = b2Clamp(v, lowerBound, upperBound);
|
||||
m_points[i] = v;
|
||||
}
|
||||
|
||||
m_count = e_count;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new ConvexHull;
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_auto = !m_auto;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_G:
|
||||
Generate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.Set(m_points, m_count);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press g to generate a new random convex hull");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
g_debugDraw.DrawPolygon(shape.m_vertices, shape.m_count, b2Color(0.9f, 0.9f, 0.9f));
|
||||
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
g_debugDraw.DrawPoint(m_points[i], 3.0f, b2Color(0.3f, 0.9f, 0.3f));
|
||||
g_debugDraw.DrawString(m_points[i] + b2Vec2(0.05f, 0.05f), "%d", i);
|
||||
}
|
||||
|
||||
if (shape.Validate() == false)
|
||||
{
|
||||
m_textLine += 0;
|
||||
}
|
||||
|
||||
if (m_auto)
|
||||
{
|
||||
Generate();
|
||||
}
|
||||
}
|
||||
|
||||
b2Vec2 m_points[b2_maxPolygonVertices];
|
||||
int32 m_count;
|
||||
bool m_auto;
|
||||
};
|
||||
|
||||
#endif
|
||||
98
external/Box2D-2.3.1/Box2D/Testbed/Tests/ConveyorBelt.h
vendored
Normal file
98
external/Box2D-2.3.1/Box2D/Testbed/Tests/ConveyorBelt.h
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 CONVEYOR_BELT_H
|
||||
#define CONVEYOR_BELT_H
|
||||
|
||||
class ConveyorBelt : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
ConveyorBelt()
|
||||
{
|
||||
// Ground
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Platform
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-5.0f, 5.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(10.0f, 0.5f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.friction = 0.8f;
|
||||
m_platform = body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Boxes
|
||||
for (int32 i = 0; i < 5; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-10.0f + 2.0f * i, 7.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
body->CreateFixture(&shape, 20.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
|
||||
{
|
||||
Test::PreSolve(contact, oldManifold);
|
||||
|
||||
b2Fixture* fixtureA = contact->GetFixtureA();
|
||||
b2Fixture* fixtureB = contact->GetFixtureB();
|
||||
|
||||
if (fixtureA == m_platform)
|
||||
{
|
||||
contact->SetTangentSpeed(5.0f);
|
||||
}
|
||||
|
||||
if (fixtureB == m_platform)
|
||||
{
|
||||
contact->SetTangentSpeed(-5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new ConveyorBelt;
|
||||
}
|
||||
|
||||
b2Fixture* m_platform;
|
||||
};
|
||||
|
||||
#endif
|
||||
135
external/Box2D-2.3.1/Box2D/Testbed/Tests/DistanceTest.h
vendored
Normal file
135
external/Box2D-2.3.1/Box2D/Testbed/Tests/DistanceTest.h
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 DISTANCE_TEST_H
|
||||
#define DISTANCE_TEST_H
|
||||
|
||||
class DistanceTest : public Test
|
||||
{
|
||||
public:
|
||||
DistanceTest()
|
||||
{
|
||||
{
|
||||
m_transformA.SetIdentity();
|
||||
m_transformA.p.Set(0.0f, -0.2f);
|
||||
m_polygonA.SetAsBox(10.0f, 0.2f);
|
||||
}
|
||||
|
||||
{
|
||||
m_positionB.Set(12.017401f, 0.13678508f);
|
||||
m_angleB = -0.0109265f;
|
||||
m_transformB.Set(m_positionB, m_angleB);
|
||||
|
||||
m_polygonB.SetAsBox(2.0f, 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new DistanceTest;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
b2DistanceInput input;
|
||||
input.proxyA.Set(&m_polygonA, 0);
|
||||
input.proxyB.Set(&m_polygonB, 0);
|
||||
input.transformA = m_transformA;
|
||||
input.transformB = m_transformB;
|
||||
input.useRadii = true;
|
||||
b2SimplexCache cache;
|
||||
cache.count = 0;
|
||||
b2DistanceOutput output;
|
||||
b2Distance(&output, &cache, &input);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "distance = %g", output.distance);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "iterations = %d", output.iterations);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
{
|
||||
b2Color color(0.9f, 0.9f, 0.9f);
|
||||
b2Vec2 v[b2_maxPolygonVertices];
|
||||
for (int32 i = 0; i < m_polygonA.m_count; ++i)
|
||||
{
|
||||
v[i] = b2Mul(m_transformA, m_polygonA.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(v, m_polygonA.m_count, color);
|
||||
|
||||
for (int32 i = 0; i < m_polygonB.m_count; ++i)
|
||||
{
|
||||
v[i] = b2Mul(m_transformB, m_polygonB.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(v, m_polygonB.m_count, color);
|
||||
}
|
||||
|
||||
b2Vec2 x1 = output.pointA;
|
||||
b2Vec2 x2 = output.pointB;
|
||||
|
||||
b2Color c1(1.0f, 0.0f, 0.0f);
|
||||
g_debugDraw.DrawPoint(x1, 4.0f, c1);
|
||||
|
||||
b2Color c2(1.0f, 1.0f, 0.0f);
|
||||
g_debugDraw.DrawPoint(x2, 4.0f, c2);
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_positionB.x -= 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
m_positionB.x += 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
m_positionB.y -= 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_W:
|
||||
m_positionB.y += 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_Q:
|
||||
m_angleB += 0.1f * b2_pi;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_E:
|
||||
m_angleB -= 0.1f * b2_pi;
|
||||
break;
|
||||
}
|
||||
|
||||
m_transformB.Set(m_positionB, m_angleB);
|
||||
}
|
||||
|
||||
b2Vec2 m_positionB;
|
||||
float32 m_angleB;
|
||||
|
||||
b2Transform m_transformA;
|
||||
b2Transform m_transformB;
|
||||
b2PolygonShape m_polygonA;
|
||||
b2PolygonShape m_polygonB;
|
||||
};
|
||||
|
||||
#endif
|
||||
215
external/Box2D-2.3.1/Box2D/Testbed/Tests/Dominos.h
vendored
Normal file
215
external/Box2D-2.3.1/Box2D/Testbed/Tests/Dominos.h
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 DOMINOS_H
|
||||
#define DOMINOS_H
|
||||
|
||||
class Dominos : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
Dominos()
|
||||
{
|
||||
b2Body* b1;
|
||||
{
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
|
||||
b2BodyDef bd;
|
||||
b1 = m_world->CreateBody(&bd);
|
||||
b1->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(6.0f, 0.25f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-1.5f, 10.0f);
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.1f, 1.0f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
fd.friction = 0.1f;
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-6.0f + 1.0f * i, 11.25f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(7.0f, 0.25f, b2Vec2_zero, 0.3f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(1.0f, 6.0f);
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
b2Body* b2;
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f, 1.5f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-7.0f, 4.0f);
|
||||
b2 = m_world->CreateBody(&bd);
|
||||
b2->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
b2Body* b3;
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(6.0f, 0.125f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-0.9f, 1.0f);
|
||||
bd.angle = -0.15f;
|
||||
|
||||
b3 = m_world->CreateBody(&bd);
|
||||
b3->CreateFixture(&shape, 10.0f);
|
||||
}
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
b2Vec2 anchor;
|
||||
|
||||
anchor.Set(-2.0f, 1.0f);
|
||||
jd.Initialize(b1, b3, anchor);
|
||||
jd.collideConnected = true;
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
b2Body* b4;
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f, 0.25f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-10.0f, 15.0f);
|
||||
b4 = m_world->CreateBody(&bd);
|
||||
b4->CreateFixture(&shape, 10.0f);
|
||||
}
|
||||
|
||||
anchor.Set(-7.0f, 15.0f);
|
||||
jd.Initialize(b2, b4, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
b2Body* b5;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(6.5f, 3.0f);
|
||||
b5 = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
b2FixtureDef fd;
|
||||
|
||||
fd.shape = &shape;
|
||||
fd.density = 10.0f;
|
||||
fd.friction = 0.1f;
|
||||
|
||||
shape.SetAsBox(1.0f, 0.1f, b2Vec2(0.0f, -0.9f), 0.0f);
|
||||
b5->CreateFixture(&fd);
|
||||
|
||||
shape.SetAsBox(0.1f, 1.0f, b2Vec2(-0.9f, 0.0f), 0.0f);
|
||||
b5->CreateFixture(&fd);
|
||||
|
||||
shape.SetAsBox(0.1f, 1.0f, b2Vec2(0.9f, 0.0f), 0.0f);
|
||||
b5->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
anchor.Set(6.0f, 2.0f);
|
||||
jd.Initialize(b1, b5, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
b2Body* b6;
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.0f, 0.1f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(6.5f, 4.1f);
|
||||
b6 = m_world->CreateBody(&bd);
|
||||
b6->CreateFixture(&shape, 30.0f);
|
||||
}
|
||||
|
||||
anchor.Set(7.5f, 4.0f);
|
||||
jd.Initialize(b5, b6, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
b2Body* b7;
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.1f, 1.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(7.4f, 1.0f);
|
||||
|
||||
b7 = m_world->CreateBody(&bd);
|
||||
b7->CreateFixture(&shape, 10.0f);
|
||||
}
|
||||
|
||||
b2DistanceJointDef djd;
|
||||
djd.bodyA = b3;
|
||||
djd.bodyB = b7;
|
||||
djd.localAnchorA.Set(6.0f, 0.0f);
|
||||
djd.localAnchorB.Set(0.0f, -1.0f);
|
||||
b2Vec2 d = djd.bodyB->GetWorldPoint(djd.localAnchorB) - djd.bodyA->GetWorldPoint(djd.localAnchorA);
|
||||
djd.length = d.Length();
|
||||
m_world->CreateJoint(&djd);
|
||||
|
||||
{
|
||||
float32 radius = 0.2f;
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = radius;
|
||||
|
||||
for (int32 i = 0; i < 4; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(5.9f + 2.0f * radius * i, 2.4f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 10.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Dominos;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
175
external/Box2D-2.3.1/Box2D/Testbed/Tests/DumpShell.h
vendored
Normal file
175
external/Box2D-2.3.1/Box2D/Testbed/Tests/DumpShell.h
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 DUMP_SHELL_H
|
||||
#define DUMP_SHELL_H
|
||||
|
||||
// This test holds worlds dumped using b2World::Dump.
|
||||
class DumpShell : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
DumpShell()
|
||||
{
|
||||
//Source code dump of Box2D scene: issue304-minimal-case.rube
|
||||
//
|
||||
// Created by R.U.B.E 1.3.0
|
||||
// Using Box2D version 2.3.0
|
||||
// Wed April 3 2013 04:33:28
|
||||
//
|
||||
// This code is originally intended for use in the Box2D testbed,
|
||||
// but you can easily use it in other applications by providing
|
||||
// a b2World for use as the 'm_world' variable in the code below.
|
||||
|
||||
b2Vec2 g(0.000000000000000e+00f, -1.000000000000000e+01f);
|
||||
m_world->SetGravity(g);
|
||||
b2Body** bodies = (b2Body**)b2Alloc(3 * sizeof(b2Body*));
|
||||
b2Joint** joints = (b2Joint**)b2Alloc(0 * sizeof(b2Joint*));
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2BodyType(0);
|
||||
bd.position.Set(2.587699890136719e-02f, 5.515012264251709e+00f);
|
||||
bd.angle = 0.000000000000000e+00f;
|
||||
bd.linearVelocity.Set(0.000000000000000e+00f, 0.000000000000000e+00f);
|
||||
bd.angularVelocity = 0.000000000000000e+00f;
|
||||
bd.linearDamping = 0.000000000000000e+00f;
|
||||
bd.angularDamping = 0.000000000000000e+00f;
|
||||
bd.allowSleep = bool(4);
|
||||
bd.awake = bool(2);
|
||||
bd.fixedRotation = bool(0);
|
||||
bd.bullet = bool(0);
|
||||
bd.active = bool(32);
|
||||
bd.gravityScale = 1.000000000000000e+00f;
|
||||
bodies[0] = m_world->CreateBody(&bd);
|
||||
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.friction = 2.000000029802322e-01f;
|
||||
fd.restitution = 0.000000000000000e+00f;
|
||||
fd.density = 1.000000000000000e+00f;
|
||||
fd.isSensor = bool(0);
|
||||
fd.filter.categoryBits = uint16(1);
|
||||
fd.filter.maskBits = uint16(65535);
|
||||
fd.filter.groupIndex = int16(0);
|
||||
b2PolygonShape shape;
|
||||
b2Vec2 vs[8];
|
||||
vs[0].Set(7.733039855957031e-01f, -1.497260034084320e-01f);
|
||||
vs[1].Set(-4.487270116806030e-01f, 1.138330027461052e-01f);
|
||||
vs[2].Set(-1.880589962005615e+00f, -1.365900039672852e-01f);
|
||||
vs[3].Set(3.972740173339844e-01f, -3.897832870483398e+00f);
|
||||
shape.Set(vs, 4);
|
||||
|
||||
fd.shape = &shape;
|
||||
|
||||
bodies[0]->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2BodyType(2);
|
||||
bd.position.Set(-3.122138977050781e-02f, 7.535382270812988e+00f);
|
||||
bd.angle = -1.313644275069237e-02f;
|
||||
bd.linearVelocity.Set(8.230687379837036e-01f, 7.775862514972687e-02f);
|
||||
bd.angularVelocity = 3.705333173274994e-02f;
|
||||
bd.linearDamping = 0.000000000000000e+00f;
|
||||
bd.angularDamping = 0.000000000000000e+00f;
|
||||
bd.allowSleep = bool(4);
|
||||
bd.awake = bool(2);
|
||||
bd.fixedRotation = bool(0);
|
||||
bd.bullet = bool(0);
|
||||
bd.active = bool(32);
|
||||
bd.gravityScale = 1.000000000000000e+00f;
|
||||
bodies[1] = m_world->CreateBody(&bd);
|
||||
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.friction = 5.000000000000000e-01f;
|
||||
fd.restitution = 0.000000000000000e+00f;
|
||||
fd.density = 5.000000000000000e+00f;
|
||||
fd.isSensor = bool(0);
|
||||
fd.filter.categoryBits = uint16(1);
|
||||
fd.filter.maskBits = uint16(65535);
|
||||
fd.filter.groupIndex = int16(0);
|
||||
b2PolygonShape shape;
|
||||
b2Vec2 vs[8];
|
||||
vs[0].Set(3.473900079727173e+00f, -2.009889930486679e-01f);
|
||||
vs[1].Set(3.457079887390137e+00f, 3.694039955735207e-02f);
|
||||
vs[2].Set(-3.116359949111938e+00f, 2.348500071093440e-03f);
|
||||
vs[3].Set(-3.109960079193115e+00f, -3.581250011920929e-01f);
|
||||
vs[4].Set(-2.590820074081421e+00f, -5.472509860992432e-01f);
|
||||
vs[5].Set(2.819370031356812e+00f, -5.402340292930603e-01f);
|
||||
shape.Set(vs, 6);
|
||||
|
||||
fd.shape = &shape;
|
||||
|
||||
bodies[1]->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2BodyType(2);
|
||||
bd.position.Set(-7.438077926635742e-01f, 6.626811981201172e+00f);
|
||||
bd.angle = -1.884713363647461e+01f;
|
||||
bd.linearVelocity.Set(1.785794943571091e-01f, 3.799796104431152e-07f);
|
||||
bd.angularVelocity = -5.908820639888290e-06f;
|
||||
bd.linearDamping = 0.000000000000000e+00f;
|
||||
bd.angularDamping = 0.000000000000000e+00f;
|
||||
bd.allowSleep = bool(4);
|
||||
bd.awake = bool(2);
|
||||
bd.fixedRotation = bool(0);
|
||||
bd.bullet = bool(0);
|
||||
bd.active = bool(32);
|
||||
bd.gravityScale = 1.000000000000000e+00f;
|
||||
bodies[2] = m_world->CreateBody(&bd);
|
||||
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.friction = 9.499999880790710e-01f;
|
||||
fd.restitution = 0.000000000000000e+00f;
|
||||
fd.density = 1.000000000000000e+01f;
|
||||
fd.isSensor = bool(0);
|
||||
fd.filter.categoryBits = uint16(1);
|
||||
fd.filter.maskBits = uint16(65535);
|
||||
fd.filter.groupIndex = int16(-3);
|
||||
b2PolygonShape shape;
|
||||
b2Vec2 vs[8];
|
||||
vs[0].Set(1.639146506786346e-01f, 4.428443685173988e-02f);
|
||||
vs[1].Set(-1.639146655797958e-01f, 4.428443685173988e-02f);
|
||||
vs[2].Set(-1.639146655797958e-01f, -4.428443312644958e-02f);
|
||||
vs[3].Set(1.639146357774734e-01f, -4.428444057703018e-02f);
|
||||
shape.Set(vs, 4);
|
||||
|
||||
fd.shape = &shape;
|
||||
|
||||
bodies[2]->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
b2Free(joints);
|
||||
b2Free(bodies);
|
||||
joints = NULL;
|
||||
bodies = NULL;
|
||||
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new DumpShell;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
357
external/Box2D-2.3.1/Box2D/Testbed/Tests/DynamicTreeTest.h
vendored
Normal file
357
external/Box2D-2.3.1/Box2D/Testbed/Tests/DynamicTreeTest.h
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 DYNAMIC_TREE_TEST_H
|
||||
#define DYNAMIC_TREE_TEST_H
|
||||
|
||||
class DynamicTreeTest : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_actorCount = 128
|
||||
};
|
||||
|
||||
DynamicTreeTest()
|
||||
{
|
||||
m_worldExtent = 15.0f;
|
||||
m_proxyExtent = 0.5f;
|
||||
|
||||
srand(888);
|
||||
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
Actor* actor = m_actors + i;
|
||||
GetRandomAABB(&actor->aabb);
|
||||
actor->proxyId = m_tree.CreateProxy(actor->aabb, actor);
|
||||
}
|
||||
|
||||
m_stepCount = 0;
|
||||
|
||||
float32 h = m_worldExtent;
|
||||
m_queryAABB.lowerBound.Set(-3.0f, -4.0f + h);
|
||||
m_queryAABB.upperBound.Set(5.0f, 6.0f + h);
|
||||
|
||||
m_rayCastInput.p1.Set(-5.0, 5.0f + h);
|
||||
m_rayCastInput.p2.Set(7.0f, -4.0f + h);
|
||||
//m_rayCastInput.p1.Set(0.0f, 2.0f + h);
|
||||
//m_rayCastInput.p2.Set(0.0f, -2.0f + h);
|
||||
m_rayCastInput.maxFraction = 1.0f;
|
||||
|
||||
m_automated = false;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new DynamicTreeTest;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
B2_NOT_USED(settings);
|
||||
|
||||
m_rayActor = NULL;
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
m_actors[i].fraction = 1.0f;
|
||||
m_actors[i].overlap = false;
|
||||
}
|
||||
|
||||
if (m_automated == true)
|
||||
{
|
||||
int32 actionCount = b2Max(1, e_actorCount >> 2);
|
||||
|
||||
for (int32 i = 0; i < actionCount; ++i)
|
||||
{
|
||||
Action();
|
||||
}
|
||||
}
|
||||
|
||||
Query();
|
||||
RayCast();
|
||||
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
Actor* actor = m_actors + i;
|
||||
if (actor->proxyId == b2_nullNode)
|
||||
continue;
|
||||
|
||||
b2Color c(0.9f, 0.9f, 0.9f);
|
||||
if (actor == m_rayActor && actor->overlap)
|
||||
{
|
||||
c.Set(0.9f, 0.6f, 0.6f);
|
||||
}
|
||||
else if (actor == m_rayActor)
|
||||
{
|
||||
c.Set(0.6f, 0.9f, 0.6f);
|
||||
}
|
||||
else if (actor->overlap)
|
||||
{
|
||||
c.Set(0.6f, 0.6f, 0.9f);
|
||||
}
|
||||
|
||||
g_debugDraw.DrawAABB(&actor->aabb, c);
|
||||
}
|
||||
|
||||
b2Color c(0.7f, 0.7f, 0.7f);
|
||||
g_debugDraw.DrawAABB(&m_queryAABB, c);
|
||||
|
||||
g_debugDraw.DrawSegment(m_rayCastInput.p1, m_rayCastInput.p2, c);
|
||||
|
||||
b2Color c1(0.2f, 0.9f, 0.2f);
|
||||
b2Color c2(0.9f, 0.2f, 0.2f);
|
||||
g_debugDraw.DrawPoint(m_rayCastInput.p1, 6.0f, c1);
|
||||
g_debugDraw.DrawPoint(m_rayCastInput.p2, 6.0f, c2);
|
||||
|
||||
if (m_rayActor)
|
||||
{
|
||||
b2Color cr(0.2f, 0.2f, 0.9f);
|
||||
b2Vec2 p = m_rayCastInput.p1 + m_rayActor->fraction * (m_rayCastInput.p2 - m_rayCastInput.p1);
|
||||
g_debugDraw.DrawPoint(p, 6.0f, cr);
|
||||
}
|
||||
|
||||
{
|
||||
int32 height = m_tree.GetHeight();
|
||||
g_debugDraw.DrawString(5, m_textLine, "dynamic tree height = %d", height);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
++m_stepCount;
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_automated = !m_automated;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_C:
|
||||
CreateProxy();
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
DestroyProxy();
|
||||
break;
|
||||
|
||||
case GLFW_KEY_M:
|
||||
MoveProxy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool QueryCallback(int32 proxyId)
|
||||
{
|
||||
Actor* actor = (Actor*)m_tree.GetUserData(proxyId);
|
||||
actor->overlap = b2TestOverlap(m_queryAABB, actor->aabb);
|
||||
return true;
|
||||
}
|
||||
|
||||
float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
|
||||
{
|
||||
Actor* actor = (Actor*)m_tree.GetUserData(proxyId);
|
||||
|
||||
b2RayCastOutput output;
|
||||
bool hit = actor->aabb.RayCast(&output, input);
|
||||
|
||||
if (hit)
|
||||
{
|
||||
m_rayCastOutput = output;
|
||||
m_rayActor = actor;
|
||||
m_rayActor->fraction = output.fraction;
|
||||
return output.fraction;
|
||||
}
|
||||
|
||||
return input.maxFraction;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct Actor
|
||||
{
|
||||
b2AABB aabb;
|
||||
float32 fraction;
|
||||
bool overlap;
|
||||
int32 proxyId;
|
||||
};
|
||||
|
||||
void GetRandomAABB(b2AABB* aabb)
|
||||
{
|
||||
b2Vec2 w; w.Set(2.0f * m_proxyExtent, 2.0f * m_proxyExtent);
|
||||
//aabb->lowerBound.x = -m_proxyExtent;
|
||||
//aabb->lowerBound.y = -m_proxyExtent + m_worldExtent;
|
||||
aabb->lowerBound.x = RandomFloat(-m_worldExtent, m_worldExtent);
|
||||
aabb->lowerBound.y = RandomFloat(0.0f, 2.0f * m_worldExtent);
|
||||
aabb->upperBound = aabb->lowerBound + w;
|
||||
}
|
||||
|
||||
void MoveAABB(b2AABB* aabb)
|
||||
{
|
||||
b2Vec2 d;
|
||||
d.x = RandomFloat(-0.5f, 0.5f);
|
||||
d.y = RandomFloat(-0.5f, 0.5f);
|
||||
//d.x = 2.0f;
|
||||
//d.y = 0.0f;
|
||||
aabb->lowerBound += d;
|
||||
aabb->upperBound += d;
|
||||
|
||||
b2Vec2 c0 = 0.5f * (aabb->lowerBound + aabb->upperBound);
|
||||
b2Vec2 min; min.Set(-m_worldExtent, 0.0f);
|
||||
b2Vec2 max; max.Set(m_worldExtent, 2.0f * m_worldExtent);
|
||||
b2Vec2 c = b2Clamp(c0, min, max);
|
||||
|
||||
aabb->lowerBound += c - c0;
|
||||
aabb->upperBound += c - c0;
|
||||
}
|
||||
|
||||
void CreateProxy()
|
||||
{
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
int32 j = rand() % e_actorCount;
|
||||
Actor* actor = m_actors + j;
|
||||
if (actor->proxyId == b2_nullNode)
|
||||
{
|
||||
GetRandomAABB(&actor->aabb);
|
||||
actor->proxyId = m_tree.CreateProxy(actor->aabb, actor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyProxy()
|
||||
{
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
int32 j = rand() % e_actorCount;
|
||||
Actor* actor = m_actors + j;
|
||||
if (actor->proxyId != b2_nullNode)
|
||||
{
|
||||
m_tree.DestroyProxy(actor->proxyId);
|
||||
actor->proxyId = b2_nullNode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveProxy()
|
||||
{
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
int32 j = rand() % e_actorCount;
|
||||
Actor* actor = m_actors + j;
|
||||
if (actor->proxyId == b2_nullNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
b2AABB aabb0 = actor->aabb;
|
||||
MoveAABB(&actor->aabb);
|
||||
b2Vec2 displacement = actor->aabb.GetCenter() - aabb0.GetCenter();
|
||||
m_tree.MoveProxy(actor->proxyId, actor->aabb, displacement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Action()
|
||||
{
|
||||
int32 choice = rand() % 20;
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case 0:
|
||||
CreateProxy();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DestroyProxy();
|
||||
break;
|
||||
|
||||
default:
|
||||
MoveProxy();
|
||||
}
|
||||
}
|
||||
|
||||
void Query()
|
||||
{
|
||||
m_tree.Query(this, m_queryAABB);
|
||||
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
if (m_actors[i].proxyId == b2_nullNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool overlap = b2TestOverlap(m_queryAABB, m_actors[i].aabb);
|
||||
B2_NOT_USED(overlap);
|
||||
b2Assert(overlap == m_actors[i].overlap);
|
||||
}
|
||||
}
|
||||
|
||||
void RayCast()
|
||||
{
|
||||
m_rayActor = NULL;
|
||||
|
||||
b2RayCastInput input = m_rayCastInput;
|
||||
|
||||
// Ray cast against the dynamic tree.
|
||||
m_tree.RayCast(this, input);
|
||||
|
||||
// Brute force ray cast.
|
||||
Actor* bruteActor = NULL;
|
||||
b2RayCastOutput bruteOutput;
|
||||
for (int32 i = 0; i < e_actorCount; ++i)
|
||||
{
|
||||
if (m_actors[i].proxyId == b2_nullNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
b2RayCastOutput output;
|
||||
bool hit = m_actors[i].aabb.RayCast(&output, input);
|
||||
if (hit)
|
||||
{
|
||||
bruteActor = m_actors + i;
|
||||
bruteOutput = output;
|
||||
input.maxFraction = output.fraction;
|
||||
}
|
||||
}
|
||||
|
||||
if (bruteActor != NULL)
|
||||
{
|
||||
b2Assert(bruteOutput.fraction == m_rayCastOutput.fraction);
|
||||
}
|
||||
}
|
||||
|
||||
float32 m_worldExtent;
|
||||
float32 m_proxyExtent;
|
||||
|
||||
b2DynamicTree m_tree;
|
||||
b2AABB m_queryAABB;
|
||||
b2RayCastInput m_rayCastInput;
|
||||
b2RayCastOutput m_rayCastOutput;
|
||||
Actor* m_rayActor;
|
||||
Actor m_actors[e_actorCount];
|
||||
int32 m_stepCount;
|
||||
bool m_automated;
|
||||
};
|
||||
|
||||
#endif
|
||||
249
external/Box2D-2.3.1/Box2D/Testbed/Tests/EdgeShapes.h
vendored
Normal file
249
external/Box2D-2.3.1/Box2D/Testbed/Tests/EdgeShapes.h
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 EDGE_SHAPES_H
|
||||
#define EDGE_SHAPES_H
|
||||
|
||||
class EdgeShapesCallback : public b2RayCastCallback
|
||||
{
|
||||
public:
|
||||
EdgeShapesCallback()
|
||||
{
|
||||
m_fixture = NULL;
|
||||
}
|
||||
|
||||
float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point,
|
||||
const b2Vec2& normal, float32 fraction)
|
||||
{
|
||||
m_fixture = fixture;
|
||||
m_point = point;
|
||||
m_normal = normal;
|
||||
|
||||
return fraction;
|
||||
}
|
||||
|
||||
b2Fixture* m_fixture;
|
||||
b2Vec2 m_point;
|
||||
b2Vec2 m_normal;
|
||||
};
|
||||
|
||||
class EdgeShapes : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_maxBodies = 256
|
||||
};
|
||||
|
||||
EdgeShapes()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
float32 x1 = -20.0f;
|
||||
float32 y1 = 2.0f * cosf(x1 / 10.0f * b2_pi);
|
||||
for (int32 i = 0; i < 80; ++i)
|
||||
{
|
||||
float32 x2 = x1 + 0.5f;
|
||||
float32 y2 = 2.0f * cosf(x2 / 10.0f * b2_pi);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(x1, y1), b2Vec2(x2, y2));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.5f, 0.0f);
|
||||
vertices[1].Set(0.5f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
m_polygons[0].Set(vertices, 3);
|
||||
}
|
||||
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.1f, 0.0f);
|
||||
vertices[1].Set(0.1f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
m_polygons[1].Set(vertices, 3);
|
||||
}
|
||||
|
||||
{
|
||||
float32 w = 1.0f;
|
||||
float32 b = w / (2.0f + b2Sqrt(2.0f));
|
||||
float32 s = b2Sqrt(2.0f) * b;
|
||||
|
||||
b2Vec2 vertices[8];
|
||||
vertices[0].Set(0.5f * s, 0.0f);
|
||||
vertices[1].Set(0.5f * w, b);
|
||||
vertices[2].Set(0.5f * w, b + s);
|
||||
vertices[3].Set(0.5f * s, w);
|
||||
vertices[4].Set(-0.5f * s, w);
|
||||
vertices[5].Set(-0.5f * w, b + s);
|
||||
vertices[6].Set(-0.5f * w, b);
|
||||
vertices[7].Set(-0.5f * s, 0.0f);
|
||||
|
||||
m_polygons[2].Set(vertices, 8);
|
||||
}
|
||||
|
||||
{
|
||||
m_polygons[3].SetAsBox(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
{
|
||||
m_circle.m_radius = 0.5f;
|
||||
}
|
||||
|
||||
m_bodyIndex = 0;
|
||||
memset(m_bodies, 0, sizeof(m_bodies));
|
||||
|
||||
m_angle = 0.0f;
|
||||
}
|
||||
|
||||
void Create(int32 index)
|
||||
{
|
||||
if (m_bodies[m_bodyIndex] != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[m_bodyIndex]);
|
||||
m_bodies[m_bodyIndex] = NULL;
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
|
||||
float32 x = RandomFloat(-10.0f, 10.0f);
|
||||
float32 y = RandomFloat(10.0f, 20.0f);
|
||||
bd.position.Set(x, y);
|
||||
bd.angle = RandomFloat(-b2_pi, b2_pi);
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
if (index == 4)
|
||||
{
|
||||
bd.angularDamping = 0.02f;
|
||||
}
|
||||
|
||||
m_bodies[m_bodyIndex] = m_world->CreateBody(&bd);
|
||||
|
||||
if (index < 4)
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = m_polygons + index;
|
||||
fd.friction = 0.3f;
|
||||
fd.density = 20.0f;
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &m_circle;
|
||||
fd.friction = 0.3f;
|
||||
fd.density = 20.0f;
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
m_bodyIndex = (m_bodyIndex + 1) % e_maxBodies;
|
||||
}
|
||||
|
||||
void DestroyBody()
|
||||
{
|
||||
for (int32 i = 0; i < e_maxBodies; ++i)
|
||||
{
|
||||
if (m_bodies[i] != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[i]);
|
||||
m_bodies[i] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_1:
|
||||
case GLFW_KEY_2:
|
||||
case GLFW_KEY_3:
|
||||
case GLFW_KEY_4:
|
||||
case GLFW_KEY_5:
|
||||
Create(key - GLFW_KEY_1);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
DestroyBody();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
bool advanceRay = settings->pause == 0 || settings->singleStep;
|
||||
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 1-5 to drop stuff");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
float32 L = 25.0f;
|
||||
b2Vec2 point1(0.0f, 10.0f);
|
||||
b2Vec2 d(L * cosf(m_angle), -L * b2Abs(sinf(m_angle)));
|
||||
b2Vec2 point2 = point1 + d;
|
||||
|
||||
EdgeShapesCallback callback;
|
||||
|
||||
m_world->RayCast(&callback, point1, point2);
|
||||
|
||||
if (callback.m_fixture)
|
||||
{
|
||||
g_debugDraw.DrawPoint(callback.m_point, 5.0f, b2Color(0.4f, 0.9f, 0.4f));
|
||||
|
||||
g_debugDraw.DrawSegment(point1, callback.m_point, b2Color(0.8f, 0.8f, 0.8f));
|
||||
|
||||
b2Vec2 head = callback.m_point + 0.5f * callback.m_normal;
|
||||
g_debugDraw.DrawSegment(callback.m_point, head, b2Color(0.9f, 0.9f, 0.4f));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debugDraw.DrawSegment(point1, point2, b2Color(0.8f, 0.8f, 0.8f));
|
||||
}
|
||||
|
||||
if (advanceRay)
|
||||
{
|
||||
m_angle += 0.25f * b2_pi / 180.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new EdgeShapes;
|
||||
}
|
||||
|
||||
int32 m_bodyIndex;
|
||||
b2Body* m_bodies[e_maxBodies];
|
||||
b2PolygonShape m_polygons[4];
|
||||
b2CircleShape m_circle;
|
||||
|
||||
float32 m_angle;
|
||||
};
|
||||
|
||||
#endif
|
||||
109
external/Box2D-2.3.1/Box2D/Testbed/Tests/EdgeTest.h
vendored
Normal file
109
external/Box2D-2.3.1/Box2D/Testbed/Tests/EdgeTest.h
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 EDGE_TEST_H
|
||||
#define EDGE_TEST_H
|
||||
|
||||
class EdgeTest : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
EdgeTest()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2Vec2 v1(-10.0f, 0.0f), v2(-7.0f, -2.0f), v3(-4.0f, 0.0f);
|
||||
b2Vec2 v4(0.0f, 0.0f), v5(4.0f, 0.0f), v6(7.0f, 2.0f), v7(10.0f, 0.0f);
|
||||
|
||||
b2EdgeShape shape;
|
||||
|
||||
shape.Set(v1, v2);
|
||||
shape.m_hasVertex3 = true;
|
||||
shape.m_vertex3 = v3;
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(v2, v3);
|
||||
shape.m_hasVertex0 = true;
|
||||
shape.m_hasVertex3 = true;
|
||||
shape.m_vertex0 = v1;
|
||||
shape.m_vertex3 = v4;
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(v3, v4);
|
||||
shape.m_hasVertex0 = true;
|
||||
shape.m_hasVertex3 = true;
|
||||
shape.m_vertex0 = v2;
|
||||
shape.m_vertex3 = v5;
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(v4, v5);
|
||||
shape.m_hasVertex0 = true;
|
||||
shape.m_hasVertex3 = true;
|
||||
shape.m_vertex0 = v3;
|
||||
shape.m_vertex3 = v6;
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(v5, v6);
|
||||
shape.m_hasVertex0 = true;
|
||||
shape.m_hasVertex3 = true;
|
||||
shape.m_vertex0 = v4;
|
||||
shape.m_vertex3 = v7;
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(v6, v7);
|
||||
shape.m_hasVertex0 = true;
|
||||
shape.m_vertex0 = v5;
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-0.5f, 0.6f);
|
||||
bd.allowSleep = false;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(1.0f, 0.6f);
|
||||
bd.allowSleep = false;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new EdgeTest;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
177
external/Box2D-2.3.1/Box2D/Testbed/Tests/Gears.h
vendored
Normal file
177
external/Box2D-2.3.1/Box2D/Testbed/Tests/Gears.h
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 GEARS_H
|
||||
#define GEARS_H
|
||||
|
||||
class Gears : public Test
|
||||
{
|
||||
public:
|
||||
Gears()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(50.0f, 0.0f), b2Vec2(-50.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape circle1;
|
||||
circle1.m_radius = 1.0f;
|
||||
|
||||
b2PolygonShape box;
|
||||
box.SetAsBox(0.5f, 5.0f);
|
||||
|
||||
b2CircleShape circle2;
|
||||
circle2.m_radius = 2.0f;
|
||||
|
||||
b2BodyDef bd1;
|
||||
bd1.type = b2_staticBody;
|
||||
bd1.position.Set(10.0f, 9.0f);
|
||||
b2Body* body1 = m_world->CreateBody(&bd1);
|
||||
body1->CreateFixture(&circle1, 5.0f);
|
||||
|
||||
b2BodyDef bd2;
|
||||
bd2.type = b2_dynamicBody;
|
||||
bd2.position.Set(10.0f, 8.0f);
|
||||
b2Body* body2 = m_world->CreateBody(&bd2);
|
||||
body2->CreateFixture(&box, 5.0f);
|
||||
|
||||
b2BodyDef bd3;
|
||||
bd3.type = b2_dynamicBody;
|
||||
bd3.position.Set(10.0f, 6.0f);
|
||||
b2Body* body3 = m_world->CreateBody(&bd3);
|
||||
body3->CreateFixture(&circle2, 5.0f);
|
||||
|
||||
b2RevoluteJointDef jd1;
|
||||
jd1.Initialize(body2, body1, bd1.position);
|
||||
b2Joint* joint1 = m_world->CreateJoint(&jd1);
|
||||
|
||||
b2RevoluteJointDef jd2;
|
||||
jd2.Initialize(body2, body3, bd3.position);
|
||||
b2Joint* joint2 = m_world->CreateJoint(&jd2);
|
||||
|
||||
b2GearJointDef jd4;
|
||||
jd4.bodyA = body1;
|
||||
jd4.bodyB = body3;
|
||||
jd4.joint1 = joint1;
|
||||
jd4.joint2 = joint2;
|
||||
jd4.ratio = circle2.m_radius / circle1.m_radius;
|
||||
m_world->CreateJoint(&jd4);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape circle1;
|
||||
circle1.m_radius = 1.0f;
|
||||
|
||||
b2CircleShape circle2;
|
||||
circle2.m_radius = 2.0f;
|
||||
|
||||
b2PolygonShape box;
|
||||
box.SetAsBox(0.5f, 5.0f);
|
||||
|
||||
b2BodyDef bd1;
|
||||
bd1.type = b2_dynamicBody;
|
||||
bd1.position.Set(-3.0f, 12.0f);
|
||||
b2Body* body1 = m_world->CreateBody(&bd1);
|
||||
body1->CreateFixture(&circle1, 5.0f);
|
||||
|
||||
b2RevoluteJointDef jd1;
|
||||
jd1.bodyA = ground;
|
||||
jd1.bodyB = body1;
|
||||
jd1.localAnchorA = ground->GetLocalPoint(bd1.position);
|
||||
jd1.localAnchorB = body1->GetLocalPoint(bd1.position);
|
||||
jd1.referenceAngle = body1->GetAngle() - ground->GetAngle();
|
||||
m_joint1 = (b2RevoluteJoint*)m_world->CreateJoint(&jd1);
|
||||
|
||||
b2BodyDef bd2;
|
||||
bd2.type = b2_dynamicBody;
|
||||
bd2.position.Set(0.0f, 12.0f);
|
||||
b2Body* body2 = m_world->CreateBody(&bd2);
|
||||
body2->CreateFixture(&circle2, 5.0f);
|
||||
|
||||
b2RevoluteJointDef jd2;
|
||||
jd2.Initialize(ground, body2, bd2.position);
|
||||
m_joint2 = (b2RevoluteJoint*)m_world->CreateJoint(&jd2);
|
||||
|
||||
b2BodyDef bd3;
|
||||
bd3.type = b2_dynamicBody;
|
||||
bd3.position.Set(2.5f, 12.0f);
|
||||
b2Body* body3 = m_world->CreateBody(&bd3);
|
||||
body3->CreateFixture(&box, 5.0f);
|
||||
|
||||
b2PrismaticJointDef jd3;
|
||||
jd3.Initialize(ground, body3, bd3.position, b2Vec2(0.0f, 1.0f));
|
||||
jd3.lowerTranslation = -5.0f;
|
||||
jd3.upperTranslation = 5.0f;
|
||||
jd3.enableLimit = true;
|
||||
|
||||
m_joint3 = (b2PrismaticJoint*)m_world->CreateJoint(&jd3);
|
||||
|
||||
b2GearJointDef jd4;
|
||||
jd4.bodyA = body1;
|
||||
jd4.bodyB = body2;
|
||||
jd4.joint1 = m_joint1;
|
||||
jd4.joint2 = m_joint2;
|
||||
jd4.ratio = circle2.m_radius / circle1.m_radius;
|
||||
m_joint4 = (b2GearJoint*)m_world->CreateJoint(&jd4);
|
||||
|
||||
b2GearJointDef jd5;
|
||||
jd5.bodyA = body2;
|
||||
jd5.bodyB = body3;
|
||||
jd5.joint1 = m_joint2;
|
||||
jd5.joint2 = m_joint3;
|
||||
jd5.ratio = -1.0f / circle2.m_radius;
|
||||
m_joint5 = (b2GearJoint*)m_world->CreateJoint(&jd5);
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
float32 ratio, value;
|
||||
|
||||
ratio = m_joint4->GetRatio();
|
||||
value = m_joint1->GetJointAngle() + ratio * m_joint2->GetJointAngle();
|
||||
g_debugDraw.DrawString(5, m_textLine, "theta1 + %4.2f * theta2 = %4.2f", (float) ratio, (float) value);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
ratio = m_joint5->GetRatio();
|
||||
value = m_joint2->GetJointAngle() + ratio * m_joint3->GetJointTranslation();
|
||||
g_debugDraw.DrawString(5, m_textLine, "theta2 + %4.2f * delta = %4.2f", (float) ratio, (float) value);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Gears;
|
||||
}
|
||||
|
||||
b2RevoluteJoint* m_joint1;
|
||||
b2RevoluteJoint* m_joint2;
|
||||
b2PrismaticJoint* m_joint3;
|
||||
b2GearJoint* m_joint4;
|
||||
b2GearJoint* m_joint5;
|
||||
};
|
||||
|
||||
#endif
|
||||
58
external/Box2D-2.3.1/Box2D/Testbed/Tests/HeavyOnLight.h
vendored
Normal file
58
external/Box2D-2.3.1/Box2D/Testbed/Tests/HeavyOnLight.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 HEAVY_ON_LIGHT_H
|
||||
#define HEAVY_ON_LIGHT_H
|
||||
|
||||
class HeavyOnLight : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
HeavyOnLight()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 0.5f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
body->CreateFixture(&shape, 10.0f);
|
||||
|
||||
bd.position.Set(0.0f, 6.0f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
shape.m_radius = 5.0f;
|
||||
body->CreateFixture(&shape, 10.0f);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new HeavyOnLight;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
91
external/Box2D-2.3.1/Box2D/Testbed/Tests/HeavyOnLightTwo.h
vendored
Normal file
91
external/Box2D-2.3.1/Box2D/Testbed/Tests/HeavyOnLightTwo.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 HEAVY_ON_LIGHT_TWO_H
|
||||
#define HEAVY_ON_LIGHT_TWO_H
|
||||
|
||||
class HeavyOnLightTwo : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
HeavyOnLightTwo()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 2.5f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
body->CreateFixture(&shape, 10.0f);
|
||||
|
||||
bd.position.Set(0.0f, 3.5f);
|
||||
body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 10.0f);
|
||||
|
||||
m_heavy = NULL;
|
||||
}
|
||||
|
||||
void ToggleHeavy()
|
||||
{
|
||||
if (m_heavy)
|
||||
{
|
||||
m_world->DestroyBody(m_heavy);
|
||||
m_heavy = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 9.0f);
|
||||
m_heavy = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 5.0f;
|
||||
m_heavy->CreateFixture(&shape, 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_H:
|
||||
ToggleHeavy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new HeavyOnLightTwo;
|
||||
}
|
||||
|
||||
b2Body* m_heavy;
|
||||
};
|
||||
|
||||
#endif
|
||||
102
external/Box2D-2.3.1/Box2D/Testbed/Tests/Mobile.h
vendored
Normal file
102
external/Box2D-2.3.1/Box2D/Testbed/Tests/Mobile.h
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 MOBILE_H
|
||||
#define MOBILE_H
|
||||
|
||||
class Mobile : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_depth = 4
|
||||
};
|
||||
|
||||
Mobile()
|
||||
{
|
||||
b2Body* ground;
|
||||
|
||||
// Create ground body.
|
||||
{
|
||||
b2BodyDef bodyDef;
|
||||
bodyDef.position.Set(0.0f, 20.0f);
|
||||
ground = m_world->CreateBody(&bodyDef);
|
||||
}
|
||||
|
||||
float32 a = 0.5f;
|
||||
b2Vec2 h(0.0f, a);
|
||||
|
||||
b2Body* root = AddNode(ground, b2Vec2_zero, 0, 3.0f, a);
|
||||
|
||||
b2RevoluteJointDef jointDef;
|
||||
jointDef.bodyA = ground;
|
||||
jointDef.bodyB = root;
|
||||
jointDef.localAnchorA.SetZero();
|
||||
jointDef.localAnchorB = h;
|
||||
m_world->CreateJoint(&jointDef);
|
||||
}
|
||||
|
||||
b2Body* AddNode(b2Body* parent, const b2Vec2& localAnchor, int32 depth, float32 offset, float32 a)
|
||||
{
|
||||
float32 density = 20.0f;
|
||||
b2Vec2 h(0.0f, a);
|
||||
|
||||
b2Vec2 p = parent->GetPosition() + localAnchor - h;
|
||||
|
||||
b2BodyDef bodyDef;
|
||||
bodyDef.type = b2_dynamicBody;
|
||||
bodyDef.position = p;
|
||||
b2Body* body = m_world->CreateBody(&bodyDef);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f * a, a);
|
||||
body->CreateFixture(&shape, density);
|
||||
|
||||
if (depth == e_depth)
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
b2Vec2 a1 = b2Vec2(offset, -a);
|
||||
b2Vec2 a2 = b2Vec2(-offset, -a);
|
||||
b2Body* body1 = AddNode(body, a1, depth + 1, 0.5f * offset, a);
|
||||
b2Body* body2 = AddNode(body, a2, depth + 1, 0.5f * offset, a);
|
||||
|
||||
b2RevoluteJointDef jointDef;
|
||||
jointDef.bodyA = body;
|
||||
jointDef.localAnchorB = h;
|
||||
|
||||
jointDef.localAnchorA = a1;
|
||||
jointDef.bodyB = body1;
|
||||
m_world->CreateJoint(&jointDef);
|
||||
|
||||
jointDef.localAnchorA = a2;
|
||||
jointDef.bodyB = body2;
|
||||
m_world->CreateJoint(&jointDef);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Mobile;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
105
external/Box2D-2.3.1/Box2D/Testbed/Tests/MobileBalanced.h
vendored
Normal file
105
external/Box2D-2.3.1/Box2D/Testbed/Tests/MobileBalanced.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 MOBILE_BALANCED_H
|
||||
#define MOBILE_BALANCED_H
|
||||
|
||||
class MobileBalanced : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_depth = 4
|
||||
};
|
||||
|
||||
MobileBalanced()
|
||||
{
|
||||
b2Body* ground;
|
||||
|
||||
// Create ground body.
|
||||
{
|
||||
b2BodyDef bodyDef;
|
||||
bodyDef.position.Set(0.0f, 20.0f);
|
||||
ground = m_world->CreateBody(&bodyDef);
|
||||
}
|
||||
|
||||
float32 a = 0.5f;
|
||||
b2Vec2 h(0.0f, a);
|
||||
|
||||
b2Body* root = AddNode(ground, b2Vec2_zero, 0, 3.0f, a);
|
||||
|
||||
b2RevoluteJointDef jointDef;
|
||||
jointDef.bodyA = ground;
|
||||
jointDef.bodyB = root;
|
||||
jointDef.localAnchorA.SetZero();
|
||||
jointDef.localAnchorB = h;
|
||||
m_world->CreateJoint(&jointDef);
|
||||
}
|
||||
|
||||
b2Body* AddNode(b2Body* parent, const b2Vec2& localAnchor, int32 depth, float32 offset, float32 a)
|
||||
{
|
||||
float32 density = 20.0f;
|
||||
b2Vec2 h(0.0f, a);
|
||||
|
||||
b2Vec2 p = parent->GetPosition() + localAnchor - h;
|
||||
|
||||
b2BodyDef bodyDef;
|
||||
bodyDef.type = b2_dynamicBody;
|
||||
bodyDef.position = p;
|
||||
b2Body* body = m_world->CreateBody(&bodyDef);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f * a, a);
|
||||
body->CreateFixture(&shape, density);
|
||||
|
||||
if (depth == e_depth)
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
shape.SetAsBox(offset, 0.25f * a, b2Vec2(0, -a), 0.0f);
|
||||
body->CreateFixture(&shape, density);
|
||||
|
||||
b2Vec2 a1 = b2Vec2(offset, -a);
|
||||
b2Vec2 a2 = b2Vec2(-offset, -a);
|
||||
b2Body* body1 = AddNode(body, a1, depth + 1, 0.5f * offset, a);
|
||||
b2Body* body2 = AddNode(body, a2, depth + 1, 0.5f * offset, a);
|
||||
|
||||
b2RevoluteJointDef jointDef;
|
||||
jointDef.bodyA = body;
|
||||
jointDef.localAnchorB = h;
|
||||
|
||||
jointDef.localAnchorA = a1;
|
||||
jointDef.bodyB = body1;
|
||||
m_world->CreateJoint(&jointDef);
|
||||
|
||||
jointDef.localAnchorA = a2;
|
||||
jointDef.bodyB = body2;
|
||||
m_world->CreateJoint(&jointDef);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new MobileBalanced;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
114
external/Box2D-2.3.1/Box2D/Testbed/Tests/MotorJoint.h
vendored
Normal file
114
external/Box2D-2.3.1/Box2D/Testbed/Tests/MotorJoint.h
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2012 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 MOTOR_JOINT_H
|
||||
#define MOTOR_JOINT_H
|
||||
|
||||
/// This test shows how to use a motor joint. A motor joint
|
||||
/// can be used to animate a dynamic body. With finite motor forces
|
||||
/// the body can be blocked by collision with other bodies.
|
||||
class MotorJoint : public Test
|
||||
{
|
||||
public:
|
||||
MotorJoint()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
|
||||
ground->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Define motorized body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 8.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(2.0f, 0.5f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.friction = 0.6f;
|
||||
fd.density = 2.0f;
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2MotorJointDef mjd;
|
||||
mjd.Initialize(ground, body);
|
||||
mjd.maxForce = 1000.0f;
|
||||
mjd.maxTorque = 1000.0f;
|
||||
m_joint = (b2MotorJoint*)m_world->CreateJoint(&mjd);
|
||||
}
|
||||
|
||||
m_go = false;
|
||||
m_time = 0.0f;
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_S:
|
||||
m_go = !m_go;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
if (m_go && settings->hz > 0.0f)
|
||||
{
|
||||
m_time += 1.0f / settings->hz;
|
||||
}
|
||||
|
||||
b2Vec2 linearOffset;
|
||||
linearOffset.x = 6.0f * sinf(2.0f * m_time);
|
||||
linearOffset.y = 8.0f + 4.0f * sinf(1.0f * m_time);
|
||||
|
||||
float32 angularOffset = 4.0f * m_time;
|
||||
|
||||
m_joint->SetLinearOffset(linearOffset);
|
||||
m_joint->SetAngularOffset(angularOffset);
|
||||
|
||||
g_debugDraw.DrawPoint(linearOffset, 4.0f, b2Color(0.9f, 0.9f, 0.9f));
|
||||
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: (s) pause");
|
||||
m_textLine += 15;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new MotorJoint;
|
||||
}
|
||||
|
||||
b2MotorJoint* m_joint;
|
||||
float32 m_time;
|
||||
bool m_go;
|
||||
};
|
||||
|
||||
#endif
|
||||
132
external/Box2D-2.3.1/Box2D/Testbed/Tests/OneSidedPlatform.h
vendored
Normal file
132
external/Box2D-2.3.1/Box2D/Testbed/Tests/OneSidedPlatform.h
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 ONE_SIDED_PLATFORM_H
|
||||
#define ONE_SIDED_PLATFORM_H
|
||||
|
||||
class OneSidedPlatform : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum State
|
||||
{
|
||||
e_unknown,
|
||||
e_above,
|
||||
e_below
|
||||
};
|
||||
|
||||
OneSidedPlatform()
|
||||
{
|
||||
// Ground
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Platform
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(0.0f, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(3.0f, 0.5f);
|
||||
m_platform = body->CreateFixture(&shape, 0.0f);
|
||||
|
||||
m_bottom = 10.0f - 0.5f;
|
||||
m_top = 10.0f + 0.5f;
|
||||
}
|
||||
|
||||
// Actor
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 12.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
m_radius = 0.5f;
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = m_radius;
|
||||
m_character = body->CreateFixture(&shape, 20.0f);
|
||||
|
||||
body->SetLinearVelocity(b2Vec2(0.0f, -50.0f));
|
||||
|
||||
m_state = e_unknown;
|
||||
}
|
||||
}
|
||||
|
||||
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
|
||||
{
|
||||
Test::PreSolve(contact, oldManifold);
|
||||
|
||||
b2Fixture* fixtureA = contact->GetFixtureA();
|
||||
b2Fixture* fixtureB = contact->GetFixtureB();
|
||||
|
||||
if (fixtureA != m_platform && fixtureA != m_character)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (fixtureB != m_platform && fixtureB != m_character)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1
|
||||
b2Vec2 position = m_character->GetBody()->GetPosition();
|
||||
|
||||
if (position.y < m_top + m_radius - 3.0f * b2_linearSlop)
|
||||
{
|
||||
contact->SetEnabled(false);
|
||||
}
|
||||
#else
|
||||
b2Vec2 v = m_character->GetBody()->GetLinearVelocity();
|
||||
if (v.y > 0.0f)
|
||||
{
|
||||
contact->SetEnabled(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press: (c) create a shape, (d) destroy a shape.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
b2Vec2 v = m_character->GetBody()->GetLinearVelocity();
|
||||
g_debugDraw.DrawString(5, m_textLine, "Character Linear Velocity: %f", v.y);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new OneSidedPlatform;
|
||||
}
|
||||
|
||||
float32 m_radius, m_top, m_bottom;
|
||||
State m_state;
|
||||
b2Fixture* m_platform;
|
||||
b2Fixture* m_character;
|
||||
};
|
||||
|
||||
#endif
|
||||
167
external/Box2D-2.3.1/Box2D/Testbed/Tests/Pinball.h
vendored
Normal file
167
external/Box2D-2.3.1/Box2D/Testbed/Tests/Pinball.h
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 PINBALL_H
|
||||
#define PINBALL_H
|
||||
|
||||
/// This tests bullet collision and provides an example of a gameplay scenario.
|
||||
/// This also uses a loop shape.
|
||||
class Pinball : public Test
|
||||
{
|
||||
public:
|
||||
Pinball()
|
||||
{
|
||||
// Ground body
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2Vec2 vs[5];
|
||||
vs[0].Set(0.0f, -2.0f);
|
||||
vs[1].Set(8.0f, 6.0f);
|
||||
vs[2].Set(8.0f, 20.0f);
|
||||
vs[3].Set(-8.0f, 20.0f);
|
||||
vs[4].Set(-8.0f, 6.0f);
|
||||
|
||||
b2ChainShape loop;
|
||||
loop.CreateLoop(vs, 5);
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &loop;
|
||||
fd.density = 0.0f;
|
||||
ground->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
// Flippers
|
||||
{
|
||||
b2Vec2 p1(-2.0f, 0.0f), p2(2.0f, 0.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
bd.position = p1;
|
||||
b2Body* leftFlipper = m_world->CreateBody(&bd);
|
||||
|
||||
bd.position = p2;
|
||||
b2Body* rightFlipper = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape box;
|
||||
box.SetAsBox(1.75f, 0.1f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &box;
|
||||
fd.density = 1.0f;
|
||||
|
||||
leftFlipper->CreateFixture(&fd);
|
||||
rightFlipper->CreateFixture(&fd);
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
jd.bodyA = ground;
|
||||
jd.localAnchorB.SetZero();
|
||||
jd.enableMotor = true;
|
||||
jd.maxMotorTorque = 1000.0f;
|
||||
jd.enableLimit = true;
|
||||
|
||||
jd.motorSpeed = 0.0f;
|
||||
jd.localAnchorA = p1;
|
||||
jd.bodyB = leftFlipper;
|
||||
jd.lowerAngle = -30.0f * b2_pi / 180.0f;
|
||||
jd.upperAngle = 5.0f * b2_pi / 180.0f;
|
||||
m_leftJoint = (b2RevoluteJoint*)m_world->CreateJoint(&jd);
|
||||
|
||||
jd.motorSpeed = 0.0f;
|
||||
jd.localAnchorA = p2;
|
||||
jd.bodyB = rightFlipper;
|
||||
jd.lowerAngle = -5.0f * b2_pi / 180.0f;
|
||||
jd.upperAngle = 30.0f * b2_pi / 180.0f;
|
||||
m_rightJoint = (b2RevoluteJoint*)m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
// Circle character
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(1.0f, 15.0f);
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.bullet = true;
|
||||
|
||||
m_ball = m_world->CreateBody(&bd);
|
||||
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.2f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
m_ball->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
m_button = false;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
if (m_button)
|
||||
{
|
||||
m_leftJoint->SetMotorSpeed(20.0f);
|
||||
m_rightJoint->SetMotorSpeed(-20.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_leftJoint->SetMotorSpeed(-10.0f);
|
||||
m_rightJoint->SetMotorSpeed(10.0f);
|
||||
}
|
||||
|
||||
Test::Step(settings);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 'a' to control the flippers");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_button = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardUp(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_button = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Pinball;
|
||||
}
|
||||
|
||||
b2RevoluteJoint* m_leftJoint;
|
||||
b2RevoluteJoint* m_rightJoint;
|
||||
b2Body* m_ball;
|
||||
bool m_button;
|
||||
};
|
||||
|
||||
#endif
|
||||
122
external/Box2D-2.3.1/Box2D/Testbed/Tests/PolyCollision.h
vendored
Normal file
122
external/Box2D-2.3.1/Box2D/Testbed/Tests/PolyCollision.h
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 POLYCOLLISION_H
|
||||
#define POLYCOLLISION_H
|
||||
|
||||
class PolyCollision : public Test
|
||||
{
|
||||
public:
|
||||
PolyCollision()
|
||||
{
|
||||
{
|
||||
m_polygonA.SetAsBox(0.2f, 0.4f);
|
||||
m_transformA.Set(b2Vec2(0.0f, 0.0f), 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
m_polygonB.SetAsBox(0.5f, 0.5f);
|
||||
m_positionB.Set(19.345284f, 1.5632932f);
|
||||
m_angleB = 1.9160721f;
|
||||
m_transformB.Set(m_positionB, m_angleB);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new PolyCollision;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
B2_NOT_USED(settings);
|
||||
|
||||
b2Manifold manifold;
|
||||
b2CollidePolygons(&manifold, &m_polygonA, m_transformA, &m_polygonB, m_transformB);
|
||||
|
||||
b2WorldManifold worldManifold;
|
||||
worldManifold.Initialize(&manifold, m_transformA, m_polygonA.m_radius, m_transformB, m_polygonB.m_radius);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "point count = %d", manifold.pointCount);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
{
|
||||
b2Color color(0.9f, 0.9f, 0.9f);
|
||||
b2Vec2 v[b2_maxPolygonVertices];
|
||||
for (int32 i = 0; i < m_polygonA.m_count; ++i)
|
||||
{
|
||||
v[i] = b2Mul(m_transformA, m_polygonA.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(v, m_polygonA.m_count, color);
|
||||
|
||||
for (int32 i = 0; i < m_polygonB.m_count; ++i)
|
||||
{
|
||||
v[i] = b2Mul(m_transformB, m_polygonB.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(v, m_polygonB.m_count, color);
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < manifold.pointCount; ++i)
|
||||
{
|
||||
g_debugDraw.DrawPoint(worldManifold.points[i], 4.0f, b2Color(0.9f, 0.3f, 0.3f));
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_positionB.x -= 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
m_positionB.x += 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
m_positionB.y -= 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_W:
|
||||
m_positionB.y += 0.1f;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_Q:
|
||||
m_angleB += 0.1f * b2_pi;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_E:
|
||||
m_angleB -= 0.1f * b2_pi;
|
||||
break;
|
||||
}
|
||||
|
||||
m_transformB.Set(m_positionB, m_angleB);
|
||||
}
|
||||
|
||||
b2PolygonShape m_polygonA;
|
||||
b2PolygonShape m_polygonB;
|
||||
|
||||
b2Transform m_transformA;
|
||||
b2Transform m_transformB;
|
||||
|
||||
b2Vec2 m_positionB;
|
||||
float32 m_angleB;
|
||||
};
|
||||
|
||||
#endif
|
||||
299
external/Box2D-2.3.1/Box2D/Testbed/Tests/PolyShapes.h
vendored
Normal file
299
external/Box2D-2.3.1/Box2D/Testbed/Tests/PolyShapes.h
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 POLY_SHAPES_H
|
||||
#define POLY_SHAPES_H
|
||||
|
||||
/// This tests stacking. It also shows how to use b2World::Query
|
||||
/// and b2TestOverlap.
|
||||
|
||||
/// This callback is called by b2World::QueryAABB. We find all the fixtures
|
||||
/// that overlap an AABB. Of those, we use b2TestOverlap to determine which fixtures
|
||||
/// overlap a circle. Up to 4 overlapped fixtures will be highlighted with a yellow border.
|
||||
class PolyShapesCallback : public b2QueryCallback
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_maxCount = 4
|
||||
};
|
||||
|
||||
PolyShapesCallback()
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
void DrawFixture(b2Fixture* fixture)
|
||||
{
|
||||
b2Color color(0.95f, 0.95f, 0.6f);
|
||||
const b2Transform& xf = fixture->GetBody()->GetTransform();
|
||||
|
||||
switch (fixture->GetType())
|
||||
{
|
||||
case b2Shape::e_circle:
|
||||
{
|
||||
b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
|
||||
|
||||
b2Vec2 center = b2Mul(xf, circle->m_p);
|
||||
float32 radius = circle->m_radius;
|
||||
|
||||
g_debugDraw->DrawCircle(center, radius, color);
|
||||
}
|
||||
break;
|
||||
|
||||
case b2Shape::e_polygon:
|
||||
{
|
||||
b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
|
||||
int32 vertexCount = poly->m_count;
|
||||
b2Assert(vertexCount <= b2_maxPolygonVertices);
|
||||
b2Vec2 vertices[b2_maxPolygonVertices];
|
||||
|
||||
for (int32 i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
vertices[i] = b2Mul(xf, poly->m_vertices[i]);
|
||||
}
|
||||
|
||||
g_debugDraw->DrawPolygon(vertices, vertexCount, color);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Called for each fixture found in the query AABB.
|
||||
/// @return false to terminate the query.
|
||||
bool ReportFixture(b2Fixture* fixture)
|
||||
{
|
||||
if (m_count == e_maxCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
b2Body* body = fixture->GetBody();
|
||||
b2Shape* shape = fixture->GetShape();
|
||||
|
||||
bool overlap = b2TestOverlap(shape, 0, &m_circle, 0, body->GetTransform(), m_transform);
|
||||
|
||||
if (overlap)
|
||||
{
|
||||
DrawFixture(fixture);
|
||||
++m_count;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
b2CircleShape m_circle;
|
||||
b2Transform m_transform;
|
||||
b2Draw* g_debugDraw;
|
||||
int32 m_count;
|
||||
};
|
||||
|
||||
class PolyShapes : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_maxBodies = 256
|
||||
};
|
||||
|
||||
PolyShapes()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.5f, 0.0f);
|
||||
vertices[1].Set(0.5f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
m_polygons[0].Set(vertices, 3);
|
||||
}
|
||||
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.1f, 0.0f);
|
||||
vertices[1].Set(0.1f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
m_polygons[1].Set(vertices, 3);
|
||||
}
|
||||
|
||||
{
|
||||
float32 w = 1.0f;
|
||||
float32 b = w / (2.0f + b2Sqrt(2.0f));
|
||||
float32 s = b2Sqrt(2.0f) * b;
|
||||
|
||||
b2Vec2 vertices[8];
|
||||
vertices[0].Set(0.5f * s, 0.0f);
|
||||
vertices[1].Set(0.5f * w, b);
|
||||
vertices[2].Set(0.5f * w, b + s);
|
||||
vertices[3].Set(0.5f * s, w);
|
||||
vertices[4].Set(-0.5f * s, w);
|
||||
vertices[5].Set(-0.5f * w, b + s);
|
||||
vertices[6].Set(-0.5f * w, b);
|
||||
vertices[7].Set(-0.5f * s, 0.0f);
|
||||
|
||||
m_polygons[2].Set(vertices, 8);
|
||||
}
|
||||
|
||||
{
|
||||
m_polygons[3].SetAsBox(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
{
|
||||
m_circle.m_radius = 0.5f;
|
||||
}
|
||||
|
||||
m_bodyIndex = 0;
|
||||
memset(m_bodies, 0, sizeof(m_bodies));
|
||||
}
|
||||
|
||||
void Create(int32 index)
|
||||
{
|
||||
if (m_bodies[m_bodyIndex] != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[m_bodyIndex]);
|
||||
m_bodies[m_bodyIndex] = NULL;
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
float32 x = RandomFloat(-2.0f, 2.0f);
|
||||
bd.position.Set(x, 10.0f);
|
||||
bd.angle = RandomFloat(-b2_pi, b2_pi);
|
||||
|
||||
if (index == 4)
|
||||
{
|
||||
bd.angularDamping = 0.02f;
|
||||
}
|
||||
|
||||
m_bodies[m_bodyIndex] = m_world->CreateBody(&bd);
|
||||
|
||||
if (index < 4)
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = m_polygons + index;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.3f;
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &m_circle;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.3f;
|
||||
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
m_bodyIndex = (m_bodyIndex + 1) % e_maxBodies;
|
||||
}
|
||||
|
||||
void DestroyBody()
|
||||
{
|
||||
for (int32 i = 0; i < e_maxBodies; ++i)
|
||||
{
|
||||
if (m_bodies[i] != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[i]);
|
||||
m_bodies[i] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_1:
|
||||
case GLFW_KEY_2:
|
||||
case GLFW_KEY_3:
|
||||
case GLFW_KEY_4:
|
||||
case GLFW_KEY_5:
|
||||
Create(key - GLFW_KEY_1);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_A:
|
||||
for (int32 i = 0; i < e_maxBodies; i += 2)
|
||||
{
|
||||
if (m_bodies[i])
|
||||
{
|
||||
bool active = m_bodies[i]->IsActive();
|
||||
m_bodies[i]->SetActive(!active);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
DestroyBody();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
PolyShapesCallback callback;
|
||||
callback.m_circle.m_radius = 2.0f;
|
||||
callback.m_circle.m_p.Set(0.0f, 1.1f);
|
||||
callback.m_transform.SetIdentity();
|
||||
callback.g_debugDraw = &g_debugDraw;
|
||||
|
||||
b2AABB aabb;
|
||||
callback.m_circle.ComputeAABB(&aabb, callback.m_transform, 0);
|
||||
|
||||
m_world->QueryAABB(&callback, aabb);
|
||||
|
||||
b2Color color(0.4f, 0.7f, 0.8f);
|
||||
g_debugDraw.DrawCircle(callback.m_circle.m_p, callback.m_circle.m_radius, color);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 1-5 to drop stuff");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 'a' to (de)activate some bodies");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 'd' to destroy a body");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new PolyShapes;
|
||||
}
|
||||
|
||||
int32 m_bodyIndex;
|
||||
b2Body* m_bodies[e_maxBodies];
|
||||
b2PolygonShape m_polygons[4];
|
||||
b2CircleShape m_circle;
|
||||
};
|
||||
|
||||
#endif
|
||||
107
external/Box2D-2.3.1/Box2D/Testbed/Tests/Prismatic.h
vendored
Normal file
107
external/Box2D-2.3.1/Box2D/Testbed/Tests/Prismatic.h
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 PRISMATIC_H
|
||||
#define PRISMATIC_H
|
||||
|
||||
// The motor in this test gets smoother with higher velocity iterations.
|
||||
class Prismatic : public Test
|
||||
{
|
||||
public:
|
||||
Prismatic()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(2.0f, 0.5f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-10.0f, 10.0f);
|
||||
bd.angle = 0.5f * b2_pi;
|
||||
bd.allowSleep = false;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
|
||||
b2PrismaticJointDef pjd;
|
||||
|
||||
// Bouncy limit
|
||||
b2Vec2 axis(2.0f, 1.0f);
|
||||
axis.Normalize();
|
||||
pjd.Initialize(ground, body, b2Vec2(0.0f, 0.0f), axis);
|
||||
|
||||
// Non-bouncy limit
|
||||
//pjd.Initialize(ground, body, b2Vec2(-10.0f, 10.0f), b2Vec2(1.0f, 0.0f));
|
||||
|
||||
pjd.motorSpeed = 10.0f;
|
||||
pjd.maxMotorForce = 10000.0f;
|
||||
pjd.enableMotor = true;
|
||||
pjd.lowerTranslation = 0.0f;
|
||||
pjd.upperTranslation = 20.0f;
|
||||
pjd.enableLimit = true;
|
||||
|
||||
m_joint = (b2PrismaticJoint*)m_world->CreateJoint(&pjd);
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_L:
|
||||
m_joint->EnableLimit(!m_joint->IsLimitEnabled());
|
||||
break;
|
||||
|
||||
case GLFW_KEY_M:
|
||||
m_joint->EnableMotor(!m_joint->IsMotorEnabled());
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
m_joint->SetMotorSpeed(-m_joint->GetMotorSpeed());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: (l) limits, (m) motors, (s) speed");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
float32 force = m_joint->GetMotorForce(settings->hz);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Motor Force = %4.0f", (float) force);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Prismatic;
|
||||
}
|
||||
|
||||
b2PrismaticJoint* m_joint;
|
||||
};
|
||||
|
||||
#endif
|
||||
97
external/Box2D-2.3.1/Box2D/Testbed/Tests/Pulleys.h
vendored
Normal file
97
external/Box2D-2.3.1/Box2D/Testbed/Tests/Pulleys.h
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 PULLEYS_H
|
||||
#define PULLEYS_H
|
||||
|
||||
class Pulleys : public Test
|
||||
{
|
||||
public:
|
||||
Pulleys()
|
||||
{
|
||||
float32 y = 16.0f;
|
||||
float32 L = 12.0f;
|
||||
float32 a = 1.0f;
|
||||
float32 b = 2.0f;
|
||||
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape edge;
|
||||
edge.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
//ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
b2CircleShape circle;
|
||||
circle.m_radius = 2.0f;
|
||||
|
||||
circle.m_p.Set(-10.0f, y + b + L);
|
||||
ground->CreateFixture(&circle, 0.0f);
|
||||
|
||||
circle.m_p.Set(10.0f, y + b + L);
|
||||
ground->CreateFixture(&circle, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(a, b);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
//bd.fixedRotation = true;
|
||||
bd.position.Set(-10.0f, y);
|
||||
b2Body* body1 = m_world->CreateBody(&bd);
|
||||
body1->CreateFixture(&shape, 5.0f);
|
||||
|
||||
bd.position.Set(10.0f, y);
|
||||
b2Body* body2 = m_world->CreateBody(&bd);
|
||||
body2->CreateFixture(&shape, 5.0f);
|
||||
|
||||
b2PulleyJointDef pulleyDef;
|
||||
b2Vec2 anchor1(-10.0f, y + b);
|
||||
b2Vec2 anchor2(10.0f, y + b);
|
||||
b2Vec2 groundAnchor1(-10.0f, y + b + L);
|
||||
b2Vec2 groundAnchor2(10.0f, y + b + L);
|
||||
pulleyDef.Initialize(body1, body2, groundAnchor1, groundAnchor2, anchor1, anchor2, 1.5f);
|
||||
|
||||
m_joint1 = (b2PulleyJoint*)m_world->CreateJoint(&pulleyDef);
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
float32 ratio = m_joint1->GetRatio();
|
||||
float32 L = m_joint1->GetCurrentLengthA() + ratio * m_joint1->GetCurrentLengthB();
|
||||
g_debugDraw.DrawString(5, m_textLine, "L1 + %4.2f * L2 = %4.2f", (float) ratio, (float) L);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Pulleys;
|
||||
}
|
||||
|
||||
b2PulleyJoint* m_joint1;
|
||||
};
|
||||
|
||||
#endif
|
||||
89
external/Box2D-2.3.1/Box2D/Testbed/Tests/Pyramid.h
vendored
Normal file
89
external/Box2D-2.3.1/Box2D/Testbed/Tests/Pyramid.h
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 PYRAMID_H
|
||||
#define PYRAMID_H
|
||||
|
||||
class Pyramid : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_count = 20
|
||||
};
|
||||
|
||||
Pyramid()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
float32 a = 0.5f;
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(a, a);
|
||||
|
||||
b2Vec2 x(-7.0f, 0.75f);
|
||||
b2Vec2 y;
|
||||
b2Vec2 deltaX(0.5625f, 1.25f);
|
||||
b2Vec2 deltaY(1.125f, 0.0f);
|
||||
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
y = x;
|
||||
|
||||
for (int32 j = i; j < e_count; ++j)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = y;
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
|
||||
y += deltaY;
|
||||
}
|
||||
|
||||
x += deltaX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
//b2DynamicTree* tree = &m_world->m_contactManager.m_broadPhase.m_tree;
|
||||
|
||||
//if (m_stepCount == 400)
|
||||
//{
|
||||
// tree->RebuildBottomUp();
|
||||
//}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Pyramid;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
481
external/Box2D-2.3.1/Box2D/Testbed/Tests/RayCast.h
vendored
Normal file
481
external/Box2D-2.3.1/Box2D/Testbed/Tests/RayCast.h
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 RAY_CAST_H
|
||||
#define RAY_CAST_H
|
||||
|
||||
// This test demonstrates how to use the world ray-cast feature.
|
||||
// NOTE: we are intentionally filtering one of the polygons, therefore
|
||||
// the ray will always miss one type of polygon.
|
||||
|
||||
// This callback finds the closest hit. Polygon 0 is filtered.
|
||||
class RayCastClosestCallback : public b2RayCastCallback
|
||||
{
|
||||
public:
|
||||
RayCastClosestCallback()
|
||||
{
|
||||
m_hit = false;
|
||||
}
|
||||
|
||||
float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)
|
||||
{
|
||||
b2Body* body = fixture->GetBody();
|
||||
void* userData = body->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
int32 index = *(int32*)userData;
|
||||
if (index == 0)
|
||||
{
|
||||
// By returning -1, we instruct the calling code to ignore this fixture and
|
||||
// continue the ray-cast to the next fixture.
|
||||
return -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_hit = true;
|
||||
m_point = point;
|
||||
m_normal = normal;
|
||||
|
||||
// By returning the current fraction, we instruct the calling code to clip the ray and
|
||||
// continue the ray-cast to the next fixture. WARNING: do not assume that fixtures
|
||||
// are reported in order. However, by clipping, we can always get the closest fixture.
|
||||
return fraction;
|
||||
}
|
||||
|
||||
bool m_hit;
|
||||
b2Vec2 m_point;
|
||||
b2Vec2 m_normal;
|
||||
};
|
||||
|
||||
// This callback finds any hit. Polygon 0 is filtered. For this type of query we are usually
|
||||
// just checking for obstruction, so the actual fixture and hit point are irrelevant.
|
||||
class RayCastAnyCallback : public b2RayCastCallback
|
||||
{
|
||||
public:
|
||||
RayCastAnyCallback()
|
||||
{
|
||||
m_hit = false;
|
||||
}
|
||||
|
||||
float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)
|
||||
{
|
||||
b2Body* body = fixture->GetBody();
|
||||
void* userData = body->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
int32 index = *(int32*)userData;
|
||||
if (index == 0)
|
||||
{
|
||||
// By returning -1, we instruct the calling code to ignore this fixture
|
||||
// and continue the ray-cast to the next fixture.
|
||||
return -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_hit = true;
|
||||
m_point = point;
|
||||
m_normal = normal;
|
||||
|
||||
// At this point we have a hit, so we know the ray is obstructed.
|
||||
// By returning 0, we instruct the calling code to terminate the ray-cast.
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool m_hit;
|
||||
b2Vec2 m_point;
|
||||
b2Vec2 m_normal;
|
||||
};
|
||||
|
||||
// This ray cast collects multiple hits along the ray. Polygon 0 is filtered.
|
||||
// The fixtures are not necessary reported in order, so we might not capture
|
||||
// the closest fixture.
|
||||
class RayCastMultipleCallback : public b2RayCastCallback
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_maxCount = 3
|
||||
};
|
||||
|
||||
RayCastMultipleCallback()
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)
|
||||
{
|
||||
b2Body* body = fixture->GetBody();
|
||||
void* userData = body->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
int32 index = *(int32*)userData;
|
||||
if (index == 0)
|
||||
{
|
||||
// By returning -1, we instruct the calling code to ignore this fixture
|
||||
// and continue the ray-cast to the next fixture.
|
||||
return -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
b2Assert(m_count < e_maxCount);
|
||||
|
||||
m_points[m_count] = point;
|
||||
m_normals[m_count] = normal;
|
||||
++m_count;
|
||||
|
||||
if (m_count == e_maxCount)
|
||||
{
|
||||
// At this point the buffer is full.
|
||||
// By returning 0, we instruct the calling code to terminate the ray-cast.
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// By returning 1, we instruct the caller to continue without clipping the ray.
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
b2Vec2 m_points[e_maxCount];
|
||||
b2Vec2 m_normals[e_maxCount];
|
||||
int32 m_count;
|
||||
};
|
||||
|
||||
|
||||
class RayCast : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_maxBodies = 256
|
||||
};
|
||||
|
||||
enum Mode
|
||||
{
|
||||
e_closest,
|
||||
e_any,
|
||||
e_multiple
|
||||
};
|
||||
|
||||
RayCast()
|
||||
{
|
||||
// Ground body
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.5f, 0.0f);
|
||||
vertices[1].Set(0.5f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
m_polygons[0].Set(vertices, 3);
|
||||
}
|
||||
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
vertices[0].Set(-0.1f, 0.0f);
|
||||
vertices[1].Set(0.1f, 0.0f);
|
||||
vertices[2].Set(0.0f, 1.5f);
|
||||
m_polygons[1].Set(vertices, 3);
|
||||
}
|
||||
|
||||
{
|
||||
float32 w = 1.0f;
|
||||
float32 b = w / (2.0f + b2Sqrt(2.0f));
|
||||
float32 s = b2Sqrt(2.0f) * b;
|
||||
|
||||
b2Vec2 vertices[8];
|
||||
vertices[0].Set(0.5f * s, 0.0f);
|
||||
vertices[1].Set(0.5f * w, b);
|
||||
vertices[2].Set(0.5f * w, b + s);
|
||||
vertices[3].Set(0.5f * s, w);
|
||||
vertices[4].Set(-0.5f * s, w);
|
||||
vertices[5].Set(-0.5f * w, b + s);
|
||||
vertices[6].Set(-0.5f * w, b);
|
||||
vertices[7].Set(-0.5f * s, 0.0f);
|
||||
|
||||
m_polygons[2].Set(vertices, 8);
|
||||
}
|
||||
|
||||
{
|
||||
m_polygons[3].SetAsBox(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
{
|
||||
m_circle.m_radius = 0.5f;
|
||||
}
|
||||
|
||||
{
|
||||
m_edge.Set(b2Vec2(-1.0f, 0.0f), b2Vec2(1.0f, 0.0f));
|
||||
}
|
||||
|
||||
m_bodyIndex = 0;
|
||||
memset(m_bodies, 0, sizeof(m_bodies));
|
||||
|
||||
m_angle = 0.0f;
|
||||
|
||||
m_mode = e_closest;
|
||||
}
|
||||
|
||||
void Create(int32 index)
|
||||
{
|
||||
if (m_bodies[m_bodyIndex] != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[m_bodyIndex]);
|
||||
m_bodies[m_bodyIndex] = NULL;
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
|
||||
float32 x = RandomFloat(-10.0f, 10.0f);
|
||||
float32 y = RandomFloat(0.0f, 20.0f);
|
||||
bd.position.Set(x, y);
|
||||
bd.angle = RandomFloat(-b2_pi, b2_pi);
|
||||
|
||||
m_userData[m_bodyIndex] = index;
|
||||
bd.userData = m_userData + m_bodyIndex;
|
||||
|
||||
if (index == 4)
|
||||
{
|
||||
bd.angularDamping = 0.02f;
|
||||
}
|
||||
|
||||
m_bodies[m_bodyIndex] = m_world->CreateBody(&bd);
|
||||
|
||||
if (index < 4)
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = m_polygons + index;
|
||||
fd.friction = 0.3f;
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
else if (index < 5)
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &m_circle;
|
||||
fd.friction = 0.3f;
|
||||
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &m_edge;
|
||||
fd.friction = 0.3f;
|
||||
|
||||
m_bodies[m_bodyIndex]->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
m_bodyIndex = (m_bodyIndex + 1) % e_maxBodies;
|
||||
}
|
||||
|
||||
void DestroyBody()
|
||||
{
|
||||
for (int32 i = 0; i < e_maxBodies; ++i)
|
||||
{
|
||||
if (m_bodies[i] != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[i]);
|
||||
m_bodies[i] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_1:
|
||||
case GLFW_KEY_2:
|
||||
case GLFW_KEY_3:
|
||||
case GLFW_KEY_4:
|
||||
case GLFW_KEY_5:
|
||||
case GLFW_KEY_6:
|
||||
Create(key - GLFW_KEY_1);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
DestroyBody();
|
||||
break;
|
||||
|
||||
case GLFW_KEY_M:
|
||||
if (m_mode == e_closest)
|
||||
{
|
||||
m_mode = e_any;
|
||||
}
|
||||
else if (m_mode == e_any)
|
||||
{
|
||||
m_mode = e_multiple;
|
||||
}
|
||||
else if (m_mode == e_multiple)
|
||||
{
|
||||
m_mode = e_closest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
bool advanceRay = settings->pause == 0 || settings->singleStep;
|
||||
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press 1-6 to drop stuff, m to change the mode");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
switch (m_mode)
|
||||
{
|
||||
case e_closest:
|
||||
g_debugDraw.DrawString(5, m_textLine, "Ray-cast mode: closest - find closest fixture along the ray");
|
||||
break;
|
||||
|
||||
case e_any:
|
||||
g_debugDraw.DrawString(5, m_textLine, "Ray-cast mode: any - check for obstruction");
|
||||
break;
|
||||
|
||||
case e_multiple:
|
||||
g_debugDraw.DrawString(5, m_textLine, "Ray-cast mode: multiple - gather multiple fixtures");
|
||||
break;
|
||||
}
|
||||
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
float32 L = 11.0f;
|
||||
b2Vec2 point1(0.0f, 10.0f);
|
||||
b2Vec2 d(L * cosf(m_angle), L * sinf(m_angle));
|
||||
b2Vec2 point2 = point1 + d;
|
||||
|
||||
if (m_mode == e_closest)
|
||||
{
|
||||
RayCastClosestCallback callback;
|
||||
m_world->RayCast(&callback, point1, point2);
|
||||
|
||||
if (callback.m_hit)
|
||||
{
|
||||
g_debugDraw.DrawPoint(callback.m_point, 5.0f, b2Color(0.4f, 0.9f, 0.4f));
|
||||
g_debugDraw.DrawSegment(point1, callback.m_point, b2Color(0.8f, 0.8f, 0.8f));
|
||||
b2Vec2 head = callback.m_point + 0.5f * callback.m_normal;
|
||||
g_debugDraw.DrawSegment(callback.m_point, head, b2Color(0.9f, 0.9f, 0.4f));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debugDraw.DrawSegment(point1, point2, b2Color(0.8f, 0.8f, 0.8f));
|
||||
}
|
||||
}
|
||||
else if (m_mode == e_any)
|
||||
{
|
||||
RayCastAnyCallback callback;
|
||||
m_world->RayCast(&callback, point1, point2);
|
||||
|
||||
if (callback.m_hit)
|
||||
{
|
||||
g_debugDraw.DrawPoint(callback.m_point, 5.0f, b2Color(0.4f, 0.9f, 0.4f));
|
||||
g_debugDraw.DrawSegment(point1, callback.m_point, b2Color(0.8f, 0.8f, 0.8f));
|
||||
b2Vec2 head = callback.m_point + 0.5f * callback.m_normal;
|
||||
g_debugDraw.DrawSegment(callback.m_point, head, b2Color(0.9f, 0.9f, 0.4f));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debugDraw.DrawSegment(point1, point2, b2Color(0.8f, 0.8f, 0.8f));
|
||||
}
|
||||
}
|
||||
else if (m_mode == e_multiple)
|
||||
{
|
||||
RayCastMultipleCallback callback;
|
||||
m_world->RayCast(&callback, point1, point2);
|
||||
g_debugDraw.DrawSegment(point1, point2, b2Color(0.8f, 0.8f, 0.8f));
|
||||
|
||||
for (int32 i = 0; i < callback.m_count; ++i)
|
||||
{
|
||||
b2Vec2 p = callback.m_points[i];
|
||||
b2Vec2 n = callback.m_normals[i];
|
||||
g_debugDraw.DrawPoint(p, 5.0f, b2Color(0.4f, 0.9f, 0.4f));
|
||||
g_debugDraw.DrawSegment(point1, p, b2Color(0.8f, 0.8f, 0.8f));
|
||||
b2Vec2 head = p + 0.5f * n;
|
||||
g_debugDraw.DrawSegment(p, head, b2Color(0.9f, 0.9f, 0.4f));
|
||||
}
|
||||
}
|
||||
|
||||
if (advanceRay)
|
||||
{
|
||||
m_angle += 0.25f * b2_pi / 180.0f;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This case was failing.
|
||||
{
|
||||
b2Vec2 vertices[4];
|
||||
//vertices[0].Set(-22.875f, -3.0f);
|
||||
//vertices[1].Set(22.875f, -3.0f);
|
||||
//vertices[2].Set(22.875f, 3.0f);
|
||||
//vertices[3].Set(-22.875f, 3.0f);
|
||||
|
||||
b2PolygonShape shape;
|
||||
//shape.Set(vertices, 4);
|
||||
shape.SetAsBox(22.875f, 3.0f);
|
||||
|
||||
b2RayCastInput input;
|
||||
input.p1.Set(10.2725f,1.71372f);
|
||||
input.p2.Set(10.2353f,2.21807f);
|
||||
//input.maxFraction = 0.567623f;
|
||||
input.maxFraction = 0.56762173f;
|
||||
|
||||
b2Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.position.Set(23.0f, 5.0f);
|
||||
|
||||
b2RayCastOutput output;
|
||||
bool hit;
|
||||
hit = shape.RayCast(&output, input, xf);
|
||||
hit = false;
|
||||
|
||||
b2Color color(1.0f, 1.0f, 1.0f);
|
||||
b2Vec2 vs[4];
|
||||
for (int32 i = 0; i < 4; ++i)
|
||||
{
|
||||
vs[i] = b2Mul(xf, shape.m_vertices[i]);
|
||||
}
|
||||
|
||||
g_debugDraw.DrawPolygon(vs, 4, color);
|
||||
g_debugDraw.DrawSegment(input.p1, input.p2, color);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new RayCast;
|
||||
}
|
||||
|
||||
int32 m_bodyIndex;
|
||||
b2Body* m_bodies[e_maxBodies];
|
||||
int32 m_userData[e_maxBodies];
|
||||
b2PolygonShape m_polygons[4];
|
||||
b2CircleShape m_circle;
|
||||
b2EdgeShape m_edge;
|
||||
|
||||
float32 m_angle;
|
||||
|
||||
Mode m_mode;
|
||||
};
|
||||
|
||||
#endif
|
||||
166
external/Box2D-2.3.1/Box2D/Testbed/Tests/Revolute.h
vendored
Normal file
166
external/Box2D-2.3.1/Box2D/Testbed/Tests/Revolute.h
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 REVOLUTE_H
|
||||
#define REVOLUTE_H
|
||||
|
||||
class Revolute : public Test
|
||||
{
|
||||
public:
|
||||
Revolute()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
//fd.filter.categoryBits = 2;
|
||||
|
||||
ground->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
|
||||
bd.position.Set(-10.0f, 20.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
|
||||
float32 w = 100.0f;
|
||||
body->SetAngularVelocity(w);
|
||||
body->SetLinearVelocity(b2Vec2(-8.0f * w, 0.0f));
|
||||
|
||||
rjd.Initialize(ground, body, b2Vec2(-10.0f, 12.0f));
|
||||
rjd.motorSpeed = 1.0f * b2_pi;
|
||||
rjd.maxMotorTorque = 10000.0f;
|
||||
rjd.enableMotor = false;
|
||||
rjd.lowerAngle = -0.25f * b2_pi;
|
||||
rjd.upperAngle = 0.5f * b2_pi;
|
||||
rjd.enableLimit = true;
|
||||
rjd.collideConnected = true;
|
||||
|
||||
m_joint = (b2RevoluteJoint*)m_world->CreateJoint(&rjd);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape circle_shape;
|
||||
circle_shape.m_radius = 3.0f;
|
||||
|
||||
b2BodyDef circle_bd;
|
||||
circle_bd.type = b2_dynamicBody;
|
||||
circle_bd.position.Set(5.0f, 30.0f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.density = 5.0f;
|
||||
fd.filter.maskBits = 1;
|
||||
fd.shape = &circle_shape;
|
||||
|
||||
m_ball = m_world->CreateBody(&circle_bd);
|
||||
m_ball->CreateFixture(&fd);
|
||||
|
||||
b2PolygonShape polygon_shape;
|
||||
polygon_shape.SetAsBox(10.0f, 0.2f, b2Vec2 (-10.0f, 0.0f), 0.0f);
|
||||
|
||||
b2BodyDef polygon_bd;
|
||||
polygon_bd.position.Set(20.0f, 10.0f);
|
||||
polygon_bd.type = b2_dynamicBody;
|
||||
polygon_bd.bullet = true;
|
||||
b2Body* polygon_body = m_world->CreateBody(&polygon_bd);
|
||||
polygon_body->CreateFixture(&polygon_shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(ground, polygon_body, b2Vec2(20.0f, 10.0f));
|
||||
rjd.lowerAngle = -0.25f * b2_pi;
|
||||
rjd.upperAngle = 0.0f * b2_pi;
|
||||
rjd.enableLimit = true;
|
||||
m_world->CreateJoint(&rjd);
|
||||
}
|
||||
|
||||
// Tests mass computation of a small object far from the origin
|
||||
{
|
||||
b2BodyDef bodyDef;
|
||||
bodyDef.type = b2_dynamicBody;
|
||||
b2Body* body = m_world->CreateBody(&bodyDef);
|
||||
|
||||
b2PolygonShape polyShape;
|
||||
b2Vec2 verts[3];
|
||||
verts[0].Set( 17.63f, 36.31f );
|
||||
verts[1].Set( 17.52f, 36.69f );
|
||||
verts[2].Set( 17.19f, 36.36f );
|
||||
polyShape.Set(verts, 3);
|
||||
|
||||
b2FixtureDef polyFixtureDef;
|
||||
polyFixtureDef.shape = &polyShape;
|
||||
polyFixtureDef.density = 1;
|
||||
|
||||
body->CreateFixture(&polyFixtureDef); //assertion hits inside here
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_L:
|
||||
m_joint->EnableLimit(!m_joint->IsLimitEnabled());
|
||||
break;
|
||||
|
||||
case GLFW_KEY_M:
|
||||
m_joint->EnableMotor(!m_joint->IsMotorEnabled());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: (l) limits, (m) motor");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
//if (m_stepCount == 360)
|
||||
//{
|
||||
// m_ball->SetTransform(b2Vec2(0.0f, 0.5f), 0.0f);
|
||||
//}
|
||||
|
||||
//float32 torque1 = m_joint1->GetMotorTorque();
|
||||
//g_debugDraw.DrawString(5, m_textLine, "Motor Torque = %4.0f, %4.0f : Motor Force = %4.0f", (float) torque1, (float) torque2, (float) force3);
|
||||
//m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Revolute;
|
||||
}
|
||||
|
||||
b2Body* m_ball;
|
||||
b2RevoluteJoint* m_joint;
|
||||
};
|
||||
|
||||
#endif
|
||||
101
external/Box2D-2.3.1/Box2D/Testbed/Tests/Rope.h
vendored
Normal file
101
external/Box2D-2.3.1/Box2D/Testbed/Tests/Rope.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Erin Catto http://box2d.org
|
||||
*
|
||||
* 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 ROPE_H
|
||||
#define ROPE_H
|
||||
|
||||
///
|
||||
class Rope : public Test
|
||||
{
|
||||
public:
|
||||
Rope()
|
||||
{
|
||||
const int32 N = 40;
|
||||
b2Vec2 vertices[N];
|
||||
float32 masses[N];
|
||||
|
||||
for (int32 i = 0; i < N; ++i)
|
||||
{
|
||||
vertices[i].Set(0.0f, 20.0f - 0.25f * i);
|
||||
masses[i] = 1.0f;
|
||||
}
|
||||
masses[0] = 0.0f;
|
||||
masses[1] = 0.0f;
|
||||
|
||||
b2RopeDef def;
|
||||
def.vertices = vertices;
|
||||
def.count = N;
|
||||
def.gravity.Set(0.0f, -10.0f);
|
||||
def.masses = masses;
|
||||
def.damping = 0.1f;
|
||||
def.k2 = 1.0f;
|
||||
def.k3 = 0.5f;
|
||||
|
||||
m_rope.Initialize(&def);
|
||||
|
||||
m_angle = 0.0f;
|
||||
m_rope.SetAngle(m_angle);
|
||||
}
|
||||
|
||||
void Keyboard(unsigned char key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 'q':
|
||||
m_angle = b2Max(-b2_pi, m_angle - 0.05f * b2_pi);
|
||||
m_rope.SetAngle(m_angle);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
m_angle = b2Min(b2_pi, m_angle + 0.05f * b2_pi);
|
||||
m_rope.SetAngle(m_angle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
float32 dt = settings->hz > 0.0f ? 1.0f / settings->hz : 0.0f;
|
||||
|
||||
if (settings->pause == 1 && settings->singleStep == 0)
|
||||
{
|
||||
dt = 0.0f;
|
||||
}
|
||||
|
||||
m_rope.Step(dt, 1);
|
||||
|
||||
Test::Step(settings);
|
||||
|
||||
m_rope.Draw(&m_debugDraw);
|
||||
|
||||
m_debugDraw.DrawString(5, m_textLine, "Press (q,e) to adjust target angle");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
m_debugDraw.DrawString(5, m_textLine, "Target angle = %g degrees", m_angle * 180.0f / b2_pi);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Rope;
|
||||
}
|
||||
|
||||
b2Rope m_rope;
|
||||
float32 m_angle;
|
||||
};
|
||||
|
||||
#endif
|
||||
145
external/Box2D-2.3.1/Box2D/Testbed/Tests/RopeJoint.h
vendored
Normal file
145
external/Box2D-2.3.1/Box2D/Testbed/Tests/RopeJoint.h
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 ROPE_JOINT_H
|
||||
#define ROPE_JOINT_H
|
||||
|
||||
/// This test shows how a rope joint can be used to stabilize a chain of
|
||||
/// bodies with a heavy payload. Notice that the rope joint just prevents
|
||||
/// excessive stretching and has no other effect.
|
||||
/// By disabling the rope joint you can see that the Box2D solver has trouble
|
||||
/// supporting heavy bodies with light bodies. Try playing around with the
|
||||
/// densities, time step, and iterations to see how they affect stability.
|
||||
/// This test also shows how to use contact filtering. Filtering is configured
|
||||
/// so that the payload does not collide with the chain.
|
||||
class RopeJoint : public Test
|
||||
{
|
||||
public:
|
||||
RopeJoint()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.125f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
fd.friction = 0.2f;
|
||||
fd.filter.categoryBits = 0x0001;
|
||||
fd.filter.maskBits = 0xFFFF & ~0x0002;
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
jd.collideConnected = false;
|
||||
|
||||
const int32 N = 10;
|
||||
const float32 y = 15.0f;
|
||||
m_ropeDef.localAnchorA.Set(0.0f, y);
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for (int32 i = 0; i < N; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.5f + 1.0f * i, y);
|
||||
if (i == N - 1)
|
||||
{
|
||||
shape.SetAsBox(1.5f, 1.5f);
|
||||
fd.density = 100.0f;
|
||||
fd.filter.categoryBits = 0x0002;
|
||||
bd.position.Set(1.0f * i, y);
|
||||
bd.angularDamping = 0.4f;
|
||||
}
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(float32(i), y);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
m_ropeDef.localAnchorB.SetZero();
|
||||
|
||||
float32 extraLength = 0.01f;
|
||||
m_ropeDef.maxLength = N - 1.0f + extraLength;
|
||||
m_ropeDef.bodyB = prevBody;
|
||||
}
|
||||
|
||||
{
|
||||
m_ropeDef.bodyA = ground;
|
||||
m_rope = m_world->CreateJoint(&m_ropeDef);
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_J:
|
||||
if (m_rope)
|
||||
{
|
||||
m_world->DestroyJoint(m_rope);
|
||||
m_rope = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rope = m_world->CreateJoint(&m_ropeDef);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press (j) to toggle the rope joint.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
if (m_rope)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "Rope ON");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "Rope OFF");
|
||||
}
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new RopeJoint;
|
||||
}
|
||||
|
||||
b2RopeJointDef m_ropeDef;
|
||||
b2Joint* m_rope;
|
||||
};
|
||||
|
||||
#endif
|
||||
181
external/Box2D-2.3.1/Box2D/Testbed/Tests/SensorTest.h
vendored
Normal file
181
external/Box2D-2.3.1/Box2D/Testbed/Tests/SensorTest.h
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 SENSOR_TEST_H
|
||||
#define SENSOR_TEST_H
|
||||
|
||||
// This is used to test sensor shapes.
|
||||
class SensorTest : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_count = 7
|
||||
};
|
||||
|
||||
SensorTest()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
{
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
b2FixtureDef sd;
|
||||
sd.SetAsBox(10.0f, 2.0f, b2Vec2(0.0f, 20.0f), 0.0f);
|
||||
sd.isSensor = true;
|
||||
m_sensor = ground->CreateFixture(&sd);
|
||||
}
|
||||
#else
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 5.0f;
|
||||
shape.m_p.Set(0.0f, 10.0f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.isSensor = true;
|
||||
m_sensor = ground->CreateFixture(&fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 1.0f;
|
||||
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-10.0f + 3.0f * i, 20.0f);
|
||||
bd.userData = m_touching + i;
|
||||
|
||||
m_touching[i] = false;
|
||||
m_bodies[i] = m_world->CreateBody(&bd);
|
||||
|
||||
m_bodies[i]->CreateFixture(&shape, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement contact listener.
|
||||
void BeginContact(b2Contact* contact)
|
||||
{
|
||||
b2Fixture* fixtureA = contact->GetFixtureA();
|
||||
b2Fixture* fixtureB = contact->GetFixtureB();
|
||||
|
||||
if (fixtureA == m_sensor)
|
||||
{
|
||||
void* userData = fixtureB->GetBody()->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
bool* touching = (bool*)userData;
|
||||
*touching = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fixtureB == m_sensor)
|
||||
{
|
||||
void* userData = fixtureA->GetBody()->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
bool* touching = (bool*)userData;
|
||||
*touching = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement contact listener.
|
||||
void EndContact(b2Contact* contact)
|
||||
{
|
||||
b2Fixture* fixtureA = contact->GetFixtureA();
|
||||
b2Fixture* fixtureB = contact->GetFixtureB();
|
||||
|
||||
if (fixtureA == m_sensor)
|
||||
{
|
||||
void* userData = fixtureB->GetBody()->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
bool* touching = (bool*)userData;
|
||||
*touching = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fixtureB == m_sensor)
|
||||
{
|
||||
void* userData = fixtureA->GetBody()->GetUserData();
|
||||
if (userData)
|
||||
{
|
||||
bool* touching = (bool*)userData;
|
||||
*touching = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
// Traverse the contact results. Apply a force on shapes
|
||||
// that overlap the sensor.
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
if (m_touching[i] == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
b2Body* body = m_bodies[i];
|
||||
b2Body* ground = m_sensor->GetBody();
|
||||
|
||||
b2CircleShape* circle = (b2CircleShape*)m_sensor->GetShape();
|
||||
b2Vec2 center = ground->GetWorldPoint(circle->m_p);
|
||||
|
||||
b2Vec2 position = body->GetPosition();
|
||||
|
||||
b2Vec2 d = center - position;
|
||||
if (d.LengthSquared() < FLT_EPSILON * FLT_EPSILON)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
d.Normalize();
|
||||
b2Vec2 F = 100.0f * d;
|
||||
body->ApplyForce(F, position, false);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new SensorTest;
|
||||
}
|
||||
|
||||
b2Fixture* m_sensor;
|
||||
b2Body* m_bodies[e_count];
|
||||
bool m_touching[e_count];
|
||||
};
|
||||
|
||||
#endif
|
||||
105
external/Box2D-2.3.1/Box2D/Testbed/Tests/ShapeEditing.h
vendored
Normal file
105
external/Box2D-2.3.1/Box2D/Testbed/Tests/ShapeEditing.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 SHAPE_EDITING_H
|
||||
#define SHAPE_EDITING_H
|
||||
|
||||
class ShapeEditing : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
ShapeEditing()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 10.0f);
|
||||
m_body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(4.0f, 4.0f, b2Vec2(0.0f, 0.0f), 0.0f);
|
||||
m_fixture1 = m_body->CreateFixture(&shape, 10.0f);
|
||||
|
||||
m_fixture2 = NULL;
|
||||
|
||||
m_sensor = false;
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_C:
|
||||
if (m_fixture2 == NULL)
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 3.0f;
|
||||
shape.m_p.Set(0.5f, -4.0f);
|
||||
m_fixture2 = m_body->CreateFixture(&shape, 10.0f);
|
||||
m_body->SetAwake(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
if (m_fixture2 != NULL)
|
||||
{
|
||||
m_body->DestroyFixture(m_fixture2);
|
||||
m_fixture2 = NULL;
|
||||
m_body->SetAwake(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
if (m_fixture2 != NULL)
|
||||
{
|
||||
m_sensor = !m_sensor;
|
||||
m_fixture2->SetSensor(m_sensor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press: (c) create a shape, (d) destroy a shape.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "sensor = %d", m_sensor);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new ShapeEditing;
|
||||
}
|
||||
|
||||
b2Body* m_body;
|
||||
b2Fixture* m_fixture1;
|
||||
b2Fixture* m_fixture2;
|
||||
bool m_sensor;
|
||||
};
|
||||
|
||||
#endif
|
||||
156
external/Box2D-2.3.1/Box2D/Testbed/Tests/SliderCrank.h
vendored
Normal file
156
external/Box2D-2.3.1/Box2D/Testbed/Tests/SliderCrank.h
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 SLIDER_CRANK_H
|
||||
#define SLIDER_CRANK_H
|
||||
|
||||
// A motor driven slider crank with joint friction.
|
||||
|
||||
class SliderCrank : public Test
|
||||
{
|
||||
public:
|
||||
SliderCrank()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2Body* prevBody = ground;
|
||||
|
||||
// Define crank.
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 2.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 7.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(prevBody, body, b2Vec2(0.0f, 5.0f));
|
||||
rjd.motorSpeed = 1.0f * b2_pi;
|
||||
rjd.maxMotorTorque = 10000.0f;
|
||||
rjd.enableMotor = true;
|
||||
m_joint1 = (b2RevoluteJoint*)m_world->CreateJoint(&rjd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
// Define follower.
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 4.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 13.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(prevBody, body, b2Vec2(0.0f, 9.0f));
|
||||
rjd.enableMotor = false;
|
||||
m_world->CreateJoint(&rjd);
|
||||
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
// Define piston
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.5f, 1.5f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.fixedRotation = true;
|
||||
bd.position.Set(0.0f, 17.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
rjd.Initialize(prevBody, body, b2Vec2(0.0f, 17.0f));
|
||||
m_world->CreateJoint(&rjd);
|
||||
|
||||
b2PrismaticJointDef pjd;
|
||||
pjd.Initialize(ground, body, b2Vec2(0.0f, 17.0f), b2Vec2(0.0f, 1.0f));
|
||||
|
||||
pjd.maxMotorForce = 1000.0f;
|
||||
pjd.enableMotor = true;
|
||||
|
||||
m_joint2 = (b2PrismaticJoint*)m_world->CreateJoint(&pjd);
|
||||
}
|
||||
|
||||
// Create a payload
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(1.5f, 1.5f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 23.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 2.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_F:
|
||||
m_joint2->EnableMotor(!m_joint2->IsMotorEnabled());
|
||||
m_joint2->GetBodyB()->SetAwake(true);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_M:
|
||||
m_joint1->EnableMotor(!m_joint1->IsMotorEnabled());
|
||||
m_joint1->GetBodyB()->SetAwake(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: (f) toggle friction, (m) toggle motor");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
float32 torque = m_joint1->GetMotorTorque(settings->hz);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Motor Torque = %5.0f", (float) torque);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new SliderCrank;
|
||||
}
|
||||
|
||||
b2RevoluteJoint* m_joint1;
|
||||
b2PrismaticJoint* m_joint2;
|
||||
};
|
||||
|
||||
#endif
|
||||
86
external/Box2D-2.3.1/Box2D/Testbed/Tests/SphereStack.h
vendored
Normal file
86
external/Box2D-2.3.1/Box2D/Testbed/Tests/SphereStack.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 SPHERE_STACK_H
|
||||
#define SPHERE_STACK_H
|
||||
|
||||
class SphereStack : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_count = 10
|
||||
};
|
||||
|
||||
SphereStack()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 1.0f;
|
||||
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0, 4.0f + 3.0f * i);
|
||||
|
||||
m_bodies[i] = m_world->CreateBody(&bd);
|
||||
|
||||
m_bodies[i]->CreateFixture(&shape, 1.0f);
|
||||
|
||||
m_bodies[i]->SetLinearVelocity(b2Vec2(0.0f, -50.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
//for (int32 i = 0; i < e_count; ++i)
|
||||
//{
|
||||
// printf("%g ", m_bodies[i]->GetWorldCenter().y);
|
||||
//}
|
||||
|
||||
//for (int32 i = 0; i < e_count; ++i)
|
||||
//{
|
||||
// printf("%g ", m_bodies[i]->GetLinearVelocity().y);
|
||||
//}
|
||||
|
||||
//printf("\n");
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new SphereStack;
|
||||
}
|
||||
|
||||
b2Body* m_bodies[e_count];
|
||||
};
|
||||
|
||||
#endif
|
||||
129
external/Box2D-2.3.1/Box2D/Testbed/Tests/TestEntries.cpp
vendored
Normal file
129
external/Box2D-2.3.1/Box2D/Testbed/Tests/TestEntries.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "../Framework/Test.h"
|
||||
|
||||
#include "AddPair.h"
|
||||
#include "ApplyForce.h"
|
||||
#include "BasicSliderCrank.h"
|
||||
#include "BodyTypes.h"
|
||||
#include "Breakable.h"
|
||||
#include "Bridge.h"
|
||||
#include "BulletTest.h"
|
||||
#include "Cantilever.h"
|
||||
#include "Car.h"
|
||||
#include "ContinuousTest.h"
|
||||
#include "Chain.h"
|
||||
#include "CharacterCollision.h"
|
||||
#include "CollisionFiltering.h"
|
||||
#include "CollisionProcessing.h"
|
||||
#include "CompoundShapes.h"
|
||||
#include "Confined.h"
|
||||
#include "ConvexHull.h"
|
||||
#include "ConveyorBelt.h"
|
||||
#include "DistanceTest.h"
|
||||
#include "Dominos.h"
|
||||
#include "DumpShell.h"
|
||||
#include "DynamicTreeTest.h"
|
||||
#include "EdgeShapes.h"
|
||||
#include "EdgeTest.h"
|
||||
#include "Gears.h"
|
||||
#include "HeavyOnLight.h"
|
||||
#include "HeavyOnLightTwo.h"
|
||||
#include "Mobile.h"
|
||||
#include "MobileBalanced.h"
|
||||
#include "MotorJoint.h"
|
||||
#include "OneSidedPlatform.h"
|
||||
#include "Pinball.h"
|
||||
#include "PolyCollision.h"
|
||||
#include "PolyShapes.h"
|
||||
#include "Prismatic.h"
|
||||
#include "Pulleys.h"
|
||||
#include "Pyramid.h"
|
||||
#include "RayCast.h"
|
||||
#include "Revolute.h"
|
||||
#include "RopeJoint.h"
|
||||
#include "SensorTest.h"
|
||||
#include "ShapeEditing.h"
|
||||
#include "SliderCrank.h"
|
||||
#include "SphereStack.h"
|
||||
#include "TheoJansen.h"
|
||||
#include "Tiles.h"
|
||||
#include "TimeOfImpact.h"
|
||||
#include "Tumbler.h"
|
||||
#include "VaryingFriction.h"
|
||||
#include "VaryingRestitution.h"
|
||||
#include "VerticalStack.h"
|
||||
#include "Web.h"
|
||||
|
||||
TestEntry g_testEntries[] =
|
||||
{
|
||||
{"Tiles", Tiles::Create},
|
||||
{"Heavy on Light", HeavyOnLight::Create},
|
||||
{"Heavy on Light Two", HeavyOnLightTwo::Create},
|
||||
{"Vertical Stack", VerticalStack::Create},
|
||||
{"Basic Slider Crank", BasicSliderCrank::Create},
|
||||
{"Slider Crank", SliderCrank::Create},
|
||||
{"Sphere Stack", SphereStack::Create},
|
||||
{"Convex Hull", ConvexHull::Create},
|
||||
{"Tumbler", Tumbler::Create},
|
||||
{"Ray-Cast", RayCast::Create},
|
||||
{"Dump Shell", DumpShell::Create},
|
||||
{"Apply Force", ApplyForce::Create},
|
||||
{"Continuous Test", ContinuousTest::Create},
|
||||
{"Time of Impact", TimeOfImpact::Create},
|
||||
{"Motor Joint", MotorJoint::Create},
|
||||
{"One-Sided Platform", OneSidedPlatform::Create},
|
||||
{"Mobile", Mobile::Create},
|
||||
{"MobileBalanced", MobileBalanced::Create},
|
||||
{"Conveyor Belt", ConveyorBelt::Create},
|
||||
{"Gears", Gears::Create},
|
||||
{"Varying Restitution", VaryingRestitution::Create},
|
||||
{"Cantilever", Cantilever::Create},
|
||||
{"Character Collision", CharacterCollision::Create},
|
||||
{"Edge Test", EdgeTest::Create},
|
||||
{"Body Types", BodyTypes::Create},
|
||||
{"Shape Editing", ShapeEditing::Create},
|
||||
{"Car", Car::Create},
|
||||
{"Prismatic", Prismatic::Create},
|
||||
{"Revolute", Revolute::Create},
|
||||
{"Pulleys", Pulleys::Create},
|
||||
{"Polygon Shapes", PolyShapes::Create},
|
||||
{"Web", Web::Create},
|
||||
{"RopeJoint", RopeJoint::Create},
|
||||
{"Pinball", Pinball::Create},
|
||||
{"Bullet Test", BulletTest::Create},
|
||||
{"Confined", Confined::Create},
|
||||
{"Pyramid", Pyramid::Create},
|
||||
{"Theo Jansen's Walker", TheoJansen::Create},
|
||||
{"Edge Shapes", EdgeShapes::Create},
|
||||
{"PolyCollision", PolyCollision::Create},
|
||||
{"Bridge", Bridge::Create},
|
||||
{"Breakable", Breakable::Create},
|
||||
{"Chain", Chain::Create},
|
||||
{"Collision Filtering", CollisionFiltering::Create},
|
||||
{"Collision Processing", CollisionProcessing::Create},
|
||||
{"Compound Shapes", CompoundShapes::Create},
|
||||
{"Distance Test", DistanceTest::Create},
|
||||
{"Dominos", Dominos::Create},
|
||||
{"Dynamic Tree", DynamicTreeTest::Create},
|
||||
{"Sensor Test", SensorTest::Create},
|
||||
{"Varying Friction", VaryingFriction::Create},
|
||||
{"Add Pair Stress Test", AddPair::Create},
|
||||
{NULL, NULL}
|
||||
};
|
||||
256
external/Box2D-2.3.1/Box2D/Testbed/Tests/TheoJansen.h
vendored
Normal file
256
external/Box2D-2.3.1/Box2D/Testbed/Tests/TheoJansen.h
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Inspired by a contribution by roman_m
|
||||
// Dimensions scooped from APE (http://www.cove.org/ape/index.htm)
|
||||
|
||||
#ifndef THEO_JANSEN_H
|
||||
#define THEO_JANSEN_H
|
||||
|
||||
class TheoJansen : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
void CreateLeg(float32 s, const b2Vec2& wheelAnchor)
|
||||
{
|
||||
b2Vec2 p1(5.4f * s, -6.1f);
|
||||
b2Vec2 p2(7.2f * s, -1.2f);
|
||||
b2Vec2 p3(4.3f * s, -1.9f);
|
||||
b2Vec2 p4(3.1f * s, 0.8f);
|
||||
b2Vec2 p5(6.0f * s, 1.5f);
|
||||
b2Vec2 p6(2.5f * s, 3.7f);
|
||||
|
||||
b2FixtureDef fd1, fd2;
|
||||
fd1.filter.groupIndex = -1;
|
||||
fd2.filter.groupIndex = -1;
|
||||
fd1.density = 1.0f;
|
||||
fd2.density = 1.0f;
|
||||
|
||||
b2PolygonShape poly1, poly2;
|
||||
|
||||
if (s > 0.0f)
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
|
||||
vertices[0] = p1;
|
||||
vertices[1] = p2;
|
||||
vertices[2] = p3;
|
||||
poly1.Set(vertices, 3);
|
||||
|
||||
vertices[0] = b2Vec2_zero;
|
||||
vertices[1] = p5 - p4;
|
||||
vertices[2] = p6 - p4;
|
||||
poly2.Set(vertices, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
b2Vec2 vertices[3];
|
||||
|
||||
vertices[0] = p1;
|
||||
vertices[1] = p3;
|
||||
vertices[2] = p2;
|
||||
poly1.Set(vertices, 3);
|
||||
|
||||
vertices[0] = b2Vec2_zero;
|
||||
vertices[1] = p6 - p4;
|
||||
vertices[2] = p5 - p4;
|
||||
poly2.Set(vertices, 3);
|
||||
}
|
||||
|
||||
fd1.shape = &poly1;
|
||||
fd2.shape = &poly2;
|
||||
|
||||
b2BodyDef bd1, bd2;
|
||||
bd1.type = b2_dynamicBody;
|
||||
bd2.type = b2_dynamicBody;
|
||||
bd1.position = m_offset;
|
||||
bd2.position = p4 + m_offset;
|
||||
|
||||
bd1.angularDamping = 10.0f;
|
||||
bd2.angularDamping = 10.0f;
|
||||
|
||||
b2Body* body1 = m_world->CreateBody(&bd1);
|
||||
b2Body* body2 = m_world->CreateBody(&bd2);
|
||||
|
||||
body1->CreateFixture(&fd1);
|
||||
body2->CreateFixture(&fd2);
|
||||
|
||||
b2DistanceJointDef djd;
|
||||
|
||||
// Using a soft distance constraint can reduce some jitter.
|
||||
// It also makes the structure seem a bit more fluid by
|
||||
// acting like a suspension system.
|
||||
djd.dampingRatio = 0.5f;
|
||||
djd.frequencyHz = 10.0f;
|
||||
|
||||
djd.Initialize(body1, body2, p2 + m_offset, p5 + m_offset);
|
||||
m_world->CreateJoint(&djd);
|
||||
|
||||
djd.Initialize(body1, body2, p3 + m_offset, p4 + m_offset);
|
||||
m_world->CreateJoint(&djd);
|
||||
|
||||
djd.Initialize(body1, m_wheel, p3 + m_offset, wheelAnchor + m_offset);
|
||||
m_world->CreateJoint(&djd);
|
||||
|
||||
djd.Initialize(body2, m_wheel, p6 + m_offset, wheelAnchor + m_offset);
|
||||
m_world->CreateJoint(&djd);
|
||||
|
||||
b2RevoluteJointDef rjd;
|
||||
|
||||
rjd.Initialize(body2, m_chassis, p4 + m_offset);
|
||||
m_world->CreateJoint(&rjd);
|
||||
}
|
||||
|
||||
TheoJansen()
|
||||
{
|
||||
m_offset.Set(0.0f, 8.0f);
|
||||
m_motorSpeed = 2.0f;
|
||||
m_motorOn = true;
|
||||
b2Vec2 pivot(0.0f, 0.8f);
|
||||
|
||||
// Ground
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-50.0f, 0.0f), b2Vec2(50.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(b2Vec2(-50.0f, 0.0f), b2Vec2(-50.0f, 10.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(b2Vec2(50.0f, 0.0f), b2Vec2(50.0f, 10.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
// Balls
|
||||
for (int32 i = 0; i < 40; ++i)
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.25f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-40.0f + 2.0f * i, 0.5f);
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
}
|
||||
|
||||
// Chassis
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(2.5f, 1.0f);
|
||||
|
||||
b2FixtureDef sd;
|
||||
sd.density = 1.0f;
|
||||
sd.shape = &shape;
|
||||
sd.filter.groupIndex = -1;
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = pivot + m_offset;
|
||||
m_chassis = m_world->CreateBody(&bd);
|
||||
m_chassis->CreateFixture(&sd);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 1.6f;
|
||||
|
||||
b2FixtureDef sd;
|
||||
sd.density = 1.0f;
|
||||
sd.shape = &shape;
|
||||
sd.filter.groupIndex = -1;
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = pivot + m_offset;
|
||||
m_wheel = m_world->CreateBody(&bd);
|
||||
m_wheel->CreateFixture(&sd);
|
||||
}
|
||||
|
||||
{
|
||||
b2RevoluteJointDef jd;
|
||||
jd.Initialize(m_wheel, m_chassis, pivot + m_offset);
|
||||
jd.collideConnected = false;
|
||||
jd.motorSpeed = m_motorSpeed;
|
||||
jd.maxMotorTorque = 400.0f;
|
||||
jd.enableMotor = m_motorOn;
|
||||
m_motorJoint = (b2RevoluteJoint*)m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
b2Vec2 wheelAnchor;
|
||||
|
||||
wheelAnchor = pivot + b2Vec2(0.0f, -0.8f);
|
||||
|
||||
CreateLeg(-1.0f, wheelAnchor);
|
||||
CreateLeg(1.0f, wheelAnchor);
|
||||
|
||||
m_wheel->SetTransform(m_wheel->GetPosition(), 120.0f * b2_pi / 180.0f);
|
||||
CreateLeg(-1.0f, wheelAnchor);
|
||||
CreateLeg(1.0f, wheelAnchor);
|
||||
|
||||
m_wheel->SetTransform(m_wheel->GetPosition(), -120.0f * b2_pi / 180.0f);
|
||||
CreateLeg(-1.0f, wheelAnchor);
|
||||
CreateLeg(1.0f, wheelAnchor);
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
g_debugDraw.DrawString(5, m_textLine, "Keys: left = a, brake = s, right = d, toggle motor = m");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
Test::Step(settings);
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_A:
|
||||
m_motorJoint->SetMotorSpeed(-m_motorSpeed);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_S:
|
||||
m_motorJoint->SetMotorSpeed(0.0f);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_D:
|
||||
m_motorJoint->SetMotorSpeed(m_motorSpeed);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_M:
|
||||
m_motorJoint->EnableMotor(!m_motorJoint->IsMotorEnabled());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new TheoJansen;
|
||||
}
|
||||
|
||||
b2Vec2 m_offset;
|
||||
b2Body* m_chassis;
|
||||
b2Body* m_wheel;
|
||||
b2RevoluteJoint* m_motorJoint;
|
||||
bool m_motorOn;
|
||||
float32 m_motorSpeed;
|
||||
};
|
||||
|
||||
#endif // THEO_JANSEN_H
|
||||
156
external/Box2D-2.3.1/Box2D/Testbed/Tests/Tiles.h
vendored
Normal file
156
external/Box2D-2.3.1/Box2D/Testbed/Tests/Tiles.h
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 TILES_H
|
||||
#define TILES_H
|
||||
|
||||
/// This stress tests the dynamic tree broad-phase. This also shows that tile
|
||||
/// based collision is _not_ smooth due to Box2D not knowing about adjacency.
|
||||
class Tiles : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_count = 20
|
||||
};
|
||||
|
||||
Tiles()
|
||||
{
|
||||
m_fixtureCount = 0;
|
||||
b2Timer timer;
|
||||
|
||||
{
|
||||
float32 a = 0.5f;
|
||||
b2BodyDef bd;
|
||||
bd.position.y = -a;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
#if 1
|
||||
int32 N = 200;
|
||||
int32 M = 10;
|
||||
b2Vec2 position;
|
||||
position.y = 0.0f;
|
||||
for (int32 j = 0; j < M; ++j)
|
||||
{
|
||||
position.x = -N * a;
|
||||
for (int32 i = 0; i < N; ++i)
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(a, a, position, 0.0f);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
++m_fixtureCount;
|
||||
position.x += 2.0f * a;
|
||||
}
|
||||
position.y -= 2.0f * a;
|
||||
}
|
||||
#else
|
||||
int32 N = 200;
|
||||
int32 M = 10;
|
||||
b2Vec2 position;
|
||||
position.x = -N * a;
|
||||
for (int32 i = 0; i < N; ++i)
|
||||
{
|
||||
position.y = 0.0f;
|
||||
for (int32 j = 0; j < M; ++j)
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(a, a, position, 0.0f);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
position.y -= 2.0f * a;
|
||||
}
|
||||
position.x += 2.0f * a;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
float32 a = 0.5f;
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(a, a);
|
||||
|
||||
b2Vec2 x(-7.0f, 0.75f);
|
||||
b2Vec2 y;
|
||||
b2Vec2 deltaX(0.5625f, 1.25f);
|
||||
b2Vec2 deltaY(1.125f, 0.0f);
|
||||
|
||||
for (int32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
y = x;
|
||||
|
||||
for (int32 j = i; j < e_count; ++j)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position = y;
|
||||
|
||||
//if (i == 0 && j == 0)
|
||||
//{
|
||||
// bd.allowSleep = false;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// bd.allowSleep = true;
|
||||
//}
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
++m_fixtureCount;
|
||||
y += deltaY;
|
||||
}
|
||||
|
||||
x += deltaX;
|
||||
}
|
||||
}
|
||||
|
||||
m_createTime = timer.GetMilliseconds();
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
const b2ContactManager& cm = m_world->GetContactManager();
|
||||
int32 height = cm.m_broadPhase.GetTreeHeight();
|
||||
int32 leafCount = cm.m_broadPhase.GetProxyCount();
|
||||
int32 minimumNodeCount = 2 * leafCount - 1;
|
||||
float32 minimumHeight = ceilf(logf(float32(minimumNodeCount)) / logf(2.0f));
|
||||
g_debugDraw.DrawString(5, m_textLine, "dynamic tree height = %d, min = %d", height, int32(minimumHeight));
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
Test::Step(settings);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "create time = %6.2f ms, fixture count = %d",
|
||||
m_createTime, m_fixtureCount);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
//b2DynamicTree* tree = &m_world->m_contactManager.m_broadPhase.m_tree;
|
||||
|
||||
//if (m_stepCount == 400)
|
||||
//{
|
||||
// tree->RebuildBottomUp();
|
||||
//}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Tiles;
|
||||
}
|
||||
|
||||
int32 m_fixtureCount;
|
||||
float32 m_createTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
127
external/Box2D-2.3.1/Box2D/Testbed/Tests/TimeOfImpact.h
vendored
Normal file
127
external/Box2D-2.3.1/Box2D/Testbed/Tests/TimeOfImpact.h
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 TIME_OF_IMPACT_H
|
||||
#define TIME_OF_IMPACT_H
|
||||
|
||||
class TimeOfImpact : public Test
|
||||
{
|
||||
public:
|
||||
TimeOfImpact()
|
||||
{
|
||||
m_shapeA.SetAsBox(25.0f, 5.0f);
|
||||
m_shapeB.SetAsBox(2.5f, 2.5f);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new TimeOfImpact;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
b2Sweep sweepA;
|
||||
sweepA.c0.Set(24.0f, -60.0f);
|
||||
sweepA.a0 = 2.95f;
|
||||
sweepA.c = sweepA.c0;
|
||||
sweepA.a = sweepA.a0;
|
||||
sweepA.localCenter.SetZero();
|
||||
|
||||
b2Sweep sweepB;
|
||||
sweepB.c0.Set(53.474274f, -50.252514f);
|
||||
sweepB.a0 = 513.36676f; // - 162.0f * b2_pi;
|
||||
sweepB.c.Set(54.595478f, -51.083473f);
|
||||
sweepB.a = 513.62781f; // - 162.0f * b2_pi;
|
||||
sweepB.localCenter.SetZero();
|
||||
|
||||
//sweepB.a0 -= 300.0f * b2_pi;
|
||||
//sweepB.a -= 300.0f * b2_pi;
|
||||
|
||||
b2TOIInput input;
|
||||
input.proxyA.Set(&m_shapeA, 0);
|
||||
input.proxyB.Set(&m_shapeB, 0);
|
||||
input.sweepA = sweepA;
|
||||
input.sweepB = sweepB;
|
||||
input.tMax = 1.0f;
|
||||
|
||||
b2TOIOutput output;
|
||||
|
||||
b2TimeOfImpact(&output, &input);
|
||||
|
||||
g_debugDraw.DrawString(5, m_textLine, "toi = %g", output.t);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
extern int32 b2_toiMaxIters, b2_toiMaxRootIters;
|
||||
g_debugDraw.DrawString(5, m_textLine, "max toi iters = %d, max root iters = %d", b2_toiMaxIters, b2_toiMaxRootIters);
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
|
||||
b2Vec2 vertices[b2_maxPolygonVertices];
|
||||
|
||||
b2Transform transformA;
|
||||
sweepA.GetTransform(&transformA, 0.0f);
|
||||
for (int32 i = 0; i < m_shapeA.m_count; ++i)
|
||||
{
|
||||
vertices[i] = b2Mul(transformA, m_shapeA.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(vertices, m_shapeA.m_count, b2Color(0.9f, 0.9f, 0.9f));
|
||||
|
||||
b2Transform transformB;
|
||||
sweepB.GetTransform(&transformB, 0.0f);
|
||||
|
||||
//b2Vec2 localPoint(2.0f, -0.1f);
|
||||
|
||||
for (int32 i = 0; i < m_shapeB.m_count; ++i)
|
||||
{
|
||||
vertices[i] = b2Mul(transformB, m_shapeB.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(vertices, m_shapeB.m_count, b2Color(0.5f, 0.9f, 0.5f));
|
||||
|
||||
sweepB.GetTransform(&transformB, output.t);
|
||||
for (int32 i = 0; i < m_shapeB.m_count; ++i)
|
||||
{
|
||||
vertices[i] = b2Mul(transformB, m_shapeB.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(vertices, m_shapeB.m_count, b2Color(0.5f, 0.7f, 0.9f));
|
||||
|
||||
sweepB.GetTransform(&transformB, 1.0f);
|
||||
for (int32 i = 0; i < m_shapeB.m_count; ++i)
|
||||
{
|
||||
vertices[i] = b2Mul(transformB, m_shapeB.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(vertices, m_shapeB.m_count, b2Color(0.9f, 0.5f, 0.5f));
|
||||
|
||||
#if 0
|
||||
for (float32 t = 0.0f; t < 1.0f; t += 0.1f)
|
||||
{
|
||||
sweepB.GetTransform(&transformB, t);
|
||||
for (int32 i = 0; i < m_shapeB.m_count; ++i)
|
||||
{
|
||||
vertices[i] = b2Mul(transformB, m_shapeB.m_vertices[i]);
|
||||
}
|
||||
g_debugDraw.DrawPolygon(vertices, m_shapeB.m_count, b2Color(0.9f, 0.5f, 0.5f));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
b2PolygonShape m_shapeA;
|
||||
b2PolygonShape m_shapeB;
|
||||
};
|
||||
|
||||
#endif
|
||||
99
external/Box2D-2.3.1/Box2D/Testbed/Tests/Tumbler.h
vendored
Normal file
99
external/Box2D-2.3.1/Box2D/Testbed/Tests/Tumbler.h
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 TUMBLER_H
|
||||
#define TUMBLER_H
|
||||
|
||||
class Tumbler : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_count = 800
|
||||
};
|
||||
|
||||
Tumbler()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
}
|
||||
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.allowSleep = false;
|
||||
bd.position.Set(0.0f, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 10.0f, b2Vec2( 10.0f, 0.0f), 0.0);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
shape.SetAsBox(0.5f, 10.0f, b2Vec2(-10.0f, 0.0f), 0.0);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
shape.SetAsBox(10.0f, 0.5f, b2Vec2(0.0f, 10.0f), 0.0);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
shape.SetAsBox(10.0f, 0.5f, b2Vec2(0.0f, -10.0f), 0.0);
|
||||
body->CreateFixture(&shape, 5.0f);
|
||||
|
||||
b2RevoluteJointDef jd;
|
||||
jd.bodyA = ground;
|
||||
jd.bodyB = body;
|
||||
jd.localAnchorA.Set(0.0f, 10.0f);
|
||||
jd.localAnchorB.Set(0.0f, 0.0f);
|
||||
jd.referenceAngle = 0.0f;
|
||||
jd.motorSpeed = 0.05f * b2_pi;
|
||||
jd.maxMotorTorque = 1e8f;
|
||||
jd.enableMotor = true;
|
||||
m_joint = (b2RevoluteJoint*)m_world->CreateJoint(&jd);
|
||||
}
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
|
||||
if (m_count < e_count)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(0.0f, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.125f, 0.125f);
|
||||
body->CreateFixture(&shape, 1.0f);
|
||||
|
||||
++m_count;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Tumbler;
|
||||
}
|
||||
|
||||
b2RevoluteJoint* m_joint;
|
||||
int32 m_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
124
external/Box2D-2.3.1/Box2D/Testbed/Tests/VaryingFriction.h
vendored
Normal file
124
external/Box2D-2.3.1/Box2D/Testbed/Tests/VaryingFriction.h
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 VARYING_FRICTION_H
|
||||
#define VARYING_FRICTION_H
|
||||
|
||||
class VaryingFriction : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
VaryingFriction()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(13.0f, 0.25f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-4.0f, 22.0f);
|
||||
bd.angle = -0.25f;
|
||||
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f, 1.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(10.5f, 19.0f);
|
||||
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(13.0f, 0.25f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(4.0f, 14.0f);
|
||||
bd.angle = 0.25f;
|
||||
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.25f, 1.0f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-10.5f, 11.0f);
|
||||
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(13.0f, 0.25f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.position.Set(-4.0f, 6.0f);
|
||||
bd.angle = -0.25f;
|
||||
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 25.0f;
|
||||
|
||||
float friction[5] = {0.75f, 0.5f, 0.35f, 0.1f, 0.0f};
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-15.0f + 4.0f * i, 28.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
fd.friction = friction[i];
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new VaryingFriction;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
69
external/Box2D-2.3.1/Box2D/Testbed/Tests/VaryingRestitution.h
vendored
Normal file
69
external/Box2D-2.3.1/Box2D/Testbed/Tests/VaryingRestitution.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 VARYING_RESTITUTION_H
|
||||
#define VARYING_RESTITUTION_H
|
||||
|
||||
// Note: even with a restitution of 1.0, there is some energy change
|
||||
// due to position correction.
|
||||
class VaryingRestitution : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
VaryingRestitution()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 1.0f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
|
||||
float32 restitution[7] = {0.0f, 0.1f, 0.3f, 0.5f, 0.75f, 0.9f, 1.0f};
|
||||
|
||||
for (int32 i = 0; i < 7; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-10.0f + 3.0f * i, 20.0f);
|
||||
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
fd.restitution = restitution[i];
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new VaryingRestitution;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
171
external/Box2D-2.3.1/Box2D/Testbed/Tests/VerticalStack.h
vendored
Normal file
171
external/Box2D-2.3.1/Box2D/Testbed/Tests/VerticalStack.h
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 VERTICAL_STACK_H
|
||||
#define VERTICAL_STACK_H
|
||||
|
||||
extern bool g_blockSolve;
|
||||
|
||||
class VerticalStack : public Test
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
e_columnCount = 1,
|
||||
e_rowCount = 15
|
||||
//e_columnCount = 1,
|
||||
//e_rowCount = 1
|
||||
};
|
||||
|
||||
VerticalStack()
|
||||
{
|
||||
{
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
|
||||
shape.Set(b2Vec2(20.0f, 0.0f), b2Vec2(20.0f, 20.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
float32 xs[5] = {0.0f, -10.0f, -5.0f, 5.0f, 10.0f};
|
||||
|
||||
for (int32 j = 0; j < e_columnCount; ++j)
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 1.0f;
|
||||
fd.friction = 0.3f;
|
||||
|
||||
for (int i = 0; i < e_rowCount; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
int32 n = j * e_rowCount + i;
|
||||
b2Assert(n < e_rowCount * e_columnCount);
|
||||
m_indices[n] = n;
|
||||
bd.userData = m_indices + n;
|
||||
|
||||
float32 x = 0.0f;
|
||||
//float32 x = RandomFloat(-0.02f, 0.02f);
|
||||
//float32 x = i % 2 == 0 ? -0.01f : 0.01f;
|
||||
bd.position.Set(xs[j] + x, 0.55f + 1.1f * i);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
|
||||
m_bodies[n] = body;
|
||||
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
m_bullet = NULL;
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_COMMA:
|
||||
if (m_bullet != NULL)
|
||||
{
|
||||
m_world->DestroyBody(m_bullet);
|
||||
m_bullet = NULL;
|
||||
}
|
||||
|
||||
{
|
||||
b2CircleShape shape;
|
||||
shape.m_radius = 0.25f;
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &shape;
|
||||
fd.density = 20.0f;
|
||||
fd.restitution = 0.05f;
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.bullet = true;
|
||||
bd.position.Set(-31.0f, 5.0f);
|
||||
|
||||
m_bullet = m_world->CreateBody(&bd);
|
||||
m_bullet->CreateFixture(&fd);
|
||||
|
||||
m_bullet->SetLinearVelocity(b2Vec2(400.0f, 0.0f));
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_B:
|
||||
g_blockSolve = !g_blockSolve;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press: (,) to launch a bullet.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "Blocksolve = %d", g_blockSolve);
|
||||
//if (m_stepCount == 300)
|
||||
//{
|
||||
// if (m_bullet != NULL)
|
||||
// {
|
||||
// m_world->DestroyBody(m_bullet);
|
||||
// m_bullet = NULL;
|
||||
// }
|
||||
|
||||
// {
|
||||
// b2CircleShape shape;
|
||||
// shape.m_radius = 0.25f;
|
||||
|
||||
// b2FixtureDef fd;
|
||||
// fd.shape = &shape;
|
||||
// fd.density = 20.0f;
|
||||
// fd.restitution = 0.05f;
|
||||
|
||||
// b2BodyDef bd;
|
||||
// bd.type = b2_dynamicBody;
|
||||
// bd.bullet = true;
|
||||
// bd.position.Set(-31.0f, 5.0f);
|
||||
|
||||
// m_bullet = m_world->CreateBody(&bd);
|
||||
// m_bullet->CreateFixture(&fd);
|
||||
|
||||
// m_bullet->SetLinearVelocity(b2Vec2(400.0f, 0.0f));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new VerticalStack;
|
||||
}
|
||||
|
||||
b2Body* m_bullet;
|
||||
b2Body* m_bodies[e_rowCount * e_columnCount];
|
||||
int32 m_indices[e_rowCount * e_columnCount];
|
||||
};
|
||||
|
||||
#endif
|
||||
209
external/Box2D-2.3.1/Box2D/Testbed/Tests/Web.h
vendored
Normal file
209
external/Box2D-2.3.1/Box2D/Testbed/Tests/Web.h
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 WEB_H
|
||||
#define WEB_H
|
||||
|
||||
// This tests distance joints, body destruction, and joint destruction.
|
||||
class Web : public Test
|
||||
{
|
||||
public:
|
||||
Web()
|
||||
{
|
||||
b2Body* ground = NULL;
|
||||
{
|
||||
b2BodyDef bd;
|
||||
ground = m_world->CreateBody(&bd);
|
||||
|
||||
b2EdgeShape shape;
|
||||
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
ground->CreateFixture(&shape, 0.0f);
|
||||
}
|
||||
|
||||
{
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsBox(0.5f, 0.5f);
|
||||
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
|
||||
bd.position.Set(-5.0f, 5.0f);
|
||||
m_bodies[0] = m_world->CreateBody(&bd);
|
||||
m_bodies[0]->CreateFixture(&shape, 5.0f);
|
||||
|
||||
bd.position.Set(5.0f, 5.0f);
|
||||
m_bodies[1] = m_world->CreateBody(&bd);
|
||||
m_bodies[1]->CreateFixture(&shape, 5.0f);
|
||||
|
||||
bd.position.Set(5.0f, 15.0f);
|
||||
m_bodies[2] = m_world->CreateBody(&bd);
|
||||
m_bodies[2]->CreateFixture(&shape, 5.0f);
|
||||
|
||||
bd.position.Set(-5.0f, 15.0f);
|
||||
m_bodies[3] = m_world->CreateBody(&bd);
|
||||
m_bodies[3]->CreateFixture(&shape, 5.0f);
|
||||
|
||||
b2DistanceJointDef jd;
|
||||
b2Vec2 p1, p2, d;
|
||||
|
||||
jd.frequencyHz = 2.0f;
|
||||
jd.dampingRatio = 0.0f;
|
||||
|
||||
jd.bodyA = ground;
|
||||
jd.bodyB = m_bodies[0];
|
||||
jd.localAnchorA.Set(-10.0f, 0.0f);
|
||||
jd.localAnchorB.Set(-0.5f, -0.5f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[0] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = ground;
|
||||
jd.bodyB = m_bodies[1];
|
||||
jd.localAnchorA.Set(10.0f, 0.0f);
|
||||
jd.localAnchorB.Set(0.5f, -0.5f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[1] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = ground;
|
||||
jd.bodyB = m_bodies[2];
|
||||
jd.localAnchorA.Set(10.0f, 20.0f);
|
||||
jd.localAnchorB.Set(0.5f, 0.5f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[2] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = ground;
|
||||
jd.bodyB = m_bodies[3];
|
||||
jd.localAnchorA.Set(-10.0f, 20.0f);
|
||||
jd.localAnchorB.Set(-0.5f, 0.5f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[3] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = m_bodies[0];
|
||||
jd.bodyB = m_bodies[1];
|
||||
jd.localAnchorA.Set(0.5f, 0.0f);
|
||||
jd.localAnchorB.Set(-0.5f, 0.0f);;
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[4] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = m_bodies[1];
|
||||
jd.bodyB = m_bodies[2];
|
||||
jd.localAnchorA.Set(0.0f, 0.5f);
|
||||
jd.localAnchorB.Set(0.0f, -0.5f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[5] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = m_bodies[2];
|
||||
jd.bodyB = m_bodies[3];
|
||||
jd.localAnchorA.Set(-0.5f, 0.0f);
|
||||
jd.localAnchorB.Set(0.5f, 0.0f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[6] = m_world->CreateJoint(&jd);
|
||||
|
||||
jd.bodyA = m_bodies[3];
|
||||
jd.bodyB = m_bodies[0];
|
||||
jd.localAnchorA.Set(0.0f, -0.5f);
|
||||
jd.localAnchorB.Set(0.0f, 0.5f);
|
||||
p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
|
||||
p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
|
||||
d = p2 - p1;
|
||||
jd.length = d.Length();
|
||||
m_joints[7] = m_world->CreateJoint(&jd);
|
||||
}
|
||||
}
|
||||
|
||||
void Keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_B:
|
||||
for (int32 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (m_bodies[i])
|
||||
{
|
||||
m_world->DestroyBody(m_bodies[i]);
|
||||
m_bodies[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GLFW_KEY_J:
|
||||
for (int32 i = 0; i < 8; ++i)
|
||||
{
|
||||
if (m_joints[i])
|
||||
{
|
||||
m_world->DestroyJoint(m_joints[i]);
|
||||
m_joints[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Step(Settings* settings)
|
||||
{
|
||||
Test::Step(settings);
|
||||
g_debugDraw.DrawString(5, m_textLine, "This demonstrates a soft distance joint.");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
g_debugDraw.DrawString(5, m_textLine, "Press: (b) to delete a body, (j) to delete a joint");
|
||||
m_textLine += DRAW_STRING_NEW_LINE;
|
||||
}
|
||||
|
||||
void JointDestroyed(b2Joint* joint)
|
||||
{
|
||||
for (int32 i = 0; i < 8; ++i)
|
||||
{
|
||||
if (m_joints[i] == joint)
|
||||
{
|
||||
m_joints[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Web;
|
||||
}
|
||||
|
||||
b2Body* m_bodies[4];
|
||||
b2Joint* m_joints[8];
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user