add hello world example and edit source tree
This commit is contained in:
128
examples/hello_world/main.cpp
Normal file
128
examples/hello_world/main.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 <bounce\bounce.h>
|
||||
|
||||
// We don't care for a profiler. This definition does nothing.
|
||||
bool b3PushProfileScope(const char* name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't care for a profiler. This definition does nothing.
|
||||
void b3PopProfileScope()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// This example shows how to setup and run a simple simulation
|
||||
// using Bounce.
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// The world gravity.
|
||||
const b3Vec3 gravity(0.0f, -9.8f, 0.0f);
|
||||
|
||||
// The fixed time step size.
|
||||
const float32 timeStep = 1.0f / 60.0f;
|
||||
|
||||
// Number of iterations for the velocity constraint solver.
|
||||
const u32 velocityIterations = 8;
|
||||
|
||||
// Number of iterations for the position constraint solver.
|
||||
const u32 positionIterations = 2;
|
||||
|
||||
// The world-> We allocate it using the heap but you can to it
|
||||
// on the stack if the stack is sufficiently large.
|
||||
b3World* world = new b3World();
|
||||
world->SetGravity(gravity);
|
||||
|
||||
// Create a static ground body at the world origin.
|
||||
b3BodyDef groundDef;
|
||||
b3Body* ground = world->CreateBody(groundDef);
|
||||
|
||||
// Create a box positioned at the world origin and
|
||||
// aligned with the world frame.
|
||||
b3BoxHull groundBox;
|
||||
|
||||
// Set the ground box dimensions using a linear scale transform.
|
||||
b3Transform scale;
|
||||
scale.position.SetZero();
|
||||
scale.rotation = b3Diagonal(10.0f, 1.0f, 10.0f);
|
||||
groundBox.SetTransform(scale);
|
||||
|
||||
// Create the box physics wrapper.
|
||||
b3HullShape groundShape;
|
||||
groundShape.m_hull = &groundBox;
|
||||
|
||||
// Add the box to the ground body.
|
||||
b3ShapeDef groundBoxDef;
|
||||
groundBoxDef.shape = &groundShape;
|
||||
ground->CreateShape(groundBoxDef);
|
||||
|
||||
// Create a dynamic body.
|
||||
b3BodyDef bodyDef;
|
||||
bodyDef.type = e_dynamicBody;
|
||||
|
||||
// Position the body 10 meters high from the world origin.
|
||||
bodyDef.position.Set(0.0f, 10.0f, 0.0f);
|
||||
|
||||
// Set the initial angular velocity to pi radians (180 degrees) per second.
|
||||
bodyDef.angularVelocity.Set(0.0f, B3_PI, 0.0f);
|
||||
|
||||
b3Body* body = world->CreateBody(bodyDef);
|
||||
|
||||
// Create a unit box positioned at the world origin and
|
||||
// aligned with the world frame.
|
||||
b3BoxHull bodyBox;
|
||||
bodyBox.SetIdentity();
|
||||
|
||||
// Create the box physics wrapper.
|
||||
b3HullShape bodyShape;
|
||||
bodyShape.m_hull = &bodyBox;
|
||||
|
||||
// Add the box to the body.
|
||||
b3ShapeDef bodyBoxDef;
|
||||
bodyBoxDef.shape = &bodyShape;
|
||||
bodyBoxDef.density = 1.0f;
|
||||
body->CreateShape(bodyBoxDef);
|
||||
|
||||
// Run a small game loop of 60 frames length.
|
||||
for (u32 i = 0; i < 60; ++i)
|
||||
{
|
||||
// Perform a time step of the world in this frame.
|
||||
world->Step(timeStep, velocityIterations, positionIterations);
|
||||
|
||||
// Read the body position and orientation in this frame.
|
||||
b3Vec3 position = body->GetPosition();
|
||||
b3Quat orientation = body->GetOrientation();
|
||||
|
||||
// Decode the axis and angle of rotation about it from the quaternion.
|
||||
b3Vec3 axis;
|
||||
float32 angle;
|
||||
orientation.GetAxisAngle(&axis, &angle);
|
||||
|
||||
// Visualize the body state in this frame.
|
||||
printf("position = %.2f %.2f %.2f\n", position.x, position.y, position.z);
|
||||
printf("axis = %.2f %.2f %.2f, angle = %.2f\n\n", axis.x, axis.y, axis.z, angle);
|
||||
}
|
||||
|
||||
// Now destroy the bodies since the world manages their lifetime.
|
||||
delete world;
|
||||
|
||||
return 0;
|
||||
}
|
1462
examples/testbed/framework/debug_draw.cpp
Normal file
1462
examples/testbed/framework/debug_draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
120
examples/testbed/framework/debug_draw.h
Normal file
120
examples/testbed/framework/debug_draw.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 DEBUG_DRAW_H
|
||||
#define DEBUG_DRAW_H
|
||||
|
||||
#include <bounce/bounce.h>
|
||||
#include "mat44.h"
|
||||
|
||||
struct DrawPoints;
|
||||
struct DrawLines;
|
||||
struct DrawTriangles;
|
||||
struct DrawWire;
|
||||
struct DrawSolid;
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera()
|
||||
{
|
||||
m_center.Set(0.0f, 5.0f, 0.0f);
|
||||
m_q.SetIdentity();
|
||||
m_width = 1024.0f;
|
||||
m_height = 768.0f;
|
||||
m_zNear = 1.0f;
|
||||
m_zFar = 500.0f;
|
||||
m_fovy = 0.25f * B3_PI;
|
||||
m_zoom = 10.0f;
|
||||
}
|
||||
|
||||
Mat44 BuildProjectionMatrix() const;
|
||||
Mat44 BuildViewMatrix() const;
|
||||
b3Transform BuildViewTransform() const;
|
||||
Mat44 BuildWorldMatrix() const;
|
||||
b3Transform BuildWorldTransform() const;
|
||||
|
||||
b3Vec2 ConvertWorldToScreen(const b3Vec3& pw) const;
|
||||
Ray3 ConvertScreenToWorld(const b3Vec2& ps) const;
|
||||
|
||||
float32 m_zoom;
|
||||
b3Vec3 m_center;
|
||||
b3Quat m_q;
|
||||
float32 m_width, m_height;
|
||||
float32 m_fovy;
|
||||
float32 m_zNear;
|
||||
float32 m_zFar;
|
||||
};
|
||||
|
||||
class DebugDraw : public b3Draw
|
||||
{
|
||||
public:
|
||||
DebugDraw();
|
||||
~DebugDraw();
|
||||
|
||||
void DrawPoint(const b3Vec3& p, float32 size, const b3Color& color);
|
||||
|
||||
void DrawSegment(const b3Vec3& p1, const b3Vec3& p2, const b3Color& color);
|
||||
|
||||
void DrawTriangle(const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color);
|
||||
|
||||
void DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color);
|
||||
|
||||
void DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color);
|
||||
|
||||
void DrawSolidPolygon(const b3Vec3& normal, const b3Vec3* vertices, u32 count, const b3Color& color);
|
||||
|
||||
void DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color);
|
||||
|
||||
void DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color);
|
||||
|
||||
void DrawSphere(const b3Vec3& center, float32 radius, const b3Color& color);
|
||||
|
||||
void DrawSolidSphere(const b3Vec3& center, float32 radius, const b3Color& color);
|
||||
|
||||
void DrawAABB(const b3AABB3& aabb, const b3Color& color);
|
||||
|
||||
void DrawTransform(const b3Transform& xf);
|
||||
|
||||
//
|
||||
void DrawString(const char* string, const b3Color& color, ...);
|
||||
|
||||
void DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf);
|
||||
|
||||
void DrawCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf);
|
||||
|
||||
void DrawHull(const b3HullShape* s, const b3Color& c, const b3Transform& xf);
|
||||
|
||||
void DrawMesh(const b3MeshShape* s, const b3Color& c, const b3Transform& xf);
|
||||
|
||||
void DrawShape(const b3Shape* s, const b3Color& c, const b3Transform& xf);
|
||||
|
||||
void Draw(const b3World& world);
|
||||
|
||||
void Submit();
|
||||
private:
|
||||
friend struct DrawShapes;
|
||||
|
||||
DrawPoints* m_points;
|
||||
DrawLines* m_lines;
|
||||
DrawTriangles* m_triangles;
|
||||
DrawWire* m_wire;
|
||||
DrawSolid* m_solid;
|
||||
};
|
||||
|
||||
#endif
|
493
examples/testbed/framework/main.cpp
Normal file
493
examples/testbed/framework/main.cpp
Normal file
@ -0,0 +1,493 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 <glad/glad.h>
|
||||
#include <glfw/glfw3.h>
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/imgui_impl_glfw_gl3.h>
|
||||
|
||||
#include <testbed/tests/test.h>
|
||||
|
||||
GLFWwindow* g_window;
|
||||
Settings g_settings;
|
||||
Test* g_test;
|
||||
u32 g_testCount;
|
||||
Camera g_camera;
|
||||
DebugDraw* g_debugDraw;
|
||||
Profiler* g_profiler;
|
||||
bool g_leftDown;
|
||||
bool g_rightDown;
|
||||
bool g_shiftDown;
|
||||
b3Vec2 g_ps0;
|
||||
|
||||
void WindowSize(int w, int h)
|
||||
{
|
||||
g_camera.m_width = float32(w);
|
||||
g_camera.m_height = float32(h);
|
||||
}
|
||||
|
||||
void MouseMove(GLFWwindow* w, double x, double y)
|
||||
{
|
||||
b3Vec2 ps;
|
||||
ps.Set(float32(x), float32(y));
|
||||
|
||||
b3Vec2 dp = ps - g_ps0;
|
||||
g_ps0 = ps;
|
||||
|
||||
Ray3 pw = g_camera.ConvertScreenToWorld(ps);
|
||||
|
||||
float32 nx = b3Clamp(dp.x, -1.0f, 1.0f);
|
||||
float32 ny = b3Clamp(dp.y, -1.0f, 1.0f);
|
||||
|
||||
if (g_shiftDown)
|
||||
{
|
||||
if (g_leftDown)
|
||||
{
|
||||
// Negate angles to do positive rotations (CCW) of the world.
|
||||
float32 angleX = 0.005f * B3_PI * -nx;
|
||||
float32 angleY = 0.005f * B3_PI * -ny;
|
||||
|
||||
b3Quat qx(b3Vec3(1.0f, 0.0f, 0.0f), angleY);
|
||||
b3Quat qy(b3Vec3(0.0f, 1.0f, 0.0f), angleX);
|
||||
|
||||
g_camera.m_q = qy * g_camera.m_q;
|
||||
g_camera.m_q = g_camera.m_q * qx;
|
||||
g_camera.m_q.Normalize();
|
||||
}
|
||||
|
||||
if (g_rightDown)
|
||||
{
|
||||
b3Transform xf = g_camera.BuildWorldTransform();
|
||||
g_camera.m_center += 0.2f * nx * xf.rotation.x;
|
||||
g_camera.m_center += 0.2f * -ny * xf.rotation.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_test->MouseMove(pw);
|
||||
}
|
||||
}
|
||||
|
||||
void MouseWheel(GLFWwindow* w, double dx, double dy)
|
||||
{
|
||||
float32 n = b3Clamp(float32(dy), -1.0f, 1.0f);
|
||||
if (g_shiftDown)
|
||||
{
|
||||
g_camera.m_zoom += 0.5f * -n;
|
||||
}
|
||||
}
|
||||
|
||||
void MouseButton(GLFWwindow* w, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
glfwGetCursorPos(w, &x, &y);
|
||||
b3Vec2 p;
|
||||
p.Set(float32(x), float32(y));
|
||||
|
||||
Ray3 pw = g_camera.ConvertScreenToWorld(p);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case GLFW_PRESS:
|
||||
{
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
||||
{
|
||||
g_leftDown = true;
|
||||
|
||||
if (g_shiftDown == false)
|
||||
{
|
||||
g_test->MouseLeftDown(pw);
|
||||
}
|
||||
}
|
||||
|
||||
if (button == GLFW_MOUSE_BUTTON_RIGHT)
|
||||
{
|
||||
g_rightDown = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case GLFW_RELEASE:
|
||||
{
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT)
|
||||
{
|
||||
g_leftDown = false;
|
||||
|
||||
if (g_shiftDown == false)
|
||||
{
|
||||
g_test->MouseLeftUp(pw);
|
||||
}
|
||||
}
|
||||
|
||||
if (button == GLFW_MOUSE_BUTTON_RIGHT)
|
||||
{
|
||||
g_rightDown = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyButton(GLFWwindow* w, int button, int scancode, int action, int mods)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case GLFW_PRESS:
|
||||
{
|
||||
if (button == GLFW_KEY_LEFT_SHIFT)
|
||||
{
|
||||
g_shiftDown = true;
|
||||
g_test->KeyDown(button);
|
||||
}
|
||||
|
||||
if (g_shiftDown)
|
||||
{
|
||||
if (button == GLFW_KEY_DOWN)
|
||||
{
|
||||
g_camera.m_zoom += 0.05f;
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_UP)
|
||||
{
|
||||
g_camera.m_zoom -= 0.05f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_test->KeyDown(button);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case GLFW_RELEASE:
|
||||
{
|
||||
if (button == GLFW_KEY_LEFT_SHIFT)
|
||||
{
|
||||
g_shiftDown = false;
|
||||
}
|
||||
|
||||
if (g_shiftDown == false)
|
||||
{
|
||||
g_test->KeyUp(button);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Char(GLFWwindow* w, unsigned int codepoint)
|
||||
{
|
||||
ImGui_ImplGlfwGL3_CharCallback(w, codepoint);
|
||||
}
|
||||
|
||||
void CreateInterface()
|
||||
{
|
||||
ImGui_ImplGlfwGL3_Init(g_window, false);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts[0].AddFontDefault();
|
||||
}
|
||||
|
||||
void DestroyInterface()
|
||||
{
|
||||
ImGui_ImplGlfwGL3_Shutdown();
|
||||
}
|
||||
|
||||
bool GetTestName(void*, int idx, const char** name)
|
||||
{
|
||||
*name = g_tests[idx].name;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Interface()
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImVec2(g_camera.m_width, 0.0f));
|
||||
ImGui::SetNextWindowSize(ImVec2(250.0f, g_camera.m_height));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
|
||||
ImGui::Begin("Controls", NULL, ImVec2(0.0f, 0.0f), 0.25f, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
ImGui::PushItemWidth(-1.0f);
|
||||
|
||||
ImGui::Text("Test");
|
||||
if (ImGui::Combo("##Test", &g_settings.testID, GetTestName, NULL, g_testCount, g_testCount))
|
||||
{
|
||||
delete g_test;
|
||||
g_test = g_tests[g_settings.testID].create();
|
||||
g_settings.lastTestID = -1;
|
||||
}
|
||||
|
||||
ImVec2 buttonSize = ImVec2(-1, 0);
|
||||
if (ImGui::Button("Restart", buttonSize))
|
||||
{
|
||||
g_settings.lastTestID = -1;
|
||||
}
|
||||
if (ImGui::Button("Previous", buttonSize))
|
||||
{
|
||||
g_settings.testID = b3Clamp(g_settings.testID - 1, 0, int(g_testCount) - 1);
|
||||
g_settings.lastTestID = -1;
|
||||
}
|
||||
if (ImGui::Button("Next", buttonSize))
|
||||
{
|
||||
g_settings.testID = b3Clamp(g_settings.testID + 1, 0, int(g_testCount) - 1);
|
||||
g_settings.lastTestID = -1;
|
||||
}
|
||||
if (ImGui::Button("Exit", buttonSize))
|
||||
{
|
||||
glfwSetWindowShouldClose(g_window, true);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Step");
|
||||
|
||||
ImGui::Text("Hertz");
|
||||
ImGui::SliderFloat("##Hertz", &g_settings.hertz, 0.0f, 240.0f, "%.1f");
|
||||
ImGui::Text("Velocity Iterations");
|
||||
ImGui::SliderInt("##Velocity Iterations", &g_settings.velocityIterations, 0, 50);
|
||||
ImGui::Text("Position Iterations");
|
||||
ImGui::SliderInt("#Position Iterations", &g_settings.positionIterations, 0, 50);
|
||||
ImGui::Checkbox("Sleep", &g_settings.sleep);
|
||||
ImGui::Checkbox("Warm Start", &g_settings.warmStart);
|
||||
//ImGui::Checkbox("Convex Cache", &g_settings.convexCache);
|
||||
|
||||
if (ImGui::Button("Play/Pause", buttonSize))
|
||||
{
|
||||
g_settings.pause = !g_settings.pause;
|
||||
}
|
||||
if (ImGui::Button("Single Step", buttonSize))
|
||||
{
|
||||
g_settings.pause = true;
|
||||
g_settings.singleStep = true;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("View");
|
||||
ImGui::Checkbox("Grid", &g_settings.drawGrid);
|
||||
ImGui::Checkbox("Vertices and Edges", &g_settings.drawVerticesEdges);
|
||||
ImGui::Checkbox("Faces", &g_settings.drawFaces);
|
||||
ImGui::Checkbox("Center of Masses", &g_settings.drawCenterOfMasses);
|
||||
ImGui::Checkbox("Bounding Boxes", &g_settings.drawBounds);
|
||||
ImGui::Checkbox("Joints", &g_settings.drawJoints);
|
||||
ImGui::Checkbox("Contact Points", &g_settings.drawContactPoints);
|
||||
ImGui::Checkbox("Contact Normals", &g_settings.drawContactNormals);
|
||||
ImGui::Checkbox("Contact Tangents", &g_settings.drawContactTangents);
|
||||
ImGui::Checkbox("Statistics", &g_settings.drawStats);
|
||||
ImGui::Checkbox("Profile", &g_settings.drawProfile);
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
if (g_settings.drawGrid)
|
||||
{
|
||||
int n = 20;
|
||||
|
||||
b3Vec3 t;
|
||||
t.x = -0.5f * float32(n);
|
||||
t.y = 0.0f;
|
||||
t.z = -0.5f * float32(n);
|
||||
|
||||
b3Color color(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
for (int i = 0; i < n; i += 1)
|
||||
{
|
||||
for (int j = 0; j < n; j += 1)
|
||||
{
|
||||
b3Vec3 vs[4];
|
||||
vs[0] = b3Vec3((float)i, 0.0f, (float)j);
|
||||
vs[1] = b3Vec3((float)i, 0.0f, (float)j + 1);
|
||||
vs[2] = b3Vec3((float)i + 1, 0.0f, (float)j + 1);
|
||||
vs[3] = b3Vec3((float)i + 1, 0.0f, (float)j);
|
||||
|
||||
for (u32 k = 0; k < 4; ++k)
|
||||
{
|
||||
vs[k] += t;
|
||||
}
|
||||
|
||||
g_debugDraw->DrawPolygon(vs, 4, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_settings.testID != g_settings.lastTestID)
|
||||
{
|
||||
delete g_test;
|
||||
g_settings.lastTestID = g_settings.testID;
|
||||
g_test = g_tests[g_settings.testID].create();
|
||||
g_settings.pause = true;
|
||||
}
|
||||
|
||||
g_test->Step();
|
||||
g_debugDraw->Submit();
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
glFrontFace(GL_CCW);
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
glClearDepth(1.0f);
|
||||
|
||||
double t1 = glfwGetTime();
|
||||
double frameTime = 0.0;
|
||||
|
||||
while (glfwWindowShouldClose(g_window) == 0)
|
||||
{
|
||||
int width, height;
|
||||
glfwGetWindowSize(g_window, &width, &height);
|
||||
g_camera.m_width = float32(width) - 250.0f;
|
||||
g_camera.m_height = float32(height);
|
||||
|
||||
glViewport(0, 0, width - 250, height);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
ImGui_ImplGlfwGL3_NewFrame();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||
ImGui::SetNextWindowSize(ImVec2((float)g_camera.m_width, (float)g_camera.m_height));
|
||||
ImGui::Begin("Overlay", NULL, ImVec2(0, 0), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar);
|
||||
ImGui::SetCursorPos(ImVec2(5, (float)g_camera.m_height - 20));
|
||||
ImGui::Text("%.1f ms", 1000.0 * frameTime);
|
||||
ImGui::End();
|
||||
|
||||
Interface();
|
||||
Step();
|
||||
|
||||
double t = glfwGetTime();
|
||||
frameTime = t - t1;
|
||||
t1 = t;
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
glfwSwapBuffers(g_window);
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** args)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// Report memory leaks
|
||||
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
|
||||
#endif
|
||||
|
||||
if (glfwInit() == 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize GLFW\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create window
|
||||
extern b3Version b3_version;
|
||||
char title[256];
|
||||
sprintf(title, "Bounce Testbed Version %d.%d.%d", b3_version.major, b3_version.minor, b3_version.revision);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
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
|
||||
|
||||
g_window = glfwCreateWindow(1024, 768, title, NULL, NULL);
|
||||
if (g_window == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to open GLFW window\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(g_window);
|
||||
glfwSetCursorPosCallback(g_window, MouseMove);
|
||||
glfwSetScrollCallback(g_window, MouseWheel);
|
||||
glfwSetMouseButtonCallback(g_window, MouseButton);
|
||||
glfwSetKeyCallback(g_window, KeyButton);
|
||||
glfwSetCharCallback(g_window, Char);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
if (gladLoadGL() == 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to load OpenGL extensions\n");
|
||||
fprintf(stderr, "Error: %d\n", glad_glGetError());
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
g_leftDown = false;
|
||||
g_rightDown = false;
|
||||
g_shiftDown = false;
|
||||
g_ps0.SetZero();
|
||||
|
||||
// Create UI
|
||||
CreateInterface();
|
||||
|
||||
// Create profiler
|
||||
g_profiler = new Profiler();
|
||||
|
||||
// Create renderer
|
||||
g_debugDraw = new DebugDraw();
|
||||
|
||||
// Run the testbed
|
||||
g_testCount = 0;
|
||||
while (g_tests[g_testCount].create != NULL)
|
||||
{
|
||||
++g_testCount;
|
||||
}
|
||||
g_test = NULL;
|
||||
|
||||
Run();
|
||||
|
||||
// Destroy the last test
|
||||
if (g_test)
|
||||
{
|
||||
delete g_test;
|
||||
g_test = NULL;
|
||||
}
|
||||
|
||||
// Destroy renderer
|
||||
delete g_debugDraw;
|
||||
|
||||
// Destroy profiler
|
||||
delete g_profiler;
|
||||
|
||||
// Destroy UI
|
||||
DestroyInterface();
|
||||
|
||||
// Destroy g_window
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
131
examples/testbed/framework/mat44.h
Normal file
131
examples/testbed/framework/mat44.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 MAT44_H
|
||||
#define MAT44_H
|
||||
|
||||
#include <bounce/bounce.h>
|
||||
|
||||
struct Vec4
|
||||
{
|
||||
Vec4() { }
|
||||
Vec4(float32 _x, float32 _y, float32 _z, float32 _w) : x(_x), y(_y), z(_z), w(_w) { }
|
||||
|
||||
void SetZero()
|
||||
{
|
||||
x = y = z = w = 0.0f;
|
||||
}
|
||||
|
||||
void Set(float32 _x, float32 _y, float32 _z, float32 _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
}
|
||||
|
||||
float32 x, y, z, w;
|
||||
};
|
||||
|
||||
inline Vec4 operator+(const Vec4& a, const Vec4& b)
|
||||
{
|
||||
return Vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
|
||||
}
|
||||
|
||||
inline Vec4 operator*(float32 s, const Vec4& v)
|
||||
{
|
||||
return Vec4(s * v.x, s * v.y, s * v.z, s * v.w);
|
||||
}
|
||||
|
||||
struct Mat44
|
||||
{
|
||||
Mat44() { }
|
||||
Mat44(const Vec4& _x, const Vec4& _y, const Vec4& _z, const Vec4& _w) : x(_x), y(_y), z(_z), w(_w) { }
|
||||
|
||||
void SetIdentity()
|
||||
{
|
||||
x.Set(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
y.Set(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
z.Set(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
w.Set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Vec4 x, y, z, w;
|
||||
};
|
||||
|
||||
inline Vec4 operator*(const Mat44& A, const Vec4& v)
|
||||
{
|
||||
return v.x * A.x + v.y * A.y + v.z * A.z + v.w * A.w;
|
||||
}
|
||||
|
||||
inline b3Vec3 operator*(const Mat44& A, const b3Vec3& v)
|
||||
{
|
||||
Vec4 q = v.x * A.x + v.y * A.y + v.z * A.z + A.w;
|
||||
return b3Vec3(q.x, q.y, q.z);
|
||||
}
|
||||
|
||||
inline Mat44 operator*(const Mat44& A, const Mat44& B)
|
||||
{
|
||||
return Mat44(A * B.x, A * B.y, A * B.z, A * B.w);
|
||||
}
|
||||
|
||||
inline Mat44 GetMat44(const b3Transform& T)
|
||||
{
|
||||
return Mat44(
|
||||
Vec4(T.rotation.x.x, T.rotation.x.y, T.rotation.x.z, 0.0f),
|
||||
Vec4(T.rotation.y.x, T.rotation.y.y, T.rotation.y.z, 0.0f),
|
||||
Vec4(T.rotation.z.x, T.rotation.z.y, T.rotation.z.z, 0.0f),
|
||||
Vec4(T.position.x, T.position.y, T.position.z, 1.0f));
|
||||
}
|
||||
|
||||
inline b3Transform GetTransform(const Mat44& T)
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.rotation.x.Set(T.x.x, T.x.y, T.x.z);
|
||||
xf.rotation.y.Set(T.y.x, T.y.y, T.y.z);
|
||||
xf.rotation.z.Set(T.z.x, T.z.y, T.z.z);
|
||||
xf.position.Set(T.w.x, T.w.y, T.w.z);
|
||||
return xf;
|
||||
}
|
||||
|
||||
inline float32 RandomFloat(float32 a, float32 b)
|
||||
{
|
||||
float32 x = float32(rand()) / float32(RAND_MAX);
|
||||
float32 diff = b - a;
|
||||
float32 r = x * diff;
|
||||
return a + r;
|
||||
}
|
||||
|
||||
struct Ray3
|
||||
{
|
||||
b3Vec3 Start() const
|
||||
{
|
||||
return origin;
|
||||
}
|
||||
|
||||
b3Vec3 End() const
|
||||
{
|
||||
return origin + fraction * direction;
|
||||
}
|
||||
|
||||
b3Vec3 direction;
|
||||
b3Vec3 origin;
|
||||
float32 fraction;
|
||||
};
|
||||
|
||||
#endif
|
217
examples/testbed/framework/profiler.cpp
Normal file
217
examples/testbed/framework/profiler.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 <testbed/framework/profiler.h>
|
||||
#include <bounce/common/profiler.h>
|
||||
#include <bounce/common/time.h>
|
||||
#include <bounce/common/template/queue.h>
|
||||
|
||||
struct Event
|
||||
{
|
||||
i32 tid;
|
||||
i32 pid;
|
||||
const char* name;
|
||||
float64 t0;
|
||||
float64 t1;
|
||||
Event* parent;
|
||||
};
|
||||
|
||||
static b3Time time;
|
||||
static b3BoundedQueue<Event, 256> events;
|
||||
static Event* top = NULL;
|
||||
|
||||
bool b3PushProfileScope(const char* name)
|
||||
{
|
||||
time.Update();
|
||||
|
||||
Event e;
|
||||
e.tid = -1;
|
||||
e.pid = -1;
|
||||
e.t0 = time.GetCurrentMilis();
|
||||
e.t1 = 0;
|
||||
e.name = name;
|
||||
e.parent = top;
|
||||
|
||||
Event* back = events.Push(e);
|
||||
if (back)
|
||||
{
|
||||
top = back;
|
||||
}
|
||||
|
||||
return back != NULL;
|
||||
}
|
||||
|
||||
void b3PopProfileScope()
|
||||
{
|
||||
B3_ASSERT(top);
|
||||
B3_ASSERT(top->t1 == 0);
|
||||
|
||||
time.Update();
|
||||
top->t1 = time.GetCurrentMilis();
|
||||
B3_ASSERT(top->t1 != 0);
|
||||
top = top->parent;
|
||||
}
|
||||
|
||||
void ProfileBegin()
|
||||
{
|
||||
B3_ASSERT(events.IsEmpty());
|
||||
}
|
||||
|
||||
void ProfileEnd()
|
||||
{
|
||||
ProfileBeginEvents();
|
||||
|
||||
while (events.IsEmpty() == false)
|
||||
{
|
||||
const Event& e = events.Front();
|
||||
events.Pop();
|
||||
|
||||
ProfileEvent(e.tid, e.pid, e.name, e.t0, e_begin);
|
||||
ProfileEvent(e.tid, e.pid, e.name, e.t1, e_end);
|
||||
ProfileEvent(e.tid, e.pid, e.name, e.t1 - e.t0);
|
||||
}
|
||||
|
||||
B3_ASSERT(events.IsEmpty());
|
||||
|
||||
ProfileEndEvents();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#define PROFILER_SCREEN 1
|
||||
#define PROFILER_JSON 2
|
||||
|
||||
#define PROFILER_OUTPUT PROFILER_SCREEN
|
||||
|
||||
#if PROFILER_OUTPUT == PROFILER_SCREEN
|
||||
|
||||
extern Profiler* g_profiler;
|
||||
|
||||
void ProfileBeginEvents()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ProfileEvent(i32 tid, i32 pid, const char* name, float64 time, ProfileType type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ProfileEvent(i32 tid, i32 pid, const char* name, float64 elapsed)
|
||||
{
|
||||
g_profiler->Add(name, elapsed);
|
||||
}
|
||||
|
||||
void ProfileEndEvents()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#elif PROFILER_OUTPUT == PROFILER_JSON
|
||||
|
||||
#include <rapidjson/filewritestream.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
static FILE* file = NULL;
|
||||
static FileWriteStream* stream = NULL;
|
||||
static Writer<FileWriteStream>* writer = NULL;
|
||||
|
||||
#define STRING(x) String(x, sizeof(x) - 1)
|
||||
|
||||
void ProfileBeginEvents()
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
file = fopen("profile.json", "wt");
|
||||
if (!file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static char buffer[512];
|
||||
stream = new FileWriteStream(file, buffer, sizeof(buffer));
|
||||
|
||||
writer = new Writer<FileWriteStream>(*stream);
|
||||
|
||||
writer->StartObject();
|
||||
writer->STRING("traceEvents");
|
||||
writer->StartArray();
|
||||
}
|
||||
|
||||
void ProfileEvent(i32 tid, i32 pid, const char* name, float64 time, ProfileType type)
|
||||
{
|
||||
if (!writer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char* phase = 0;
|
||||
switch (type)
|
||||
{
|
||||
case ProfileType::e_begin: phase = "B"; break;
|
||||
case ProfileType::e_end: phase = "E"; break;
|
||||
default: B3_ASSERT(false);
|
||||
}
|
||||
|
||||
float64 scale = 1000.0;
|
||||
|
||||
writer->StartObject();
|
||||
writer->STRING("pid"); writer->Int(pid);
|
||||
writer->STRING("tid"); writer->Int(tid);
|
||||
writer->STRING("ts"); writer->Int64((u64)(time * scale));
|
||||
writer->STRING("ph"); writer->String(phase, 1);
|
||||
writer->STRING("cat"); writer->STRING("physics");
|
||||
writer->STRING("name"); writer->String(name, strlen(name));
|
||||
writer->STRING("args"); writer->StartObject(); writer->EndObject();
|
||||
writer->EndObject();
|
||||
}
|
||||
|
||||
void ProfileEvent(i32 tid, i32 pid, const char* name, float64 elapsed)
|
||||
{
|
||||
}
|
||||
|
||||
void ProfileEndEvents()
|
||||
{
|
||||
if (!writer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer->EndArray();
|
||||
writer->EndObject();
|
||||
|
||||
delete writer;
|
||||
writer = NULL;
|
||||
|
||||
delete stream;
|
||||
stream = NULL;
|
||||
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
#undef STRING
|
||||
|
||||
#else
|
||||
|
||||
#endif
|
83
examples/testbed/framework/profiler.h
Normal file
83
examples/testbed/framework/profiler.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 PROFILER_H
|
||||
#define PROFILER_H
|
||||
|
||||
#include <bounce/common/math/math.h>
|
||||
#include <bounce/common/template/array.h>
|
||||
|
||||
enum ProfileType
|
||||
{
|
||||
e_begin,
|
||||
e_end
|
||||
};
|
||||
|
||||
void ProfileBeginEvents();
|
||||
|
||||
void ProfileEvent(i32 tid, i32 pid, const char* name, float64 time, ProfileType type);
|
||||
void ProfileEvent(i32 tid, i32 pid, const char* name, float64 elapsed);
|
||||
|
||||
void ProfileEndEvents();
|
||||
|
||||
void ProfileBegin();
|
||||
void ProfileEnd();
|
||||
|
||||
struct ProfileRecord
|
||||
{
|
||||
float64 elapsed;
|
||||
float64 maxElapsed;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
class Profiler
|
||||
{
|
||||
public:
|
||||
void Clear()
|
||||
{
|
||||
for (u32 i = 0; i < m_records.Count(); ++i)
|
||||
{
|
||||
m_records[i].elapsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Add(const char* name, float64 elapsed)
|
||||
{
|
||||
for (u32 i = 0; i < m_records.Count(); ++i)
|
||||
{
|
||||
ProfileRecord& r = m_records[i];
|
||||
if (r.name == name)
|
||||
{
|
||||
r.elapsed += elapsed;
|
||||
r.maxElapsed = b3Max(r.maxElapsed, r.elapsed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ProfileRecord r;
|
||||
r.elapsed = elapsed;
|
||||
r.maxElapsed = 0;
|
||||
r.name = name;
|
||||
|
||||
m_records.PushBack(r);
|
||||
}
|
||||
|
||||
b3StackArray<ProfileRecord, 256> m_records;
|
||||
};
|
||||
|
||||
#endif
|
499
examples/testbed/framework/test.cpp
Normal file
499
examples/testbed/framework/test.cpp
Normal file
@ -0,0 +1,499 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 <testbed/tests/test.h>
|
||||
|
||||
extern u32 b3_allocCalls, b3_maxAllocCalls;
|
||||
extern u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters;
|
||||
extern u32 b3_convexCalls, b3_convexCacheHits;
|
||||
extern bool b3_enableConvexCache;
|
||||
extern b3Draw* b3_debugDraw;
|
||||
|
||||
extern Settings g_settings;
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Profiler* g_profiler;
|
||||
|
||||
Test::Test()
|
||||
{
|
||||
b3_allocCalls = 0;
|
||||
b3_gjkCalls = 0;
|
||||
b3_gjkIters = 0;
|
||||
b3_gjkMaxIters = 0;
|
||||
b3_convexCalls = 0;
|
||||
b3_convexCacheHits = 0;
|
||||
b3_enableConvexCache = g_settings.convexCache;
|
||||
b3_debugDraw = g_debugDraw;
|
||||
|
||||
m_world.SetContactListener(this);
|
||||
|
||||
g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.15f * B3_PI);
|
||||
g_camera.m_q = g_camera.m_q * b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.15f * B3_PI);
|
||||
g_camera.m_zoom = 50.0f;
|
||||
g_camera.m_center.SetZero();
|
||||
|
||||
m_rayHit.shape = NULL;
|
||||
m_mouseJoint = NULL;
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(50.0f, 1.0f, 50.0f);
|
||||
m_groundHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(1.0f, 1.0f, 1.0f);
|
||||
m_boxHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(1.0f, 5.0f, 1.0f);
|
||||
m_tallHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(2.0f, 4.0f, 0.5f);
|
||||
m_doorHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(25.0f, 0.5f, 25.0f);
|
||||
m_rampHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(1.0f, 0.5f, 3.0f);
|
||||
m_plankHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.position.SetZero();
|
||||
xf.rotation = b3Diagonal(4.05f, 2.0f * B3_LINEAR_SLOP, 4.05f);
|
||||
m_thinHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
const u32 w = 5;
|
||||
const u32 h = 5;
|
||||
|
||||
b3Vec3 t;
|
||||
t.x = -0.5f * float32(w);
|
||||
t.y = 0.0f;
|
||||
t.z = -0.5f * float32(h);
|
||||
|
||||
b3Mesh* mesh = m_meshes + e_clothMesh;
|
||||
|
||||
mesh->vertexCount = w * h;
|
||||
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
|
||||
|
||||
for (u32 i = 0; i < w; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < h; ++j)
|
||||
{
|
||||
u32 v1 = i * w + j;
|
||||
|
||||
b3Vec3 v;
|
||||
v.x = float32(i);
|
||||
v.y = RandomFloat(0.0f, 0.5f);
|
||||
v.z = float32(j);
|
||||
|
||||
v += t;
|
||||
|
||||
mesh->vertices[v1] = v;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->triangleCount = 2 * (w - 1) * (h - 1);
|
||||
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
|
||||
|
||||
u32 triangleCount = 0;
|
||||
for (u32 i = 0; i < w - 1; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < h - 1; ++j)
|
||||
{
|
||||
u32 v1 = i * w + j;
|
||||
u32 v2 = (i + 1) * w + j;
|
||||
u32 v3 = (i + 1) * w + (j + 1);
|
||||
u32 v4 = i * w + (j + 1);
|
||||
|
||||
B3_ASSERT(triangleCount < mesh->triangleCount);
|
||||
b3Triangle* t1 = mesh->triangles + triangleCount;
|
||||
++triangleCount;
|
||||
|
||||
t1->v1 = v3;
|
||||
t1->v2 = v2;
|
||||
t1->v3 = v1;
|
||||
|
||||
B3_ASSERT(triangleCount < mesh->triangleCount);
|
||||
b3Triangle* t2 = mesh->triangles + triangleCount;
|
||||
++triangleCount;
|
||||
|
||||
t2->v1 = v1;
|
||||
t2->v2 = v4;
|
||||
t2->v3 = v3;
|
||||
}
|
||||
}
|
||||
|
||||
B3_ASSERT(triangleCount == mesh->triangleCount);
|
||||
|
||||
mesh->BuildTree();
|
||||
}
|
||||
|
||||
{
|
||||
const u32 w = 50;
|
||||
const u32 h = 50;
|
||||
|
||||
b3Vec3 t;
|
||||
t.x = -0.5f * float32(w);
|
||||
t.y = 0.0f;
|
||||
t.z = -0.5f * float32(h);
|
||||
|
||||
b3Mesh* mesh = m_meshes + e_gridMesh;
|
||||
|
||||
mesh->vertexCount = w * h;
|
||||
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
|
||||
|
||||
for (u32 i = 0; i < w; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < h; ++j)
|
||||
{
|
||||
u32 v1 = i * w + j;
|
||||
|
||||
b3Vec3 v;
|
||||
v.x = float32(i);
|
||||
v.y = 0.0f;
|
||||
v.z = float32(j);
|
||||
|
||||
v += t;
|
||||
|
||||
mesh->vertices[v1] = v;
|
||||
}
|
||||
}
|
||||
|
||||
// 2 triangles per quad
|
||||
mesh->triangleCount = 2 * (w - 1) * (h - 1);
|
||||
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
|
||||
|
||||
u32 triangleCount = 0;
|
||||
for (u32 i = 0; i < w - 1; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < h - 1; ++j)
|
||||
{
|
||||
u32 v1 = i * w + j;
|
||||
u32 v2 = (i + 1) * w + j;
|
||||
u32 v3 = (i + 1) * w + (j + 1);
|
||||
u32 v4 = i * w + (j + 1);
|
||||
|
||||
B3_ASSERT(triangleCount < mesh->triangleCount);
|
||||
b3Triangle* t1 = mesh->triangles + triangleCount;
|
||||
++triangleCount;
|
||||
|
||||
t1->v1 = v3;
|
||||
t1->v2 = v2;
|
||||
t1->v3 = v1;
|
||||
|
||||
B3_ASSERT(triangleCount < mesh->triangleCount);
|
||||
b3Triangle* t2 = mesh->triangles + triangleCount;
|
||||
++triangleCount;
|
||||
|
||||
t2->v1 = v1;
|
||||
t2->v2 = v4;
|
||||
t2->v3 = v3;
|
||||
}
|
||||
}
|
||||
|
||||
B3_ASSERT(triangleCount == mesh->triangleCount);
|
||||
|
||||
mesh->BuildTree();
|
||||
}
|
||||
|
||||
{
|
||||
const u32 w = 50;
|
||||
const u32 h = 50;
|
||||
|
||||
b3Vec3 t;
|
||||
t.x = -0.5f * float32(w);
|
||||
t.y = 0.0f;
|
||||
t.z = -0.5f * float32(h);
|
||||
|
||||
b3Mesh* mesh = m_meshes + e_terrainMesh;
|
||||
|
||||
mesh->vertexCount = w * h;
|
||||
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
|
||||
|
||||
for (u32 i = 0; i < w; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < h; ++j)
|
||||
{
|
||||
u32 v1 = i * w + j;
|
||||
|
||||
b3Vec3 v;
|
||||
v.x = 2.0f * float32(i);
|
||||
v.y = RandomFloat(0.0f, 0.5f);
|
||||
v.z = 2.0f *float32(j);
|
||||
|
||||
v += t;
|
||||
|
||||
mesh->vertices[v1] = v;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->triangleCount = 2 * (w - 1) * (h - 1);
|
||||
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
|
||||
|
||||
u32 triangleCount = 0;
|
||||
for (u32 i = 0; i < w - 1; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < h - 1; ++j)
|
||||
{
|
||||
u32 v1 = i * w + j;
|
||||
u32 v2 = (i + 1) * w + j;
|
||||
u32 v3 = (i + 1) * w + (j + 1);
|
||||
u32 v4 = i * w + (j + 1);
|
||||
|
||||
B3_ASSERT(triangleCount < mesh->triangleCount);
|
||||
b3Triangle* t1 = mesh->triangles + triangleCount;
|
||||
++triangleCount;
|
||||
|
||||
t1->v1 = v3;
|
||||
t1->v2 = v2;
|
||||
t1->v3 = v1;
|
||||
|
||||
B3_ASSERT(triangleCount < mesh->triangleCount);
|
||||
b3Triangle* t2 = mesh->triangles + triangleCount;
|
||||
++triangleCount;
|
||||
|
||||
t2->v1 = v1;
|
||||
t2->v2 = v4;
|
||||
t2->v3 = v3;
|
||||
}
|
||||
}
|
||||
|
||||
B3_ASSERT(triangleCount == mesh->triangleCount);
|
||||
|
||||
mesh->BuildTree();
|
||||
}
|
||||
}
|
||||
|
||||
Test::~Test()
|
||||
{
|
||||
for (u32 i = 0; i < e_maxMeshes; ++i)
|
||||
{
|
||||
b3Free(m_meshes[i].vertices);
|
||||
b3Free(m_meshes[i].triangles);
|
||||
}
|
||||
}
|
||||
|
||||
void Test::BeginContact(b3Contact* contact)
|
||||
{
|
||||
}
|
||||
|
||||
void Test::EndContact(b3Contact* contact)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Test::PreSolve(b3Contact* contact)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Test::Step()
|
||||
{
|
||||
float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f;
|
||||
|
||||
if (g_settings.pause)
|
||||
{
|
||||
if (g_settings.singleStep)
|
||||
{
|
||||
g_settings.singleStep = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
dt = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
b3_allocCalls = 0;
|
||||
b3_gjkCalls = 0;
|
||||
b3_gjkIters = 0;
|
||||
b3_gjkMaxIters = 0;
|
||||
b3_convexCalls = 0;
|
||||
b3_convexCacheHits = 0;
|
||||
b3_enableConvexCache = g_settings.convexCache;
|
||||
|
||||
// Step
|
||||
ProfileBegin();
|
||||
|
||||
m_world.SetSleeping(g_settings.sleep);
|
||||
m_world.SetWarmStart(g_settings.warmStart);
|
||||
m_world.Step(dt, g_settings.velocityIterations, g_settings.positionIterations);
|
||||
|
||||
ProfileEnd();
|
||||
|
||||
// Draw World
|
||||
u32 drawFlags = 0;
|
||||
drawFlags += g_settings.drawBounds * b3Draw::e_aabbsFlag;
|
||||
drawFlags += g_settings.drawVerticesEdges * b3Draw::e_shapesFlag;
|
||||
drawFlags += g_settings.drawCenterOfMasses * b3Draw::e_centerOfMassesFlag;
|
||||
drawFlags += g_settings.drawJoints * b3Draw::e_jointsFlag;
|
||||
drawFlags += g_settings.drawContactPoints * b3Draw::e_contactPointsFlag;
|
||||
drawFlags += g_settings.drawContactNormals * b3Draw::e_contactNormalsFlag;
|
||||
drawFlags += g_settings.drawContactTangents * b3Draw::e_contactTangentsFlag;
|
||||
|
||||
g_debugDraw->SetFlags(drawFlags);
|
||||
m_world.DebugDraw();
|
||||
g_debugDraw->Submit();
|
||||
|
||||
if (g_settings.drawFaces)
|
||||
{
|
||||
g_debugDraw->Draw(m_world);
|
||||
}
|
||||
|
||||
// Draw Statistics
|
||||
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Log", NULL, ImVec2(0, 0), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar);
|
||||
|
||||
if (g_settings.pause)
|
||||
{
|
||||
ImGui::Text("*PAUSED*");
|
||||
}
|
||||
|
||||
if (g_settings.drawStats)
|
||||
{
|
||||
ImGui::Text("Bodies %d", m_world.GetBodyList().m_count);
|
||||
ImGui::Text("Joints %d", m_world.GetJointList().m_count);
|
||||
ImGui::Text("Contacts %d", m_world.GetContactList().m_count);
|
||||
|
||||
float32 avgGjkIters = 0.0f;
|
||||
if (b3_gjkCalls > 0)
|
||||
{
|
||||
avgGjkIters = float32(b3_gjkIters) / float32(b3_gjkCalls);
|
||||
}
|
||||
|
||||
ImGui::Text("GJK Calls %d", b3_gjkCalls);
|
||||
ImGui::Text("GJK Iterations %d (%d) (%f)", b3_gjkIters, b3_gjkMaxIters, avgGjkIters);
|
||||
|
||||
float32 convexCacheHitRatio = 0.0f;
|
||||
if (b3_convexCalls > 0)
|
||||
{
|
||||
convexCacheHitRatio = float32(b3_convexCacheHits) / float32(b3_convexCalls);
|
||||
}
|
||||
|
||||
ImGui::Text("Convex Calls %d", b3_convexCalls);
|
||||
ImGui::Text("Convex Cache Hits %d (%f)", b3_convexCacheHits, convexCacheHitRatio);
|
||||
ImGui::Text("Frame Allocations %d (%d)", b3_allocCalls, b3_maxAllocCalls);
|
||||
}
|
||||
|
||||
if (g_settings.drawProfile)
|
||||
{
|
||||
for (u32 i = 0; i < g_profiler->m_records.Count(); ++i)
|
||||
{
|
||||
const ProfileRecord& r = g_profiler->m_records[i];
|
||||
ImGui::Text("%s %.4f (%.4f) [ms]", r.name, r.elapsed, r.maxElapsed);
|
||||
}
|
||||
}
|
||||
|
||||
g_profiler->Clear();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void Test::MouseMove(const Ray3& pw)
|
||||
{
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
float32 t = m_rayHit.fraction;
|
||||
float32 w1 = 1.0f - t;
|
||||
float32 w2 = t;
|
||||
|
||||
b3Vec3 target = w1 * pw.Start() + w2 * pw.End();
|
||||
m_mouseJoint->SetTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
void Test::MouseLeftDown(const Ray3& pw)
|
||||
{
|
||||
// Clear the current hit
|
||||
m_rayHit.shape = NULL;
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
b3Body* groundBody = m_mouseJoint->GetBodyA();
|
||||
|
||||
m_world.DestroyJoint(m_mouseJoint);
|
||||
m_mouseJoint = NULL;
|
||||
|
||||
m_world.DestroyBody(groundBody);
|
||||
}
|
||||
|
||||
b3Vec3 p1 = pw.Start();
|
||||
b3Vec3 p2 = pw.End();
|
||||
|
||||
RayCastListener listener;
|
||||
listener.hit.shape = NULL;
|
||||
|
||||
// Perform the ray cast
|
||||
b3RayCastSingleOutput out;
|
||||
if (m_world.RayCastSingle(&out, p1, p2))
|
||||
{
|
||||
m_rayHit = out;
|
||||
RayHit();
|
||||
}
|
||||
}
|
||||
|
||||
void Test::MouseLeftUp(const Ray3& pw)
|
||||
{
|
||||
m_rayHit.shape = NULL;
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
b3Body* groundBody = m_mouseJoint->GetBodyA();
|
||||
|
||||
m_world.DestroyJoint(m_mouseJoint);
|
||||
m_mouseJoint = NULL;
|
||||
|
||||
m_world.DestroyBody(groundBody);
|
||||
}
|
||||
}
|
||||
|
||||
void Test::RayHit()
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
b3Body* bodyA = m_world.CreateBody(bdef);
|
||||
b3Body* bodyB = m_rayHit.shape->GetBody();
|
||||
|
||||
b3MouseJointDef def;
|
||||
def.bodyA = bodyA;
|
||||
def.bodyB = bodyB;
|
||||
def.target = m_rayHit.point;
|
||||
def.maxForce = 2000.0f * bodyB->GetMass();
|
||||
|
||||
m_mouseJoint = (b3MouseJoint*)m_world.CreateJoint(def);
|
||||
bodyB->SetAwake(true);
|
||||
}
|
89
examples/testbed/framework/test_entries.cpp
Normal file
89
examples/testbed/framework/test_entries.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 <testbed/tests/test.h>
|
||||
#include <testbed/tests/quickhull_test.h>
|
||||
#include <testbed/tests/cluster_test.h>
|
||||
#include <testbed/tests/distance_test.h>
|
||||
#include <testbed/tests/capsule_distance.h>
|
||||
#include <testbed/tests/collide_test.h>
|
||||
#include <testbed/tests/capsule_collision.h>
|
||||
#include <testbed/tests/capsule_and_hull_collision.h>
|
||||
#include <testbed/tests/hull_collision.h>
|
||||
#include <testbed/tests/linear_motion.h>
|
||||
#include <testbed/tests/angular_motion.h>
|
||||
#include <testbed/tests/multiple_shapes.h>
|
||||
#include <testbed/tests/quadric_shapes.h>
|
||||
#include <testbed/tests/spring.h>
|
||||
#include <testbed/tests/newton_cradle.h>
|
||||
#include <testbed/tests/hinge_motor.h>
|
||||
#include <testbed/tests/hinge_chain.h>
|
||||
#include <testbed/tests/ragdoll.h>
|
||||
#include <testbed/tests/mesh_contact_test.h>
|
||||
#include <testbed/tests/sphere_stack.h>
|
||||
#include <testbed/tests/capsule_stack.h>
|
||||
#include <testbed/tests/box_stack.h>
|
||||
#include <testbed/tests/shape_stack.h>
|
||||
#include <testbed/tests/jenga.h>
|
||||
#include <testbed/tests/thin.h>
|
||||
#include <testbed/tests/pyramid.h>
|
||||
#include <testbed/tests/pyramids.h>
|
||||
#include <testbed/tests/ray_cast.h>
|
||||
#include <testbed/tests/sensor_test.h>
|
||||
#include <testbed/tests/character_test.h>
|
||||
#include <testbed/tests/body_types.h>
|
||||
#include <testbed/tests/varying_friction.h>
|
||||
#include <testbed/tests/varying_restitution.h>
|
||||
#include <testbed/tests/cloth_test.h>
|
||||
|
||||
TestEntry g_tests[] =
|
||||
{
|
||||
{ "Quickhull Test", &QuickhullTest::Create },
|
||||
{ "Cluster Test", &Cluster::Create },
|
||||
{ "Distance Test", &Distance::Create },
|
||||
{ "Capsule Distance", &CapsuleDistance::Create },
|
||||
{ "Capsule Collision", &CapsuleCollision::Create },
|
||||
{ "Capsule and Hull Collision", &CapsuleAndHull::Create },
|
||||
{ "Hull Collision", &HullAndHull::Create },
|
||||
{ "Linear Motion", &LinearMotion::Create },
|
||||
{ "Angular Motion", &AngularMotion::Create },
|
||||
{ "Multiple Shapes", &MultipleShapes::Create },
|
||||
{ "Quadric Shapes", &QuadricShapes::Create },
|
||||
{ "Springs", &Spring::Create },
|
||||
{ "Newton's Cradle", &NewtonCradle::Create },
|
||||
{ "Hinge Motor", &HingeMotor::Create },
|
||||
{ "Hinge Chain", &HingeChain::Create },
|
||||
{ "Ragdoll", &Ragdoll::Create },
|
||||
{ "Thin Boxes", &Thin::Create },
|
||||
{ "Mesh Contact Test", &MeshContactTest::Create },
|
||||
{ "Sphere Stack", &SphereStack::Create },
|
||||
{ "Capsule Stack", &CapsuleStack::Create },
|
||||
{ "Box Stack", &BoxStack::Create },
|
||||
{ "Shape Stack", &ShapeStack::Create },
|
||||
{ "Jenga", &Jenga::Create },
|
||||
{ "Box Pyramid", &Pyramid::Create },
|
||||
{ "Box Pyramid Rows", &Pyramids::Create },
|
||||
{ "Ray Cast", &RayCast::Create },
|
||||
{ "Sensor Test", &SensorTest::Create },
|
||||
{ "Character Test", &Character::Create },
|
||||
{ "Body Types", &BodyTypes::Create },
|
||||
{ "Varying Friction", &VaryingFriction::Create },
|
||||
{ "Varying Restitution", &VaryingRestitution::Create },
|
||||
{ "Cloth", &Cloth::Create },
|
||||
{ NULL, NULL }
|
||||
};
|
79
examples/testbed/tests/angular_motion.h
Normal file
79
examples/testbed/tests/angular_motion.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 ANGULAR_MOTION_H
|
||||
#define ANGULAR_MOTION_H
|
||||
|
||||
class AngularMotion : public Test
|
||||
{
|
||||
public:
|
||||
AngularMotion()
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_body = m_world.CreateBody(bdef);
|
||||
|
||||
b3CapsuleShape shape;
|
||||
shape.m_centers[0].Set(0.0f, 1.0f, 0.0f);
|
||||
shape.m_centers[1].Set(0.0f, -1.0f, 0.0f);
|
||||
shape.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &shape;
|
||||
sdef.density = 1.0f;
|
||||
|
||||
m_body->CreateShape(sdef);
|
||||
|
||||
b3MassData data;
|
||||
m_body->GetMassData(&data);
|
||||
|
||||
m_body->SetMassData(&data);
|
||||
|
||||
b3Vec3 g(0.0f, 0.0f, 0.0f);
|
||||
m_world.SetGravity(g);
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
Test::Step();
|
||||
|
||||
b3Vec3 v(0.0f, 0.0f, 0.0f);
|
||||
m_body->SetLinearVelocity(v);
|
||||
|
||||
b3Vec3 p = m_body->GetSweep().worldCenter;
|
||||
b3Quat quat = m_body->GetSweep().orientation;
|
||||
|
||||
b3Vec3 axis;
|
||||
float32 angle;
|
||||
quat.GetAxisAngle(&axis, &angle);
|
||||
|
||||
b3Vec3 q(0.0f, 0.0f, 0.0f);
|
||||
m_body->SetTransform(q, axis, angle);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new AngularMotion();
|
||||
}
|
||||
|
||||
b3Body* m_body;
|
||||
};
|
||||
|
||||
#endif
|
245
examples/testbed/tests/body_types.h
Normal file
245
examples/testbed/tests/body_types.h
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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()
|
||||
{
|
||||
g_camera.m_zoom = 50.0f;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(0.0f, 3.5f, 0.0f);
|
||||
bd.linearVelocity.Set(0.0f, 0.0f, 0.0f);
|
||||
bd.angularVelocity.Set(0.0f, B3_PI, 0.0f);
|
||||
|
||||
m_body = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cap;
|
||||
cap.m_centers[0].Set(0.0f, 2.0f, 0.0f);
|
||||
cap.m_centers[1].Set(0.0f, -2.0f, 0.0f);
|
||||
cap.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = ∩
|
||||
sd.density = 1.5f;
|
||||
sd.friction = 0.7f;
|
||||
|
||||
m_body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
Test::Step();
|
||||
|
||||
b3Color color(1.0f, 1.0f, 1.0f);
|
||||
g_debugDraw->DrawString("S - Static", color);
|
||||
g_debugDraw->DrawString("D - Dynamic", color);
|
||||
g_debugDraw->DrawString("K - Kinematic", color);
|
||||
g_debugDraw->DrawString("Space - Throw Bomb", color);
|
||||
g_debugDraw->DrawString("Arrows - Apply Force/Velocity/Position", color);
|
||||
}
|
||||
|
||||
void KeyDown(int button)
|
||||
{
|
||||
if (button == GLFW_KEY_S)
|
||||
{
|
||||
m_body->SetType(e_staticBody);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_K)
|
||||
{
|
||||
m_body->SetType(e_kinematicBody);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_D)
|
||||
{
|
||||
m_body->SetType(e_dynamicBody);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_SPACE)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(RandomFloat(-20.0f, 20.0f), RandomFloat(10.0f, 20.0f), RandomFloat(-20.0f, 20.0f));
|
||||
|
||||
b3Vec3 n = m_body->GetTransform().position - bd.position;
|
||||
n.Normalize();
|
||||
|
||||
bd.linearVelocity = 100.0f * n;
|
||||
|
||||
b3Body* enemy = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape shape;
|
||||
shape.m_center.Set(0.0f, 0.0f, 0.0f);
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &shape;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 1.0f;
|
||||
|
||||
enemy->CreateShape(sd);
|
||||
}
|
||||
|
||||
if (m_body->GetType() == e_staticBody)
|
||||
{
|
||||
if (button == GLFW_KEY_LEFT)
|
||||
{
|
||||
b3Vec3 p = m_body->GetSweep().worldCenter;
|
||||
b3Quat q = m_body->GetSweep().orientation;
|
||||
|
||||
p.x -= 1.0f;
|
||||
|
||||
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_RIGHT)
|
||||
{
|
||||
b3Vec3 p = m_body->GetSweep().worldCenter;
|
||||
b3Quat q = m_body->GetSweep().orientation;
|
||||
|
||||
p.x += 1.0f;
|
||||
|
||||
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_UP)
|
||||
{
|
||||
b3Vec3 p = m_body->GetSweep().worldCenter;
|
||||
b3Quat q = m_body->GetSweep().orientation;
|
||||
|
||||
p.z += 1.0f;
|
||||
|
||||
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_DOWN)
|
||||
{
|
||||
b3Vec3 p = m_body->GetSweep().worldCenter;
|
||||
b3Quat q = m_body->GetSweep().orientation;
|
||||
|
||||
p.z -= 1.0f;
|
||||
|
||||
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_body->GetType() == e_kinematicBody)
|
||||
{
|
||||
if (button == GLFW_KEY_LEFT)
|
||||
{
|
||||
b3Vec3 v = m_body->GetLinearVelocity();
|
||||
b3Vec3 w = m_body->GetAngularVelocity();
|
||||
|
||||
v.x -= 5.0f;
|
||||
w.y -= 0.25f * B3_PI;
|
||||
|
||||
m_body->SetLinearVelocity(v);
|
||||
m_body->SetAngularVelocity(w);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_RIGHT)
|
||||
{
|
||||
b3Vec3 v = m_body->GetLinearVelocity();
|
||||
b3Vec3 w = m_body->GetAngularVelocity();
|
||||
|
||||
v.x += 5.0f;
|
||||
w.y += 0.25f * B3_PI;
|
||||
|
||||
m_body->SetLinearVelocity(v);
|
||||
m_body->SetAngularVelocity(w);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_UP)
|
||||
{
|
||||
b3Vec3 v = m_body->GetLinearVelocity();
|
||||
b3Vec3 w = m_body->GetAngularVelocity();
|
||||
|
||||
v.z -= 5.0f;
|
||||
w.y -= 0.25f * B3_PI;
|
||||
|
||||
m_body->SetLinearVelocity(v);
|
||||
m_body->SetAngularVelocity(w);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_DOWN)
|
||||
{
|
||||
b3Vec3 v = m_body->GetLinearVelocity();
|
||||
b3Vec3 w = m_body->GetAngularVelocity();
|
||||
|
||||
v.z += 5.0f;
|
||||
w.y += 0.25f * B3_PI;
|
||||
|
||||
m_body->SetLinearVelocity(v);
|
||||
m_body->SetAngularVelocity(w);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_body->GetType() == e_dynamicBody)
|
||||
{
|
||||
if (button == GLFW_KEY_LEFT)
|
||||
{
|
||||
m_body->ApplyForceToCenter(b3Vec3(-100.0f, 0.0f, 0.0f), true);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_RIGHT)
|
||||
{
|
||||
m_body->ApplyForceToCenter(b3Vec3(100.0f, 0.0f, 0.0f), true);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_UP)
|
||||
{
|
||||
m_body->ApplyForceToCenter(b3Vec3(0.0f, 0.0f, -100.0f), true);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_DOWN)
|
||||
{
|
||||
m_body->ApplyForceToCenter(b3Vec3(0.0f, 0.0f, 100.0f), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new BodyTypes();
|
||||
}
|
||||
|
||||
b3Body* m_body;
|
||||
};
|
||||
|
||||
#endif
|
97
examples/testbed/tests/box_stack.h
Normal file
97
examples/testbed/tests/box_stack.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BOX_STACK_H
|
||||
#define BOX_STACK_H
|
||||
|
||||
class BoxStack : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_rowCount = 1,
|
||||
e_columnCount = 5,
|
||||
e_depthCount = 1
|
||||
};
|
||||
|
||||
BoxStack()
|
||||
{
|
||||
g_camera.m_center.Set(2.5f, -2.0f, 5.5f);
|
||||
g_camera.m_zoom = 40.0f;
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
sdef.friction = 1.0f;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
b3Vec3 stackOrigin;
|
||||
stackOrigin.Set(0.0f, 4.05f, 0.0f);
|
||||
|
||||
b3Vec3 boxScale;
|
||||
boxScale.Set(2.05f, 2.05f, 2.05f);
|
||||
|
||||
for (u32 i = 0; i < e_rowCount; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < e_columnCount; ++j)
|
||||
{
|
||||
for (u32 k = 0; k < e_depthCount; ++k)
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_dynamicBody;
|
||||
|
||||
bdef.position.x = float32(i) * boxScale.x;
|
||||
bdef.position.y = 1.5f * float32(j) * boxScale.y;
|
||||
bdef.position.z = float32(k) * boxScale.z;
|
||||
bdef.position += stackOrigin;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.5f;
|
||||
sdef.friction = 0.3f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new BoxStack();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
60
examples/testbed/tests/capsule_and_hull_collision.h
Normal file
60
examples/testbed/tests/capsule_and_hull_collision.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef CAPSULE_HULL_H
|
||||
#define CAPSULE_HULL_H
|
||||
|
||||
class CapsuleAndHull : public Collide
|
||||
{
|
||||
public:
|
||||
CapsuleAndHull()
|
||||
{
|
||||
m_xfA.position.Set(0.0f, 0.0f, 0.0f);
|
||||
m_xfA.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.55f * B3_PI));
|
||||
|
||||
m_sA.m_centers[0].Set(0.0f, -1.0f, 0.0f);
|
||||
m_sA.m_centers[1].Set(0.0f, 1.0f, 0.0f);
|
||||
m_sA.m_radius = 2.0f;
|
||||
|
||||
m_xfB.position.Set(0.f, 0.0f, 0.0f);
|
||||
m_xfB.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.0f * B3_PI));
|
||||
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.rotation = b3Diagonal(4.0f, 1.0f, 4.0f);
|
||||
|
||||
m_box.SetTransform(xf);
|
||||
|
||||
m_sB.m_hull = &m_box;
|
||||
|
||||
m_shapeA = &m_sA;
|
||||
m_shapeB = &m_sB;
|
||||
m_cache.count = 0;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CapsuleAndHull();
|
||||
}
|
||||
|
||||
b3CapsuleShape m_sA;
|
||||
b3HullShape m_sB;
|
||||
b3BoxHull m_box;
|
||||
};
|
||||
|
||||
#endif
|
57
examples/testbed/tests/capsule_collision.h
Normal file
57
examples/testbed/tests/capsule_collision.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef CAPSULE_COLLISION_H
|
||||
#define CAPSULE_COLLISION_H
|
||||
|
||||
class CapsuleCollision : public Collide
|
||||
{
|
||||
public:
|
||||
CapsuleCollision()
|
||||
{
|
||||
m_xfA.SetIdentity();
|
||||
m_xfA.position.Set(0.0f, 0.0f, 0.0f);
|
||||
//m_xfA.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.25f * B3_PI));
|
||||
m_xfA.rotation.SetIdentity();
|
||||
m_sA.m_centers[0].Set(0.0f, -5.0f, 0.0f);
|
||||
m_sA.m_centers[1].Set(0.0f, 5.0f, 0.0f);
|
||||
m_sA.m_radius = 1.0f;
|
||||
|
||||
m_xfB.SetIdentity();
|
||||
m_xfB.position.Set(0.f, 0.0f, 0.0f);
|
||||
//m_xfB.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.251f * B3_PI));
|
||||
m_xfB.rotation.SetIdentity();
|
||||
m_sB.m_centers[0].Set(0.0f, -1.0f, 0.0f);
|
||||
m_sB.m_centers[1].Set(0.0f, 1.0f, 0.0f);
|
||||
m_sB.m_radius = 1.0f;
|
||||
|
||||
m_cache.count = 0;
|
||||
m_shapeA = &m_sA;
|
||||
m_shapeB = &m_sB;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CapsuleCollision();
|
||||
}
|
||||
|
||||
b3CapsuleShape m_sA;
|
||||
b3CapsuleShape m_sB;
|
||||
};
|
||||
|
||||
#endif
|
128
examples/testbed/tests/capsule_distance.h
Normal file
128
examples/testbed/tests/capsule_distance.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef CAPSULE_DISTANCE_H
|
||||
#define CAPSULE_DISTANCE_H
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
|
||||
class CapsuleDistance : public Test
|
||||
{
|
||||
public:
|
||||
CapsuleDistance()
|
||||
{
|
||||
g_camera.m_zoom = 25.0f;
|
||||
|
||||
m_xfA.SetIdentity();
|
||||
m_xfA.position.Set(-5.0f, 0.0f, 0.0f);
|
||||
m_xfA.rotation.SetIdentity();
|
||||
m_shapeA.m_centers[0].Set(0.0f, -2.0f, 0.0f);
|
||||
m_shapeA.m_centers[1].Set(0.0f, 2.0f, 0.0f);
|
||||
m_shapeA.m_radius = 1.0f;
|
||||
|
||||
m_xfB.SetIdentity();
|
||||
m_xfB.position.Set(5.0f, 0.0f, 0.0f);
|
||||
m_xfB.rotation.SetIdentity();
|
||||
m_shapeB.m_centers[0].Set(0.0f, -2.0f, 0.0f);
|
||||
m_shapeB.m_centers[1].Set(0.0f, 2.0f, 0.0f);
|
||||
m_shapeB.m_radius = 1.0f;
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
b3Capsule edgeA;
|
||||
edgeA.vertices[0] = m_xfA * m_shapeA.m_centers[0];
|
||||
edgeA.vertices[1] = m_xfA * m_shapeA.m_centers[1];
|
||||
edgeA.radius = m_shapeA.m_radius;
|
||||
|
||||
b3Capsule edgeB;
|
||||
edgeB.vertices[0] = m_xfB * m_shapeB.m_centers[0];
|
||||
edgeB.vertices[1] = m_xfB * m_shapeB.m_centers[1];
|
||||
edgeB.radius = m_shapeB.m_radius;
|
||||
|
||||
b3Vec3 pointA, pointB;
|
||||
b3ClosestPointsOnSegments(&pointA, &pointB, edgeA.vertices[0], edgeA.vertices[1], edgeB.vertices[1], edgeB.vertices[0]);
|
||||
|
||||
if (b3Distance(pointA, pointB) > 0.0f)
|
||||
{
|
||||
g_debugDraw->DrawPoint(pointA, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawPoint(pointB, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
|
||||
|
||||
g_debugDraw->DrawSegment(pointA, pointB, b3Color(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
g_debugDraw->DrawTransform(m_xfA);
|
||||
g_debugDraw->DrawTransform(m_xfB);
|
||||
|
||||
m_world.DrawShape(m_xfA, &m_shapeA);
|
||||
m_world.DrawShape(m_xfB, &m_shapeB);
|
||||
}
|
||||
|
||||
void KeyDown(int key)
|
||||
{
|
||||
if (key == GLFW_KEY_LEFT)
|
||||
{
|
||||
m_xfB.position.x -= 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_RIGHT)
|
||||
{
|
||||
m_xfB.position.x += 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_UP)
|
||||
{
|
||||
m_xfB.position.y += 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_DOWN)
|
||||
{
|
||||
m_xfB.position.y -= 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_X)
|
||||
{
|
||||
b3Quat qx(b3Vec3(1.0f, 0.0f, 0.0f), 0.05f * B3_PI);
|
||||
b3Mat33 xfx = b3ConvertQuatToRot(qx);
|
||||
|
||||
m_xfB.rotation = m_xfB.rotation * xfx;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_Y)
|
||||
{
|
||||
b3Quat qy(b3Vec3(0.0f, 1.0f, 0.0f), 0.05f * B3_PI);
|
||||
b3Mat33 xfy = b3ConvertQuatToRot(qy);
|
||||
|
||||
m_xfB.rotation = m_xfB.rotation * xfy;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CapsuleDistance();
|
||||
}
|
||||
|
||||
b3CapsuleShape m_shapeA;
|
||||
b3Transform m_xfA;
|
||||
|
||||
b3CapsuleShape m_shapeB;
|
||||
b3Transform m_xfB;
|
||||
};
|
||||
|
||||
#endif
|
127
examples/testbed/tests/capsule_stack.h
Normal file
127
examples/testbed/tests/capsule_stack.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef CAPSULE_STACK_H
|
||||
#define CAPSULE_STACK_H
|
||||
|
||||
class CapsuleStack : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_rowCount = 5,
|
||||
e_columnCount = 5,
|
||||
e_depthCount = 5
|
||||
};
|
||||
|
||||
CapsuleStack()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_staticBody;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
float32 height = 3.0f;
|
||||
float32 radius = 1.0f;
|
||||
float32 separation = 0.0f;
|
||||
|
||||
b3CapsuleShape capsule;
|
||||
capsule.m_centers[0].Set(0.0f, -0.5f * height, 0.0f);
|
||||
capsule.m_centers[1].Set(0.0f, 0.5f * height, 0.0f);
|
||||
capsule.m_radius = radius;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &capsule;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.3f;
|
||||
|
||||
const u32 c = e_rowCount * e_columnCount * e_depthCount;
|
||||
b3Body* bs[c];
|
||||
u32 n = 0;
|
||||
|
||||
b3AABB3 aabb;
|
||||
aabb.m_lower.Set(0.0f, 0.0f, 0.0f);
|
||||
aabb.m_upper.Set(0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (u32 i = 0; i < e_rowCount; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < e_columnCount; ++j)
|
||||
{
|
||||
for (u32 k = 0; k < e_depthCount; ++k)
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_dynamicBody;
|
||||
|
||||
bdef.position.x = (2.0f + separation) * float32(i) * (0.5f * height + radius);
|
||||
bdef.position.y = (2.0f + separation) * float32(j) * radius;
|
||||
bdef.position.z = (2.0f + separation) * float32(k) * radius;
|
||||
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
bs[n++] = body;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
|
||||
b3AABB3 aabb2;
|
||||
shape->ComputeAABB(&aabb2, body->GetTransform());
|
||||
|
||||
aabb = b3Combine(aabb, aabb2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b3Vec3 center = aabb.Centroid();
|
||||
|
||||
for (u32 i = 0; i < n; ++i)
|
||||
{
|
||||
b3Body* b = bs[i];
|
||||
const b3Vec3& p = b->GetSweep().worldCenter;
|
||||
const b3Quat& q = b->GetSweep().orientation;
|
||||
|
||||
// centralize
|
||||
b3Vec3 position = p - center;
|
||||
|
||||
// move up
|
||||
position.y += 0.5f * aabb.Height() + radius;
|
||||
|
||||
// maintain orientation
|
||||
b3Vec3 axis;
|
||||
float32 angle;
|
||||
q.GetAxisAngle(&axis, &angle);
|
||||
b->SetTransform(position, axis, angle);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new CapsuleStack();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
102
examples/testbed/tests/character_test.h
Normal file
102
examples/testbed/tests/character_test.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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_H
|
||||
#define CHARACTER_H
|
||||
|
||||
class Character : public Test
|
||||
{
|
||||
public:
|
||||
Character()
|
||||
{
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
b3Body* ground = m_world.CreateBody(bdef);
|
||||
|
||||
b3MeshShape ms;
|
||||
ms.m_mesh = m_meshes + e_gridMesh;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ms;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_dynamicBody;
|
||||
bdef.fixedRotationY = true;
|
||||
bdef.position.Set(0.0f, 5.0f, 0.0f);
|
||||
|
||||
m_character = m_world.CreateBody(bdef);
|
||||
|
||||
b3CapsuleShape cap;
|
||||
cap.m_centers[0].Set(0.0f, 1.0f, 0.0f);
|
||||
cap.m_centers[1].Set(0.0f, -1.0f, 0.0f);
|
||||
cap.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = ∩
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.5f;
|
||||
|
||||
m_character->CreateShape(sdef);
|
||||
}
|
||||
}
|
||||
|
||||
void RayHit()
|
||||
{
|
||||
if (m_rayHit.shape)
|
||||
{
|
||||
if (m_rayHit.shape->GetBody() != m_character)
|
||||
{
|
||||
Test::RayHit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
if (m_rayHit.shape)
|
||||
{
|
||||
if (m_rayHit.shape->GetBody() != m_character)
|
||||
{
|
||||
b3Vec3 point = m_rayHit.point;
|
||||
b3Vec3 normal = m_rayHit.normal;
|
||||
|
||||
const b3Transform& xf = m_character->GetTransform();
|
||||
b3Vec3 n = point - xf.position;
|
||||
n.Normalize();
|
||||
|
||||
m_character->ApplyForceToCenter(100.0f * n, true);
|
||||
g_debugDraw->DrawSolidCircle(normal, point + (0.05f * normal), 5.0f, b3Color(0.5f, 0.5f, 1.0f, 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
Test::Step();
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Character();
|
||||
}
|
||||
|
||||
b3Body* m_character;
|
||||
};
|
||||
|
||||
#endif
|
79
examples/testbed/tests/cloth_test.h
Normal file
79
examples/testbed/tests/cloth_test.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 CLOTH_H
|
||||
#define CLOTH_H
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Settings g_settings;
|
||||
|
||||
class Cloth : public Test
|
||||
{
|
||||
public:
|
||||
Cloth()
|
||||
{
|
||||
g_camera.m_zoom = 25.0f;
|
||||
|
||||
b3ClothDef def;
|
||||
def.mesh = m_meshes + e_clothMesh;
|
||||
def.density = 0.2f;
|
||||
def.gravity.Set(-10.0f, 1.0f, 0.0f);
|
||||
def.k1 = 0.5f;
|
||||
def.k2 = 0.05f;
|
||||
def.kd = 0.1f;
|
||||
def.r = 1.0f;
|
||||
|
||||
m_cloth.Initialize(def);
|
||||
|
||||
b3Particle* vs = m_cloth.GetVertices();
|
||||
for (u32 i = 0; i < 5; ++i)
|
||||
{
|
||||
vs[i].im = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f;
|
||||
|
||||
if (g_settings.pause)
|
||||
{
|
||||
if (g_settings.singleStep)
|
||||
{
|
||||
g_settings.singleStep = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
dt = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_cloth.Step(dt, g_settings.positionIterations);
|
||||
m_cloth.Draw(g_debugDraw);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Cloth();
|
||||
}
|
||||
|
||||
b3Cloth m_cloth;
|
||||
};
|
||||
|
||||
#endif
|
89
examples/testbed/tests/cluster_test.h
Normal file
89
examples/testbed/tests/cluster_test.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 CLUSTER_H
|
||||
#define CLUSTER_H
|
||||
|
||||
#include <bounce/dynamics/contacts/contact_cluster.h>
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
|
||||
class Cluster : public Test
|
||||
{
|
||||
public:
|
||||
Cluster()
|
||||
{
|
||||
g_camera.m_zoom = 10.0f;
|
||||
|
||||
// Initialize observations
|
||||
b3StackArray<b3Observation, 256> tempObservations;
|
||||
tempObservations.Resize(90);
|
||||
for (u32 i = 0; i < tempObservations.Count(); ++i)
|
||||
{
|
||||
float32 x = RandomFloat(-1.0f, 1.0f);
|
||||
float32 y = RandomFloat(-1.0f, 1.0f);
|
||||
float32 z = RandomFloat(-1.0f, 1.0f);
|
||||
|
||||
tempObservations[i].point.Set(x, y, z);
|
||||
tempObservations[i].point = b3Normalize(tempObservations[i].point);
|
||||
tempObservations[i].cluster = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// Initialize clusters
|
||||
b3StackArray<b3Cluster, 3> tempClusters;
|
||||
b3InitializeClusters(tempClusters, tempObservations);
|
||||
|
||||
// Clusterize
|
||||
b3Clusterize(m_clusters, m_observs, tempClusters, tempObservations);
|
||||
|
||||
for (u32 i = 0; i < m_clusters.Count(); ++i)
|
||||
{
|
||||
m_colors[i] = b3Color(RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
for (u32 i = 0; i < m_clusters.Count(); ++i)
|
||||
{
|
||||
g_debugDraw->DrawSegment(b3Vec3(0, 0, 0), m_clusters[i].centroid, b3Color(1, 1, 1));
|
||||
g_debugDraw->DrawPoint(m_clusters[i].centroid, 4.0f, m_colors[i]);
|
||||
|
||||
for (u32 j = 0; j < m_observs.Count(); ++j)
|
||||
{
|
||||
b3Observation obs = m_observs[j];
|
||||
if (obs.cluster == i)
|
||||
{
|
||||
g_debugDraw->DrawPoint(obs.point, 4.0f, m_colors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Cluster();
|
||||
}
|
||||
|
||||
b3StackArray<b3Observation, 256> m_observs;
|
||||
b3StackArray<b3Cluster, 3> m_clusters;
|
||||
b3Color m_colors[3];
|
||||
};
|
||||
|
||||
#endif
|
118
examples/testbed/tests/collide_test.h
Normal file
118
examples/testbed/tests/collide_test.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 COLLIDE_H
|
||||
#define COLLIDE_H
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Settings g_settings;
|
||||
|
||||
class Collide : public Test
|
||||
{
|
||||
public:
|
||||
Collide()
|
||||
{
|
||||
g_camera.m_zoom = 25.0f;
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
b3ConvexCache cache;
|
||||
cache.simplexCache.count = 0;
|
||||
cache.featureCache.m_featurePair.state = b3SATCacheType::e_empty;
|
||||
|
||||
b3Manifold manifold;
|
||||
manifold.GuessImpulses();
|
||||
|
||||
b3CollideShapeAndShape(manifold, m_xfA, m_shapeA, m_xfB, m_shapeB, &cache);
|
||||
|
||||
b3WorldManifold wm;
|
||||
wm.Initialize(&manifold, m_xfA, m_shapeA->m_radius, m_xfB, m_shapeB->m_radius);
|
||||
|
||||
for (u32 i = 0; i < wm.pointCount; ++i)
|
||||
{
|
||||
b3WorldManifoldPoint* wmp = wm.points + i;
|
||||
b3Vec3 pw = wmp->point;
|
||||
b3Vec2 ps = g_camera.ConvertWorldToScreen(pw);
|
||||
|
||||
g_debugDraw->DrawPoint(pw, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawSegment(pw, pw + wmp->normal, b3Color(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
if (wm.pointCount > 0)
|
||||
{
|
||||
g_debugDraw->DrawPoint(wm.center, 4.0f, b3Color(1.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawSegment(wm.center, wm.center + wm.normal, b3Color(1.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawSegment(wm.center, wm.center + wm.tangent1, b3Color(1.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawSegment(wm.center, wm.center + wm.tangent2, b3Color(1.0f, 1.0f, 0.0f));
|
||||
}
|
||||
|
||||
m_world.DrawShape(m_xfA, m_shapeA);
|
||||
m_world.DrawShape(m_xfB, m_shapeB);
|
||||
}
|
||||
|
||||
virtual void KeyDown(int key)
|
||||
{
|
||||
if (key == GLFW_KEY_LEFT)
|
||||
{
|
||||
m_xfB.position.x -= 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_RIGHT)
|
||||
{
|
||||
m_xfB.position.x += 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_UP)
|
||||
{
|
||||
m_xfB.position.y += 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_DOWN)
|
||||
{
|
||||
m_xfB.position.y -= 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_X)
|
||||
{
|
||||
b3Quat qx(b3Vec3(1.0f, 0.0f, 0.0f), 0.05f * B3_PI);
|
||||
b3Mat33 xfx = b3ConvertQuatToRot(qx);
|
||||
|
||||
m_xfB.rotation = m_xfB.rotation * xfx;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_Y)
|
||||
{
|
||||
b3Quat qy(b3Vec3(0.0f, 1.0f, 0.0f), 0.05f * B3_PI);
|
||||
b3Mat33 xfy = b3ConvertQuatToRot(qy);
|
||||
|
||||
m_xfB.rotation = m_xfB.rotation * xfy;
|
||||
}
|
||||
}
|
||||
|
||||
b3Shape* m_shapeA;
|
||||
b3Transform m_xfA;
|
||||
|
||||
b3Shape* m_shapeB;
|
||||
b3Transform m_xfB;
|
||||
|
||||
b3SimplexCache m_cache;
|
||||
};
|
||||
|
||||
#endif
|
136
examples/testbed/tests/distance_test.h
Normal file
136
examples/testbed/tests/distance_test.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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_H
|
||||
#define DISTANCE_H
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Settings g_settings;
|
||||
|
||||
class Distance : public Test
|
||||
{
|
||||
public:
|
||||
Distance()
|
||||
{
|
||||
g_camera.m_zoom = 25.0f;
|
||||
|
||||
m_xfA.SetIdentity();
|
||||
m_xfA.position.Set(-5.0f, 0.0f, 0.0f);
|
||||
m_xfA.rotation.SetIdentity();
|
||||
m_shapeA.m_centers[0].Set(0.0f, -2.0f, 0.0f);
|
||||
m_shapeA.m_centers[1].Set(0.0f, 2.0f, 0.0f);
|
||||
m_shapeA.m_radius = 1.0f;
|
||||
|
||||
m_xfB.SetIdentity();
|
||||
m_xfB.position.Set(5.0f, 0.0f, 0.0f);
|
||||
m_xfB.rotation.SetIdentity();
|
||||
m_shapeB.m_hull = &m_boxHull;
|
||||
|
||||
m_proxyA.Set(&m_shapeA, 0);
|
||||
m_proxyB.Set(&m_shapeB, 0);
|
||||
m_cache.count = 0;
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
b3GJKOutput out = b3GJK(m_xfA, m_proxyA, m_xfB, m_proxyB, false, &m_cache);
|
||||
if (0 < m_cache.count && m_cache.count < 4)
|
||||
{
|
||||
b3GJKFeaturePair featurePair = b3GetFeaturePair(m_cache);
|
||||
|
||||
for (u32 i = 0; i < featurePair.countA; ++i)
|
||||
{
|
||||
u32 index = featurePair.indexA[i];
|
||||
g_debugDraw->DrawPoint(m_xfA * m_proxyA.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < featurePair.countB; ++i)
|
||||
{
|
||||
u32 index = featurePair.indexB[i];
|
||||
g_debugDraw->DrawPoint(m_xfB * m_proxyB.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
g_debugDraw->DrawPoint(out.pointA, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawPoint(out.pointB, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawSegment(out.pointA, out.pointB, b3Color(1.0f, 1.0f, 1.0f));
|
||||
|
||||
g_debugDraw->DrawTransform(m_xfA);
|
||||
g_debugDraw->DrawTransform(m_xfB);
|
||||
|
||||
m_world.DrawShape(m_xfA, &m_shapeA);
|
||||
m_world.DrawShape(m_xfB, &m_shapeB);
|
||||
}
|
||||
|
||||
void KeyDown(int key)
|
||||
{
|
||||
if (key == GLFW_KEY_LEFT)
|
||||
{
|
||||
m_xfB.position.x -= 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_RIGHT)
|
||||
{
|
||||
m_xfB.position.x += 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_UP)
|
||||
{
|
||||
m_xfB.position.y += 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_DOWN)
|
||||
{
|
||||
m_xfB.position.y -= 0.05f;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_X)
|
||||
{
|
||||
b3Quat qx(b3Vec3(1.0f, 0.0f, 0.0f), 0.05f * B3_PI);
|
||||
b3Mat33 xfx = b3ConvertQuatToRot(qx);
|
||||
|
||||
m_xfB.rotation = m_xfB.rotation * xfx;
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_Y)
|
||||
{
|
||||
b3Quat qy(b3Vec3(0.0f, 1.0f, 0.0f), 0.05f * B3_PI);
|
||||
b3Mat33 xfy = b3ConvertQuatToRot(qy);
|
||||
|
||||
m_xfB.rotation = m_xfB.rotation * xfy;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Distance();
|
||||
}
|
||||
|
||||
b3CapsuleShape m_shapeA;
|
||||
b3Transform m_xfA;
|
||||
b3ShapeGJKProxy m_proxyA;
|
||||
|
||||
b3HullShape m_shapeB;
|
||||
b3Transform m_xfB;
|
||||
b3ShapeGJKProxy m_proxyB;
|
||||
|
||||
b3SimplexCache m_cache;
|
||||
};
|
||||
|
||||
#endif
|
90
examples/testbed/tests/hinge_chain.h
Normal file
90
examples/testbed/tests/hinge_chain.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 HINGE_CHAIN_H
|
||||
#define HINGE_CHAIN_H
|
||||
|
||||
class HingeChain : public Test
|
||||
{
|
||||
public:
|
||||
HingeChain()
|
||||
{
|
||||
g_camera.m_zoom = 100.0f;
|
||||
g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.15f * B3_PI);
|
||||
g_camera.m_q = g_camera.m_q * b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.15f * B3_PI);
|
||||
g_camera.m_center.SetZero();
|
||||
|
||||
float32 x = -50.0f;
|
||||
float32 y = 0.0f;
|
||||
|
||||
b3Body* lastHinge;
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.position.Set(x, y, 0.0f);
|
||||
lastHinge = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_doorHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hull;
|
||||
|
||||
lastHinge->CreateShape(sdef);
|
||||
}
|
||||
|
||||
x += 4.25f;
|
||||
|
||||
for (u32 i = 0; i < 20; ++i)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(x, y, 0.0f);
|
||||
b3Body* hinge = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_doorHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hull;
|
||||
sdef.density = 1.0f;
|
||||
|
||||
hinge->CreateShape(sdef);
|
||||
|
||||
{
|
||||
b3Vec3 hingeAxis(0.0f, 1.0f, 0.0f);
|
||||
b3Vec3 hingeAnchor(x - 2.25f, y, 0.0f);
|
||||
|
||||
b3RevoluteJointDef jd;
|
||||
jd.Initialize(lastHinge, hinge, hingeAxis, hingeAnchor, 0.0f, 0.5f * B3_PI);
|
||||
jd.collideLinked = true;
|
||||
|
||||
b3RevoluteJoint* rj = (b3RevoluteJoint*)m_world.CreateJoint(jd);
|
||||
}
|
||||
|
||||
x += 4.25f;
|
||||
lastHinge = hinge;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new HingeChain();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
127
examples/testbed/tests/hinge_motor.h
Normal file
127
examples/testbed/tests/hinge_motor.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 HINGE_MOTOR_H
|
||||
#define HINGE_MOTOR_H
|
||||
|
||||
class HingeMotor : public Test
|
||||
{
|
||||
public:
|
||||
HingeMotor()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape shape;
|
||||
shape.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &shape;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Body* hinge, *door;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.position.Set(-2.0f, 5.05f, 0.0f);
|
||||
hinge = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape shape;
|
||||
shape.m_centers[0].Set(0.0f, -3.5f, 0.0f);
|
||||
shape.m_centers[1].Set(0.0f, 3.5f, 0.0f);
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &shape;
|
||||
sd.density = 1.0f;
|
||||
|
||||
hinge->CreateShape(sd);
|
||||
m_hinge = hinge;
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(1.0f, 5.05f, 0.0f);
|
||||
|
||||
door = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_doorHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hull;
|
||||
sdef.density = 2.0f;
|
||||
|
||||
door->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3Vec3 hingeAxis(0.0f, 1.0f, 0.0f);
|
||||
b3Vec3 hingeAnchor(-2.0f, 5.0f, 0.0f);
|
||||
|
||||
b3RevoluteJointDef jd;
|
||||
jd.Initialize(hinge, door, hingeAxis, hingeAnchor, 0.0f, 0.5f * B3_PI);
|
||||
jd.motorSpeed = B3_PI;
|
||||
jd.maxMotorTorque = 10000.0f;
|
||||
|
||||
m_rj = (b3RevoluteJoint*)m_world.CreateJoint(jd);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyDown(int button)
|
||||
{
|
||||
if (button == GLFW_KEY_M)
|
||||
{
|
||||
m_rj->SetEnableMotor(!m_rj->IsMotorEnabled());
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_L)
|
||||
{
|
||||
m_rj->SetEnableLimit(!m_rj->IsLimitEnabled());
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_D)
|
||||
{
|
||||
m_hinge->SetType(e_dynamicBody);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_S)
|
||||
{
|
||||
m_hinge->SetType(e_staticBody);
|
||||
}
|
||||
|
||||
if (button == GLFW_KEY_K)
|
||||
{
|
||||
m_hinge->SetType(e_kinematicBody);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new HingeMotor();
|
||||
}
|
||||
|
||||
b3Body* m_hinge;
|
||||
b3RevoluteJoint* m_rj;
|
||||
};
|
||||
|
||||
#endif
|
58
examples/testbed/tests/hull_collision.h
Normal file
58
examples/testbed/tests/hull_collision.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 HULL_HULL_H
|
||||
#define HULL_HULL_H
|
||||
|
||||
class HullAndHull : public Collide
|
||||
{
|
||||
public:
|
||||
HullAndHull()
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.rotation = b3Diagonal(1.0f, 2.0f, 1.0f);
|
||||
xf.position.SetZero();
|
||||
|
||||
m_box.SetTransform(xf);
|
||||
|
||||
b3Quat qA(0.0f, 1.0f, 0.0f, 0.025f * B3_PI);
|
||||
m_xfA.SetIdentity();
|
||||
m_xfA.position.Set(0.0186814368f, 1.96078217f, 0.0253920462f);
|
||||
m_xfA.rotation = b3ConvertQuatToRot(qA);
|
||||
m_sA.m_hull = &m_box;
|
||||
|
||||
m_xfB.SetIdentity();
|
||||
m_xfB.position.Set(0.f, 0.0f, 0.0f);
|
||||
m_sB.m_hull = &m_box;
|
||||
|
||||
m_cache.count = 0;
|
||||
m_shapeA = &m_sA;
|
||||
m_shapeB = &m_sB;
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new HullAndHull();
|
||||
}
|
||||
|
||||
b3BoxHull m_box;
|
||||
b3HullShape m_sA;
|
||||
b3HullShape m_sB;
|
||||
};
|
||||
|
||||
#endif
|
114
examples/testbed/tests/jenga.h
Normal file
114
examples/testbed/tests/jenga.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 JENGA_H
|
||||
#define JENGA_H
|
||||
|
||||
class Jenga : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_layerCount = 20,
|
||||
e_depthCount = 3,
|
||||
};
|
||||
|
||||
Jenga()
|
||||
{
|
||||
g_camera.m_center.Set(2.0f, -2.0f, 0.0f);
|
||||
g_camera.m_zoom = 60.0f;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Vec3 boxScale;
|
||||
boxScale.Set(1.0f, 0.5f, 3.0f);
|
||||
|
||||
float32 y = 2.0f;
|
||||
|
||||
for (u32 i = 0; i < e_layerCount / 2; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < e_depthCount; ++j)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
|
||||
bd.position.x = 2.0f * float32(j) * boxScale.x;
|
||||
bd.position.y = y;
|
||||
bd.position.z = 0.0f;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_plankHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.density = 0.1f;
|
||||
sd.friction = 0.1f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
y += 2.05f * boxScale.y;
|
||||
|
||||
for (u32 j = 0; j < e_depthCount; ++j)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
|
||||
bd.orientation.Set(b3Vec3(0.0f, 1.0f, 0.0f), 0.5f * B3_PI);
|
||||
|
||||
bd.position.x = 2.0f * boxScale.x;
|
||||
bd.position.y = y;
|
||||
bd.position.z = -2.0f * boxScale.x + 2.0f * float32(j) * boxScale.x;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_plankHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.density = 0.1f;
|
||||
sd.friction = 0.3f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
y += 2.05f * boxScale.y;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Jenga();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
83
examples/testbed/tests/linear_motion.h
Normal file
83
examples/testbed/tests/linear_motion.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 LINEAR_MOTION_H
|
||||
#define LINEAR_MOTION_H
|
||||
|
||||
class LinearMotion : public Test
|
||||
{
|
||||
public:
|
||||
LinearMotion()
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_body = m_world.CreateBody(bdef);
|
||||
|
||||
b3CapsuleShape shape;
|
||||
shape.m_centers[0].Set(0.0f, 1.0f, 0.0f);
|
||||
shape.m_centers[1].Set(0.0f, -1.0f, 0.0f);
|
||||
shape.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &shape;
|
||||
sdef.density = 1.0f;
|
||||
|
||||
m_body->CreateShape(sdef);
|
||||
|
||||
b3MassData data;
|
||||
m_body->GetMassData(&data);
|
||||
|
||||
data.I.SetZero();
|
||||
|
||||
m_body->SetMassData(&data);
|
||||
|
||||
b3Vec3 g(0.0f, 0.0f, 0.0f);
|
||||
m_world.SetGravity(g);
|
||||
|
||||
b3Vec3 f(0.0f, 0.0f, -10000.0f);
|
||||
m_body->ApplyForceToCenter(f, true);
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
Test::Step();
|
||||
|
||||
b3Vec3 q(0.0f, 0.0f, 0.0f);
|
||||
b3Vec3 p = m_body->GetTransform().position;
|
||||
if (b3Distance(p, q) > 50.0f)
|
||||
{
|
||||
b3Quat quat = m_body->GetSweep().orientation;
|
||||
|
||||
b3Vec3 axis;
|
||||
float32 angle;
|
||||
quat.GetAxisAngle(&axis, &angle);
|
||||
m_body->SetTransform(q, axis, angle);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new LinearMotion();
|
||||
}
|
||||
|
||||
b3Body* m_body;
|
||||
};
|
||||
|
||||
#endif
|
176
examples/testbed/tests/mesh_contact_test.h
Normal file
176
examples/testbed/tests/mesh_contact_test.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef MESH_TEST_H
|
||||
#define MESH_TEST_H
|
||||
|
||||
class MeshContactTest : public Test
|
||||
{
|
||||
public:
|
||||
MeshContactTest()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
m_ground = m_world.CreateBody(bd);
|
||||
|
||||
b3MeshShape ms;
|
||||
ms.m_mesh = m_meshes + e_gridMesh;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ms;
|
||||
|
||||
m_ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(0.0f, 5.0f, 0.0f);
|
||||
|
||||
m_body = m_world.CreateBody(bd);
|
||||
|
||||
{
|
||||
b3SphereShape sphere;
|
||||
sphere.m_center.SetZero();
|
||||
sphere.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &sphere;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.5f;
|
||||
|
||||
m_body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyDown(int key)
|
||||
{
|
||||
if (key == GLFW_KEY_S || key == GLFW_KEY_C || key == GLFW_KEY_H)
|
||||
{
|
||||
if (m_body)
|
||||
{
|
||||
m_world.DestroyBody(m_body);
|
||||
}
|
||||
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(0.0f, 5.0f, 0.0f);
|
||||
|
||||
m_body = m_world.CreateBody(bd);
|
||||
|
||||
if (key == GLFW_KEY_S)
|
||||
{
|
||||
b3SphereShape sphere;
|
||||
sphere.m_center.SetZero();
|
||||
sphere.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &sphere;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.5f;
|
||||
|
||||
m_body->CreateShape(sd);
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_C)
|
||||
{
|
||||
b3CapsuleShape capsule;
|
||||
capsule.m_centers[0].Set(0.0f, -1.0f, 0.0f);
|
||||
capsule.m_centers[1].Set(0.0f, 1.0f, 0.0f);
|
||||
capsule.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &capsule;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.5f;
|
||||
|
||||
m_body->CreateShape(sd);
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_H)
|
||||
{
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hull;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.5f;
|
||||
|
||||
m_body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_G || key == GLFW_KEY_T)
|
||||
{
|
||||
if (m_ground)
|
||||
{
|
||||
m_world.DestroyBody(m_ground);
|
||||
}
|
||||
|
||||
b3BodyDef bd;
|
||||
m_ground = m_world.CreateBody(bd);
|
||||
|
||||
if (key == GLFW_KEY_G)
|
||||
{
|
||||
b3MeshShape ms;
|
||||
ms.m_mesh = m_meshes + e_gridMesh;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ms;
|
||||
|
||||
m_ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
if (key == GLFW_KEY_T)
|
||||
{
|
||||
b3MeshShape ms;
|
||||
ms.m_mesh = m_meshes + e_terrainMesh;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ms;
|
||||
|
||||
m_ground->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
Test::Step();
|
||||
|
||||
b3Color color(1.0f, 1.0f, 1.0f);
|
||||
|
||||
g_debugDraw->DrawString("S - Sphere", color);
|
||||
g_debugDraw->DrawString("C - Capsule", color);
|
||||
g_debugDraw->DrawString("H - Hull", color);
|
||||
g_debugDraw->DrawString("G - Grid", color);
|
||||
g_debugDraw->DrawString("T - Terrain", color);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new MeshContactTest();
|
||||
}
|
||||
|
||||
b3Body* m_ground;
|
||||
b3Body* m_body;
|
||||
};
|
||||
|
||||
#endif
|
121
examples/testbed/tests/multiple_shapes.h
Normal file
121
examples/testbed/tests/multiple_shapes.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 MULTIPLE_SHAPES_H
|
||||
#define MULTIPLE_SHAPES_H
|
||||
|
||||
class MultipleShapes : public Test
|
||||
{
|
||||
public:
|
||||
MultipleShapes()
|
||||
{
|
||||
g_camera.m_center.Set(2.0f, -2.0f, 0.0f);
|
||||
g_camera.m_zoom = 50.0f;
|
||||
g_settings.drawCenterOfMasses = true;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.position.Set(-5.0f, 10.0f, 0.0f);
|
||||
m_box1.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.position.Set(5.0f, 10.0f, 0.0f);
|
||||
m_box2.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.position.Set(0.0f, 2.0f, 0.0f);
|
||||
m_box3.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.position.Set(0.0f, 6.0f, 0.0f);
|
||||
m_box4.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.position.Set(0.0f, 10.0f, 0.0f);
|
||||
m_box5.SetTransform(xf);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.angularVelocity.Set(0.0f, B3_PI, 0.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.density = 0.1f;
|
||||
|
||||
hs.m_hull = &m_box1;
|
||||
body->CreateShape(sd);
|
||||
|
||||
hs.m_hull = &m_box2;
|
||||
body->CreateShape(sd);
|
||||
|
||||
hs.m_hull = &m_box3;
|
||||
body->CreateShape(sd);
|
||||
|
||||
hs.m_hull = &m_box4;
|
||||
body->CreateShape(sd);
|
||||
|
||||
hs.m_hull = &m_box5;
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new MultipleShapes();
|
||||
}
|
||||
|
||||
b3BoxHull m_box1;
|
||||
b3BoxHull m_box2;
|
||||
b3BoxHull m_box3;
|
||||
b3BoxHull m_box4;
|
||||
b3BoxHull m_box5;
|
||||
};
|
||||
|
||||
#endif
|
124
examples/testbed/tests/newton_cradle.h
Normal file
124
examples/testbed/tests/newton_cradle.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 NEWTON_CRADLE_H
|
||||
#define NEWTON_CRADLE_H
|
||||
|
||||
class NewtonCradle : public Test
|
||||
{
|
||||
public:
|
||||
NewtonCradle()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3CapsuleShape edge;
|
||||
edge.m_centers[0].Set(0.0f, -10.0f, 0.0f);
|
||||
edge.m_centers[1].Set(0.0f, 10.0f, 0.0f);
|
||||
edge.m_radius = 0.5f;
|
||||
|
||||
b3Body* frame1, *frame2;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
|
||||
bd.position.Set(0.0f, 10.0f, -5.0f);
|
||||
|
||||
frame1 = m_world.CreateBody(bd);
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &edge;
|
||||
|
||||
frame1->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
|
||||
bd.position.Set(0.0f, 10.0f, 5.0f);
|
||||
|
||||
frame2 = m_world.CreateBody(bd);
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &edge;
|
||||
|
||||
frame2->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Vec3 center;
|
||||
center.Set(-5.0f, 4.0f, 0.0f);
|
||||
|
||||
b3SphereShape vertex;
|
||||
vertex.m_center.SetZero();
|
||||
vertex.m_radius = 1.0f;
|
||||
|
||||
u32 count = 6;
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position = center;
|
||||
if (i == count - 1)
|
||||
{
|
||||
bd.linearVelocity.x = 5.0f;
|
||||
}
|
||||
|
||||
b3Body* ball = m_world.CreateBody(bd);
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &vertex;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.8f;
|
||||
|
||||
ball->CreateShape(sd);
|
||||
|
||||
b3Vec3 c1;
|
||||
c1.x = center.x;
|
||||
c1.y = 10.0f;
|
||||
c1.z = 0.0f;
|
||||
|
||||
b3SphereJointDef jd1;
|
||||
jd1.bodyA = frame1;
|
||||
jd1.collideLinked = true;
|
||||
jd1.bodyB = ball;
|
||||
jd1.localAnchorA = b3MulT(frame1->GetTransform(), c1);
|
||||
jd1.localAnchorB = b3MulT(ball->GetTransform(), c1);
|
||||
|
||||
m_world.CreateJoint(jd1);
|
||||
|
||||
center.x += 2.0f * vertex.m_radius;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new NewtonCradle();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
104
examples/testbed/tests/pyramid.h
Normal file
104
examples/testbed/tests/pyramid.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 = 10,
|
||||
};
|
||||
|
||||
Pyramid()
|
||||
{
|
||||
g_camera.m_zoom = 100.0f;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Vec3 boxSize;
|
||||
boxSize.Set(2.0f, 2.0f, 2.0f);
|
||||
|
||||
// shift to ground center
|
||||
b3Vec3 translation;
|
||||
translation.x = -0.5f * float32(e_count) * boxSize.x;
|
||||
translation.y = 1.5f * boxSize.y;
|
||||
translation.z = -0.5f * float32(e_count) * boxSize.z;
|
||||
|
||||
u32 count = e_count;
|
||||
for (u32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
u32 j0 = 0, k0 = 0;
|
||||
for (u32 j = j0; j < count; ++j)
|
||||
{
|
||||
for (u32 k = k0; k < count; ++k)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.x = 1.05f * float32(j) * boxSize.x;
|
||||
bd.position.y = 0.0f;
|
||||
bd.position.z = 1.05f * float32(k) * boxSize.z;
|
||||
bd.position += translation;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.density = 0.5f;
|
||||
sd.friction = 0.5f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
|
||||
// reduce dimension
|
||||
++j0;
|
||||
++k0;
|
||||
--count;
|
||||
|
||||
// increment column
|
||||
translation.y += 1.5f * boxSize.y;
|
||||
// track offset
|
||||
translation.x += 0.5f * boxSize.x;
|
||||
translation.z += 0.5f * boxSize.z;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Pyramid();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
104
examples/testbed/tests/pyramids.h
Normal file
104
examples/testbed/tests/pyramids.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 PYRAMIDS_H
|
||||
#define PYRAMIDS_H
|
||||
|
||||
class Pyramids : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_count = 10,
|
||||
e_depthCount = 10,
|
||||
};
|
||||
|
||||
Pyramids()
|
||||
{
|
||||
g_camera.m_zoom = 100.0f;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Vec3 boxSize;
|
||||
boxSize.Set(2.0f, 2.0f, 2.0f);
|
||||
|
||||
// shift to ground center
|
||||
b3Vec3 translation;
|
||||
translation.x = -0.5f * float32(e_count - 1) * 4.0f * boxSize.x;
|
||||
translation.y = 1.5f * boxSize.y;
|
||||
translation.z = -0.5f * float32(e_depthCount) * boxSize.z;
|
||||
|
||||
for (u32 i = 0; i < e_count; ++i)
|
||||
{
|
||||
// reset
|
||||
translation.y = 1.5f * boxSize.y;
|
||||
translation.z = -0.5f * float32(e_depthCount) * boxSize.z;
|
||||
|
||||
for (u32 j = 0; j < e_depthCount; ++j)
|
||||
{
|
||||
for (u32 k = j; k < e_depthCount; ++k)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.x = 0.0f;
|
||||
bd.position.y = 0.0f;
|
||||
bd.position.z = 1.05f * float32(k) * boxSize.z;
|
||||
bd.position += translation;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.density = 0.5f;
|
||||
sd.friction = 0.5f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
// increment column
|
||||
translation.y += 1.5f * boxSize.y;
|
||||
// track offset
|
||||
translation.z -= 0.5f * boxSize.z;
|
||||
}
|
||||
|
||||
// increment row
|
||||
translation.x += 4.0f * boxSize.x;
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Pyramids();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
142
examples/testbed/tests/quadric_shapes.h
Normal file
142
examples/testbed/tests/quadric_shapes.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 QUADRIC_SHAPES_H
|
||||
#define QUADRIC_SHAPES_H
|
||||
|
||||
#include <testbed/tests/quickhull_test.h>
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Settings g_settings;
|
||||
|
||||
class QuadricShapes : public Test
|
||||
{
|
||||
public:
|
||||
QuadricShapes()
|
||||
{
|
||||
g_camera.m_center.Set(2.0f, -2.0f, 0.0f);
|
||||
g_camera.m_zoom = 20.0f;
|
||||
g_settings.drawCenterOfMasses = true;
|
||||
|
||||
{
|
||||
b3StackArray<b3Vec3, 32> points;
|
||||
ConstructCone(points);
|
||||
|
||||
u32 size = qhGetMemorySize(points.Count());
|
||||
void* p = b3Alloc(size);
|
||||
|
||||
qhHull hull;
|
||||
hull.Construct(p, points);
|
||||
m_coneHull = ConvertHull(hull);
|
||||
|
||||
b3Free(p);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
b3StackArray<b3Vec3, 32> points;
|
||||
ConstructCylinder(points);
|
||||
|
||||
const u32 size = qhGetMemorySize(points.Count());
|
||||
void* p = b3Alloc(size);
|
||||
|
||||
qhHull hull;
|
||||
hull.Construct(p, points);
|
||||
m_cylinderHull = ConvertHull(hull);
|
||||
|
||||
b3Free(p);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(2.0f, 5.0f, 0.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_coneHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.1f;
|
||||
sdef.friction = 0.3f;
|
||||
sdef.shape = &hull;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(-2.0f, 5.0f, 0.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_cylinderHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.1f;
|
||||
sdef.friction = 0.3f;
|
||||
sdef.shape = &hull;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
}
|
||||
|
||||
~QuadricShapes()
|
||||
{
|
||||
{
|
||||
b3Free(m_coneHull.vertices);
|
||||
b3Free(m_coneHull.edges);
|
||||
b3Free(m_coneHull.faces);
|
||||
b3Free(m_coneHull.planes);
|
||||
}
|
||||
|
||||
{
|
||||
b3Free(m_cylinderHull.vertices);
|
||||
b3Free(m_cylinderHull.edges);
|
||||
b3Free(m_cylinderHull.faces);
|
||||
b3Free(m_cylinderHull.planes);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new QuadricShapes();
|
||||
}
|
||||
|
||||
b3Hull m_coneHull;
|
||||
b3Hull m_cylinderHull;
|
||||
};
|
||||
|
||||
#endif
|
420
examples/testbed/tests/quickhull_test.h
Normal file
420
examples/testbed/tests/quickhull_test.h
Normal file
@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 QHULL_H
|
||||
#define QHULL_H
|
||||
|
||||
#include <bounce/quickhull/qh_hull.h>
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Settings g_settings;
|
||||
|
||||
inline b3Vec3 ComputeCentroid(const b3Hull& h)
|
||||
{
|
||||
b3Vec3 c(0.0f, 0.0f, 0.0f);
|
||||
float32 volume = 0.0f;
|
||||
|
||||
// Pick reference point not too away from the origin
|
||||
// to minimize floating point rounding errors.
|
||||
b3Vec3 p1(0.0f, 0.0f, 0.0f);
|
||||
// Put it inside the hull.
|
||||
for (u32 i = 0; i < h.vertexCount; ++i)
|
||||
{
|
||||
p1 += h.vertices[i];
|
||||
}
|
||||
p1 *= 1.0f / float32(h.vertexCount);
|
||||
|
||||
const float32 inv4 = 0.25f;
|
||||
const float32 inv6 = 1.0f / 6.0f;
|
||||
const float32 inv60 = 1.0f / 60.0f;
|
||||
const float32 inv120 = 1.0f / 120.0f;
|
||||
|
||||
b3Vec3 diag(0.0f, 0.0f, 0.0f);
|
||||
b3Vec3 offDiag(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Triangulate convex polygons
|
||||
for (u32 i = 0; i < h.faceCount; ++i)
|
||||
{
|
||||
const b3Face* face = h.GetFace(i);
|
||||
const b3HalfEdge* begin = h.GetEdge(face->edge);
|
||||
|
||||
const b3HalfEdge* edge = h.GetEdge(begin->next);
|
||||
do
|
||||
{
|
||||
u32 i1 = begin->origin;
|
||||
u32 i2 = edge->origin;
|
||||
const b3HalfEdge* next = h.GetEdge(edge->next);
|
||||
u32 i3 = next->origin;
|
||||
|
||||
b3Vec3 p2 = h.vertices[i1];
|
||||
b3Vec3 p3 = h.vertices[i2];
|
||||
b3Vec3 p4 = h.vertices[i3];
|
||||
|
||||
b3Vec3 e1 = p2 - p1;
|
||||
b3Vec3 e2 = p3 - p1;
|
||||
b3Vec3 e3 = p4 - p1;
|
||||
|
||||
float32 D = b3Det(e1, e2, e3);
|
||||
|
||||
float32 tetraVolume = inv6 * D;
|
||||
volume += tetraVolume;
|
||||
|
||||
// Volume weighted centroid
|
||||
c += tetraVolume * inv4 * (e1 + e2 + e3);
|
||||
|
||||
edge = next;
|
||||
} while (h.GetEdge(edge->next) != begin);
|
||||
}
|
||||
|
||||
// Centroid
|
||||
B3_ASSERT(volume > B3_EPSILON);
|
||||
c *= 1.0f / volume;
|
||||
c += p1;
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Pair
|
||||
{
|
||||
void* key;
|
||||
u8 value;
|
||||
};
|
||||
|
||||
struct Map
|
||||
{
|
||||
void Add(const Pair& pair)
|
||||
{
|
||||
m_pairs.PushBack(pair);
|
||||
}
|
||||
|
||||
Pair* Find(void* key)
|
||||
{
|
||||
for (u32 i = 0; i < m_pairs.Count(); ++i)
|
||||
{
|
||||
Pair* pair = m_pairs.Get(i);
|
||||
if (pair->key == key)
|
||||
{
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b3StackArray<Pair, 256> m_pairs;
|
||||
};
|
||||
|
||||
#define NULL_FEATURE 0xFF
|
||||
|
||||
inline b3Hull ConvertHull(const qhHull& hull)
|
||||
{
|
||||
u8 V = 0;
|
||||
u8 E = 0;
|
||||
u8 F = 0;
|
||||
|
||||
qhFace* face = hull.m_faceList.head;
|
||||
while (face)
|
||||
{
|
||||
qhHalfEdge* e = face->edge;
|
||||
do
|
||||
{
|
||||
++E;
|
||||
++V;
|
||||
e = e->next;
|
||||
} while (e != face->edge);
|
||||
|
||||
++F;
|
||||
face = face->next;
|
||||
}
|
||||
|
||||
u8 vertexCount = 0;
|
||||
b3Vec3* vertices = (b3Vec3*)b3Alloc(V * sizeof(b3Vec3));
|
||||
u8 edgeCount = 0;
|
||||
b3HalfEdge* edges = (b3HalfEdge*)b3Alloc(E * sizeof(b3HalfEdge));
|
||||
u8 faceCount = 0;
|
||||
b3Face* faces = (b3Face*)b3Alloc(F * sizeof(b3Face));
|
||||
b3Plane* planes = (b3Plane*)b3Alloc(F * sizeof(b3Plane));
|
||||
|
||||
Map vertexMap;
|
||||
Map edgeMap;
|
||||
|
||||
face = hull.m_faceList.head;
|
||||
while (face)
|
||||
{
|
||||
B3_ASSERT(faceCount < F);
|
||||
u8 iface = faceCount;
|
||||
b3Face* f = faces + faceCount;
|
||||
b3Plane* plane = planes + faceCount;
|
||||
++faceCount;
|
||||
|
||||
*plane = face->plane;
|
||||
|
||||
b3StackArray<u8, 32> faceEdges;
|
||||
|
||||
qhHalfEdge* edge = face->edge;
|
||||
do
|
||||
{
|
||||
qhHalfEdge* twin = edge->twin;
|
||||
qhVertex* v1 = edge->tail;
|
||||
qhVertex* v2 = twin->tail;
|
||||
|
||||
Pair* mte = edgeMap.Find(edge);
|
||||
Pair* mv1 = vertexMap.Find(v1);
|
||||
Pair* mv2 = vertexMap.Find(v2);
|
||||
|
||||
u8 iv1;
|
||||
if (mv1)
|
||||
{
|
||||
iv1 = mv1->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
B3_ASSERT(vertexCount < V);
|
||||
iv1 = vertexCount;
|
||||
vertices[iv1] = v1->position;
|
||||
vertexMap.Add({ v1, iv1 });
|
||||
++vertexCount;
|
||||
}
|
||||
|
||||
u8 iv2;
|
||||
if (mv2)
|
||||
{
|
||||
iv2 = mv2->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
B3_ASSERT(vertexCount < V);
|
||||
iv2 = vertexCount;
|
||||
vertices[iv2] = v2->position;
|
||||
vertexMap.Add({ v2, iv2 });
|
||||
++vertexCount;
|
||||
}
|
||||
|
||||
if (mte)
|
||||
{
|
||||
u8 ie2 = mte->value;
|
||||
b3HalfEdge* e2 = edges + ie2;
|
||||
B3_ASSERT(e2->face == NULL_FEATURE);
|
||||
e2->face = iface;
|
||||
faceEdges.PushBack(ie2);
|
||||
}
|
||||
else
|
||||
{
|
||||
B3_ASSERT(edgeCount < E);
|
||||
u8 ie1 = edgeCount;
|
||||
b3HalfEdge* e1 = edges + edgeCount;
|
||||
++edgeCount;
|
||||
|
||||
B3_ASSERT(edgeCount < E);
|
||||
u8 ie2 = edgeCount;
|
||||
b3HalfEdge* e2 = edges + edgeCount;
|
||||
++edgeCount;
|
||||
|
||||
e1->face = iface;
|
||||
e1->origin = iv1;
|
||||
e1->twin = ie2;
|
||||
|
||||
e2->face = NULL_FEATURE;
|
||||
e2->origin = iv2;
|
||||
e2->twin = ie1;
|
||||
|
||||
faceEdges.PushBack(ie1);
|
||||
|
||||
edgeMap.Add({ edge, ie1 } );
|
||||
edgeMap.Add({ twin, ie2 } );
|
||||
}
|
||||
|
||||
edge = edge->next;
|
||||
} while (edge != face->edge);
|
||||
|
||||
f->edge = faceEdges[0];
|
||||
for (u32 i = 0; i < faceEdges.Count(); ++i)
|
||||
{
|
||||
u32 j = i < faceEdges.Count() - 1 ? i + 1 : 0;
|
||||
edges[faceEdges[i]].next = faceEdges[j];
|
||||
}
|
||||
|
||||
face = face->next;
|
||||
}
|
||||
|
||||
b3Hull out;
|
||||
out.vertexCount = vertexCount;
|
||||
out.vertices = vertices;
|
||||
out.edgeCount = edgeCount;
|
||||
out.edges = edges;
|
||||
out.faceCount = faceCount;
|
||||
out.faces = faces;
|
||||
out.planes = planes;
|
||||
out.centroid = ComputeCentroid(out);
|
||||
out.Validate();
|
||||
return out;
|
||||
}
|
||||
|
||||
inline void ConstructCylinder(b3Array<b3Vec3>& points, float32 radius = 1.0f, float32 height = 1.0f)
|
||||
{
|
||||
{
|
||||
b3Vec3 center(0.0f, 0.0f, 0.0f);
|
||||
|
||||
b3Vec3 normal;
|
||||
normal.Set(0.0f, 1.0f, 0.0f);
|
||||
|
||||
u32 kEdgeCount = 20;
|
||||
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
|
||||
float32 cosInc = cos(kAngleInc);
|
||||
float32 sinInc = sin(kAngleInc);
|
||||
float32 tInc = 1.0f - cosInc;
|
||||
|
||||
b3Vec3 n1 = b3Perp(normal);
|
||||
b3Vec3 v1 = center + radius * n1;
|
||||
for (u32 i = 0; i < kEdgeCount; ++i)
|
||||
{
|
||||
// Rodrigues' rotation formula
|
||||
b3Vec3 n2 = cosInc * n1 + sinInc * b3Cross(normal, n1) + tInc * b3Dot(normal, n1) * normal;
|
||||
b3Vec3 v2 = center + radius * n2;
|
||||
|
||||
points.PushBack(v1);
|
||||
points.PushBack(v2);
|
||||
|
||||
n1 = n2;
|
||||
v1 = v2;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b3Vec3 center(0.0f, height, 0.0f);
|
||||
|
||||
b3Vec3 normal;
|
||||
normal.Set(0.0f, 1.0f, 0.0f);
|
||||
|
||||
u32 kEdgeCount = 20;
|
||||
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
|
||||
float32 cosInc = cos(kAngleInc);
|
||||
float32 sinInc = sin(kAngleInc);
|
||||
float32 tInc = 1.0f - cosInc;
|
||||
|
||||
b3Vec3 n1 = b3Perp(normal);
|
||||
b3Vec3 v1 = center + radius * n1;
|
||||
for (u32 i = 0; i < kEdgeCount; ++i)
|
||||
{
|
||||
// Rodrigues' rotation formula
|
||||
b3Vec3 n2 = cosInc * n1 + sinInc * b3Cross(normal, n1) + tInc * b3Dot(normal, n1) * normal;
|
||||
b3Vec3 v2 = center + radius * n2;
|
||||
|
||||
points.PushBack(v1);
|
||||
points.PushBack(v2);
|
||||
|
||||
n1 = n2;
|
||||
v1 = v2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void ConstructCone(b3Array<b3Vec3>& points, float32 radius = 1.0f, float32 height = 1.0f)
|
||||
{
|
||||
{
|
||||
b3Vec3 center(0.0f, 0.0f, 0.0f);
|
||||
|
||||
b3Vec3 normal;
|
||||
normal.Set(0.0f, 1.0f, 0.0f);
|
||||
|
||||
u32 kEdgeCount = 20;
|
||||
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
|
||||
float32 cosInc = cos(kAngleInc);
|
||||
float32 sinInc = sin(kAngleInc);
|
||||
float32 tInc = 1.0f - cosInc;
|
||||
|
||||
b3Vec3 n1 = b3Perp(normal);
|
||||
b3Vec3 v1 = center + radius * n1;
|
||||
for (u32 i = 0; i < kEdgeCount; ++i)
|
||||
{
|
||||
// Rodrigues' rotation formula
|
||||
b3Vec3 n2 = cosInc * n1 + sinInc * b3Cross(normal, n1) + tInc * b3Dot(normal, n1) * normal;
|
||||
b3Vec3 v2 = center + radius * n2;
|
||||
|
||||
points.PushBack(v1);
|
||||
points.PushBack(v2);
|
||||
|
||||
n1 = n2;
|
||||
v1 = v2;
|
||||
}
|
||||
}
|
||||
|
||||
b3Vec3 c(0.0f, height, 0.0f);
|
||||
points.PushBack(c);
|
||||
}
|
||||
|
||||
class QuickhullTest : public Test
|
||||
{
|
||||
public:
|
||||
QuickhullTest()
|
||||
{
|
||||
g_camera.m_zoom = 15.0f;
|
||||
g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.15f * B3_PI);
|
||||
g_camera.m_q = g_camera.m_q * b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.15f * B3_PI);
|
||||
g_camera.m_center.SetZero();
|
||||
|
||||
b3BoxHull box;
|
||||
box.SetIdentity();
|
||||
|
||||
b3StackArray<b3Vec3, 256> tetra;
|
||||
b3Vec3 v1(-1.0f, 0.0f, 0.0f);
|
||||
b3Vec3 v2(1.0f, 0.0f, 0.0f);
|
||||
b3Vec3 v3(0.0f, 0.0f, -1.0f);
|
||||
b3Vec3 v4 = 0.5f * (v1 + v2 + v3);
|
||||
v4.y += 2.0f;
|
||||
|
||||
tetra.PushBack(v1);
|
||||
tetra.PushBack(v2);
|
||||
tetra.PushBack(v3);
|
||||
tetra.PushBack(v4);
|
||||
|
||||
// Minkowski sum of box and tetrahedron
|
||||
b3StackArray<b3Vec3, 256> points;
|
||||
for (u32 i = 0; i < box.vertexCount; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < tetra.Count(); ++j)
|
||||
{
|
||||
b3Vec3 p = box.vertices[i] - tetra[j];
|
||||
points.PushBack(p);
|
||||
}
|
||||
}
|
||||
|
||||
u32 size = qhGetMemorySize(points.Count());
|
||||
m_memory = b3Alloc(size);
|
||||
m_qhull.Construct(m_memory, points);
|
||||
}
|
||||
|
||||
~QuickhullTest()
|
||||
{
|
||||
b3Free(m_memory);
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
m_qhull.Draw(g_debugDraw);
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new QuickhullTest();
|
||||
}
|
||||
|
||||
void* m_memory;
|
||||
qhHull m_qhull;
|
||||
};
|
||||
|
||||
#endif
|
223
examples/testbed/tests/ragdoll.h
Normal file
223
examples/testbed/tests/ragdoll.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 RAGDOLL_H
|
||||
#define RAGDOLL_H
|
||||
|
||||
class Ragdoll : public Test
|
||||
{
|
||||
public:
|
||||
Ragdoll()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Body* head;
|
||||
b3Body* hip;
|
||||
b3Body* lArm;
|
||||
b3Body* rArm;
|
||||
b3Body* lLeg;
|
||||
b3Body* rLeg;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(0.0f, 10.0f, 0.0f);
|
||||
hip = m_world.CreateBody(bd);
|
||||
|
||||
hip->ApplyForceToCenter(b3Vec3(0.0f, 0.0f, -5000.0f), true);
|
||||
|
||||
b3CapsuleShape cs;
|
||||
cs.m_centers[0].Set(0.0f, 0.5f, 0.0f);
|
||||
cs.m_centers[1].Set(0.0f, -0.5f, 0.0f);
|
||||
cs.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &cs;
|
||||
sd.density = 1.0f;
|
||||
hip->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(0.0f, 12.25f, 0.0f);
|
||||
bd.angularVelocity.Set(0.0f, 0.0f, 0.005f);
|
||||
head = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cs;
|
||||
cs.m_centers[0].Set(0.0f, 0.15f, 0.0f);
|
||||
cs.m_centers[1].Set(0.0f, -0.15f, 0.0f);
|
||||
cs.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &cs;
|
||||
sd.density = 5.0f;
|
||||
head->CreateShape(sd);
|
||||
}
|
||||
|
||||
// Link head to chest
|
||||
{
|
||||
b3ConeJointDef cd;
|
||||
cd.bodyA = hip;
|
||||
cd.bodyB = head;
|
||||
cd.collideLinked = false;
|
||||
cd.enableLimit = true;
|
||||
cd.Initialize(hip, head, b3Vec3(0.0f, 1.0f, 0.0f), b3Vec3(0.0f, 11.55f, 0.0f), 0.25f * B3_PI);
|
||||
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(-2.5f, 11.0f, 0.0f);
|
||||
bd.orientation.Set(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
|
||||
lArm = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cs;
|
||||
cs.m_centers[0].Set(0.0f, 1.0f, 0.0f);
|
||||
cs.m_centers[1].Set(0.0f, -1.0f, 0.0f);
|
||||
cs.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &cs;
|
||||
sd.density = 0.25f;
|
||||
|
||||
lArm->CreateShape(sd);
|
||||
}
|
||||
|
||||
// Link left arm to chest
|
||||
{
|
||||
b3ConeJointDef cd;
|
||||
cd.bodyA = hip;
|
||||
cd.bodyB = lArm;
|
||||
cd.collideLinked = false;
|
||||
cd.enableLimit = true;
|
||||
cd.Initialize(hip, lArm, b3Vec3(-1.0f, 0.0f, 0.0f), b3Vec3(-1.0f, 11.0f, 0.0f), B3_PI);
|
||||
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(2.5f, 11.0f, 0.0f);
|
||||
bd.orientation.Set(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
|
||||
rArm = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cs;
|
||||
cs.m_centers[0].Set(0.0f, 1.0f, 0.0f);
|
||||
cs.m_centers[1].Set(0.0f, -1.0f, 0.0f);
|
||||
cs.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &cs;
|
||||
sd.density = 0.25f;
|
||||
|
||||
rArm->CreateShape(sd);
|
||||
}
|
||||
|
||||
// Link right arm to chest
|
||||
{
|
||||
b3ConeJointDef cd;
|
||||
cd.bodyA = hip;
|
||||
cd.bodyB = rArm;
|
||||
cd.collideLinked = false;
|
||||
cd.enableLimit = true;
|
||||
cd.Initialize(hip, rArm, b3Vec3(1.0f, 0.0f, 0.0f), b3Vec3(1.0f, 11.0f, 0.0f), B3_PI);
|
||||
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(-0.5f, 6.0f, 0.0f);
|
||||
lLeg = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cs;
|
||||
cs.m_centers[0].Set(0.0f, 2.0f, 0.0f);
|
||||
cs.m_centers[1].Set(0.0f, -2.0f, 0.0f);
|
||||
cs.m_radius = 0.45f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &cs;
|
||||
sd.density = 0.25f;
|
||||
|
||||
lLeg->CreateShape(sd);
|
||||
}
|
||||
|
||||
// Link left leg to chest
|
||||
{
|
||||
b3ConeJointDef cd;
|
||||
cd.bodyA = hip;
|
||||
cd.bodyB = lLeg;
|
||||
cd.collideLinked = false;
|
||||
cd.enableLimit = true;
|
||||
cd.Initialize(hip, lLeg, b3Vec3(0.0f, -1.0f, 0.0f), b3Vec3(-0.5f, 8.5f, 0.0f), 0.25f * B3_PI);
|
||||
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = e_dynamicBody;
|
||||
bd.position.Set(0.5f, 6.0f, 0.0f);
|
||||
rLeg = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cs;
|
||||
cs.m_centers[0].Set(0.0f, 2.0f, 0.0f);
|
||||
cs.m_centers[1].Set(0.0f, -2.0f, 0.0f);
|
||||
cs.m_radius = 0.45f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &cs;
|
||||
sd.density = 0.25f;
|
||||
|
||||
rLeg->CreateShape(sd);
|
||||
}
|
||||
|
||||
// Link right leg to chest
|
||||
{
|
||||
b3ConeJointDef cd;
|
||||
cd.bodyA = hip;
|
||||
cd.bodyB = rLeg;
|
||||
cd.collideLinked = false;
|
||||
cd.enableLimit = true;
|
||||
cd.Initialize(hip, rLeg, b3Vec3(0.0f, -1.0f, 0.0f), b3Vec3(0.5f, 8.5f, 0.0f), 0.25f * B3_PI);
|
||||
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyDown(int button)
|
||||
{
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Ragdoll();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
246
examples/testbed/tests/ray_cast.h
Normal file
246
examples/testbed/tests/ray_cast.h
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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
|
||||
|
||||
extern Settings g_settings;
|
||||
|
||||
class RayCast : public Test
|
||||
{
|
||||
public:
|
||||
RayCast()
|
||||
{
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(0.0f, 2.0f, 10.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.25f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(-10.0f, 6.0f, -10.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.25f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_tallHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(10.0f, 2.0f, 0.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.20f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.0f;
|
||||
sdef.friction = 0.0f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(-10.0f, 2.0f, 14.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.05f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.0f;
|
||||
sdef.friction = 0.0f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(-14.0f, 2.0f, 5.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.05f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.0f;
|
||||
sdef.friction = 0.0f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(20.0f, 2.0f, 5.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.05f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.0f;
|
||||
sdef.friction = 0.0f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(12.0f, 2.0f, 5.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.35f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3SphereShape hs;
|
||||
hs.m_radius = 2.5f;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.0f;
|
||||
sdef.friction = 0.0f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
bdef.position.Set(0.0f, 1.0f, -12.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3CapsuleShape hs;
|
||||
hs.m_centers[0].Set(0.0f, 1.0f, 0.0f);
|
||||
hs.m_centers[1].Set(0.0f, -1.0f, 0.0f);
|
||||
hs.m_radius = 3.0f;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 0.0f;
|
||||
sdef.friction = 0.0f;
|
||||
sdef.shape = &hs;
|
||||
sdef.userData = NULL;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
m_p1.Set(0.0f, 2.0f, 0.0f);
|
||||
m_p2.Set(50.0f, 2.0f, 0.0f);
|
||||
|
||||
m_p12.Set(0.0f, 2.0f, 0.0f);
|
||||
m_p22.Set(-50.0f, 2.0f, 0.0f);
|
||||
}
|
||||
|
||||
void CastRay(const b3Vec3 p1, const b3Vec3 p2) const
|
||||
{
|
||||
b3RayCastSingleOutput out;
|
||||
if (m_world.RayCastSingle(&out, p1, p2))
|
||||
{
|
||||
g_debugDraw->DrawSegment(p1, out.point, b3Color(0.0f, 1.0f, 0.0f));
|
||||
g_debugDraw->DrawPoint(out.point, 4.0f, b3Color(1.0f, 0.0f, 0.0f));
|
||||
g_debugDraw->DrawSegment(out.point, out.point + out.normal, b3Color(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debugDraw->DrawSegment(p1, p2, b3Color(0.0f, 1.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f;
|
||||
b3Quat q(b3Vec3(0.0f, 1.0f, 0.0f), dt * 0.05f * B3_PI);
|
||||
|
||||
m_p1 = b3Mul(q, m_p1);
|
||||
m_p2 = b3Mul(q, m_p2);
|
||||
|
||||
m_p12 = b3Mul(q, m_p12);
|
||||
m_p22 = b3Mul(q, m_p22);
|
||||
|
||||
CastRay(m_p1, m_p2);
|
||||
CastRay(m_p12, m_p22);
|
||||
|
||||
Test::Step();
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new RayCast();
|
||||
}
|
||||
|
||||
b3Vec3 m_p1, m_p2;
|
||||
b3Vec3 m_p12, m_p22;
|
||||
};
|
||||
|
||||
#endif
|
164
examples/testbed/tests/sensor_test.h
Normal file
164
examples/testbed/tests/sensor_test.h
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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
|
||||
|
||||
class SensorTest : public Test
|
||||
{
|
||||
public:
|
||||
SensorTest()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.position.Set(0.0f, 6.0f, 0.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_tallHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.isSensor = true;
|
||||
m_sensor = body->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(0.0f, 4.0f, 10.0f);
|
||||
bd.linearVelocity.Set(0.0f, 0.0f, -5.0f);
|
||||
|
||||
m_character = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape cap;
|
||||
cap.m_centers[0].Set(0.0f, 2.0f, 0.0f);
|
||||
cap.m_centers[1].Set(0.0f, -2.0f, 0.0f);
|
||||
cap.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = ∩
|
||||
sd.density = 1.5f;
|
||||
sd.friction = 0.7f;
|
||||
|
||||
m_character->CreateShape(sd);
|
||||
}
|
||||
|
||||
m_attack = false;
|
||||
}
|
||||
|
||||
void BeginContact(b3Contact* c)
|
||||
{
|
||||
b3Shape* sA = c->GetShapeA();
|
||||
b3Body* bA = sA->GetBody();
|
||||
b3Shape* sB = c->GetShapeB();
|
||||
b3Body* bB = sB->GetBody();
|
||||
|
||||
if (sA == m_sensor)
|
||||
{
|
||||
if (bB == m_character)
|
||||
{
|
||||
m_attack = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (sB == m_sensor)
|
||||
{
|
||||
if (bA == m_character)
|
||||
{
|
||||
m_attack = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EndContact(b3Contact* c)
|
||||
{
|
||||
b3Shape* sA = c->GetShapeA();
|
||||
b3Body* bA = sA->GetBody();
|
||||
b3Shape* sB = c->GetShapeB();
|
||||
b3Body* bB = sB->GetBody();
|
||||
|
||||
if (sA == m_sensor)
|
||||
{
|
||||
}
|
||||
|
||||
if (sB == m_sensor)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void Step()
|
||||
{
|
||||
if (m_attack)
|
||||
{
|
||||
b3Body* sensorBody = m_sensor->GetBody();
|
||||
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(RandomFloat(-20.0f, 20.0f), RandomFloat(10.0f, 20.0f), RandomFloat(-20.0f, 20.0f));
|
||||
|
||||
b3Vec3 n = m_character->GetTransform().position - bd.position;
|
||||
n.Normalize();
|
||||
|
||||
bd.linearVelocity = 60.0f * n;
|
||||
|
||||
b3Body* enemy = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape shape;
|
||||
shape.m_center.Set(0.0f, 0.0f, 0.0f);
|
||||
shape.m_radius = 0.5f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &shape;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 1.0f;
|
||||
|
||||
enemy->CreateShape(sd);
|
||||
|
||||
m_attack = false;
|
||||
}
|
||||
|
||||
Test::Step();
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new SensorTest();
|
||||
}
|
||||
|
||||
b3Body* m_character;
|
||||
b3Shape* m_sensor;
|
||||
bool m_attack;
|
||||
};
|
||||
|
||||
#endif
|
108
examples/testbed/tests/shape_stack.h
Normal file
108
examples/testbed/tests/shape_stack.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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_STACK_H
|
||||
#define SHAPE_STACK_H
|
||||
|
||||
class ShapeStack : public Test
|
||||
{
|
||||
public:
|
||||
ShapeStack()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3MeshShape ms;
|
||||
ms.m_mesh = m_meshes + e_gridMesh;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ms;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
|
||||
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(-10.0f, y, 0.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape sphere;
|
||||
sphere.m_center.SetZero();
|
||||
sphere.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &sphere;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.3f;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(0.0f, y, 0.0f);
|
||||
bd.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3CapsuleShape capsule;
|
||||
capsule.m_centers[0].Set(0.0f, -1.0f, 0.0f);
|
||||
capsule.m_centers[1].Set(0.0f, 1.0f, 0.0f);
|
||||
capsule.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &capsule;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.3f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(10.0f, y, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hull;
|
||||
hull.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hull;
|
||||
sd.density = 1.0f;
|
||||
sd.friction = 0.3f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new ShapeStack();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
93
examples/testbed/tests/sphere_stack.h
Normal file
93
examples/testbed/tests/sphere_stack.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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_rowCount = 1,
|
||||
e_columnCount = 5,
|
||||
e_depthCount = 1
|
||||
};
|
||||
|
||||
SphereStack()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_staticBody;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
sd.density = 0.0f;
|
||||
sd.friction = 1.0f;
|
||||
sd.restitution = 0.0f;
|
||||
|
||||
b3Shape* groundShape = ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
b3Vec3 stackOrigin;
|
||||
stackOrigin.Set(0.0f, 5.0f, 0.0f);
|
||||
float32 radius = 1.0f;
|
||||
float32 diameter = 2.0f * radius;
|
||||
|
||||
for (u32 i = 0; i < e_rowCount; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < e_columnCount; ++j)
|
||||
{
|
||||
for (u32 k = 0; k < e_depthCount; ++k)
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_dynamicBody;
|
||||
bdef.position.x = float32(i) * diameter;
|
||||
bdef.position.y = float32(j) * diameter;
|
||||
bdef.position.z = float32(k) * diameter;
|
||||
bdef.position += stackOrigin;
|
||||
bdef.linearVelocity.Set(0.0f, -50.0f, 0.0f);
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3SphereShape sphere;
|
||||
sphere.m_center.SetZero();
|
||||
sphere.m_radius = radius;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &sphere;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.3f;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new SphereStack();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
191
examples/testbed/tests/spring.h
Normal file
191
examples/testbed/tests/spring.h
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 SPRING_H
|
||||
#define SPRING_H
|
||||
|
||||
class Spring : public Test
|
||||
{
|
||||
public:
|
||||
Spring()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
// Car frame shape
|
||||
{
|
||||
b3Transform xf;
|
||||
xf.SetIdentity();
|
||||
xf.rotation = b3Diagonal(2.0f, 0.5f, 5.0f);
|
||||
|
||||
m_frameHull.SetTransform(xf);
|
||||
}
|
||||
|
||||
b3HullShape box;
|
||||
box.m_hull = &m_frameHull;
|
||||
|
||||
// Wheel shape
|
||||
b3SphereShape sphere;
|
||||
sphere.m_center.SetZero();
|
||||
sphere.m_radius = 1.0f;
|
||||
|
||||
// Car frame
|
||||
b3Body* frame;
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(0.0f, 10.0f, 0.0f);
|
||||
|
||||
frame = m_world.CreateBody(bdef);
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.3f;
|
||||
sdef.shape = &box;
|
||||
|
||||
frame->CreateShape(sdef);
|
||||
}
|
||||
|
||||
b3Body* wheelLF;
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(-1.0f, 7.0f, -4.5f);
|
||||
bdef.fixedRotationY = true;
|
||||
|
||||
wheelLF = m_world.CreateBody(bdef);
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &sphere;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 1.0f;
|
||||
|
||||
wheelLF->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3SpringJointDef def;
|
||||
def.Initialize(frame, wheelLF, b3Vec3(-1.0f, 9.0f, -4.5), b3Vec3(-1.0f, 9.0f, -4.5f));
|
||||
def.collideLinked = true;
|
||||
def.dampingRatio = 0.5f;
|
||||
def.frequencyHz = 4.0f;
|
||||
|
||||
m_world.CreateJoint(def);
|
||||
}
|
||||
|
||||
b3Body* wheelRF;
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(1.0f, 7.0, -4.5f);
|
||||
bdef.fixedRotationY = true;
|
||||
|
||||
wheelRF = m_world.CreateBody(bdef);
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 1.0f;
|
||||
sdef.shape = &sphere;
|
||||
|
||||
wheelRF->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3SpringJointDef def;
|
||||
def.Initialize(frame, wheelRF, b3Vec3(1.0f, 9.0, -4.5), b3Vec3(1.0f, 9.0, -4.5f));
|
||||
def.collideLinked = true;
|
||||
def.dampingRatio = 0.5f;
|
||||
def.frequencyHz = 4.0f;
|
||||
|
||||
m_world.CreateJoint(def);
|
||||
}
|
||||
|
||||
b3Body* wheelLB;
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(-1.0f, 7.0f, 4.5f);
|
||||
bdef.fixedRotationY = true;
|
||||
|
||||
wheelLB = m_world.CreateBody(bdef);
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &sphere;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 1.0f;
|
||||
|
||||
wheelLB->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3SpringJointDef def;
|
||||
def.Initialize(frame, wheelLB, b3Vec3(-1.0f, 9.0f, 4.5f), b3Vec3(-1.0f, 9.0f, 4.5f));
|
||||
def.collideLinked = true;
|
||||
def.dampingRatio = 0.8f;
|
||||
def.frequencyHz = 4.0f;
|
||||
|
||||
m_world.CreateJoint(def);
|
||||
}
|
||||
|
||||
b3Body* wheelRB;
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = e_dynamicBody;
|
||||
bdef.position.Set(1.0f, 7.0f, 4.5f);
|
||||
bdef.fixedRotationY = true;
|
||||
|
||||
wheelRB = m_world.CreateBody(bdef);
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 1.0f;
|
||||
sdef.shape = &sphere;
|
||||
|
||||
wheelRB->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3SpringJointDef def;
|
||||
def.Initialize(frame, wheelRB, b3Vec3(1.0f, 9.0f, 4.5f), b3Vec3(1.0f, 9.0f, 4.5f));
|
||||
def.collideLinked = true;
|
||||
def.frequencyHz = 4.0f;
|
||||
def.dampingRatio = 0.8f;
|
||||
|
||||
m_world.CreateJoint(def);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Spring();
|
||||
}
|
||||
|
||||
b3BoxHull m_frameHull;
|
||||
};
|
||||
|
||||
#endif
|
153
examples/testbed/tests/test.h
Normal file
153
examples/testbed/tests/test.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 <glfw/glfw3.h>
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <bounce/bounce.h>
|
||||
|
||||
#include <testbed/framework/debug_draw.h>
|
||||
#include <testbed/framework/profiler.h>
|
||||
|
||||
struct Settings
|
||||
{
|
||||
Settings()
|
||||
{
|
||||
hertz = 60.0f;
|
||||
velocityIterations = 8;
|
||||
positionIterations = 2;
|
||||
sleep = false;
|
||||
warmStart = true;
|
||||
convexCache = true;
|
||||
drawCenterOfMasses = false;
|
||||
drawVerticesEdges = true;
|
||||
drawFaces = true;
|
||||
drawBounds = false;
|
||||
drawJoints = true;
|
||||
drawContactPoints = true;
|
||||
drawContactNormals = false;
|
||||
drawContactTangents = false;
|
||||
drawStats = true;
|
||||
drawProfile = true;
|
||||
drawGrid = true;
|
||||
pause = false;
|
||||
singleStep = false;
|
||||
lastTestID = -1;
|
||||
testID = 0;
|
||||
}
|
||||
|
||||
int lastTestID;
|
||||
int testID;
|
||||
|
||||
float32 hertz;
|
||||
int velocityIterations;
|
||||
int positionIterations;
|
||||
bool sleep;
|
||||
bool warmStart;
|
||||
bool convexCache;
|
||||
bool drawCenterOfMasses;
|
||||
bool drawBounds;
|
||||
bool drawVerticesEdges;
|
||||
bool drawFaces;
|
||||
bool drawSolidShapes;
|
||||
bool drawJoints;
|
||||
bool drawContactPoints;
|
||||
bool drawContactNormals;
|
||||
bool drawContactTangents;
|
||||
bool drawStats;
|
||||
bool drawProfile;
|
||||
bool drawGrid;
|
||||
bool pause;
|
||||
bool singleStep;
|
||||
};
|
||||
|
||||
class Test;
|
||||
|
||||
struct TestEntry
|
||||
{
|
||||
typedef Test* (*TestCreate)();
|
||||
const char* name;
|
||||
TestCreate create;
|
||||
};
|
||||
|
||||
extern TestEntry g_tests[];
|
||||
|
||||
class RayCastListener : public b3RayCastListener
|
||||
{
|
||||
public:
|
||||
float32 ReportShape(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction)
|
||||
{
|
||||
hit.shape = shape;
|
||||
hit.point = point;
|
||||
hit.normal = normal;
|
||||
hit.fraction = fraction;
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
b3RayCastSingleOutput hit;
|
||||
};
|
||||
|
||||
class Test : public b3ContactListener
|
||||
{
|
||||
public:
|
||||
enum Meshes
|
||||
{
|
||||
e_gridMesh,
|
||||
e_terrainMesh,
|
||||
e_clothMesh,
|
||||
e_maxMeshes,
|
||||
};
|
||||
|
||||
Test();
|
||||
virtual ~Test();
|
||||
|
||||
virtual void BeginContact(b3Contact* contact);
|
||||
virtual void EndContact(b3Contact* contact);
|
||||
virtual void PreSolve(b3Contact* contact);
|
||||
|
||||
virtual void Step();
|
||||
virtual void RayHit();
|
||||
|
||||
virtual void MouseMove(const Ray3& pw);
|
||||
virtual void MouseLeftDown(const Ray3& pw);
|
||||
virtual void MouseLeftUp(const Ray3& pw);
|
||||
virtual void KeyDown(int button) { }
|
||||
virtual void KeyUp(int button) { }
|
||||
|
||||
b3World m_world;
|
||||
|
||||
b3RayCastSingleOutput m_rayHit;
|
||||
b3BoxHull m_groundHull;
|
||||
b3BoxHull m_boxHull;
|
||||
b3BoxHull m_tallHull;
|
||||
b3BoxHull m_doorHull;
|
||||
b3BoxHull m_rampHull;
|
||||
b3BoxHull m_plankHull;
|
||||
b3BoxHull m_thinHull;
|
||||
|
||||
b3Hull* m_qhull;
|
||||
|
||||
b3Mesh m_meshes[e_maxMeshes];
|
||||
|
||||
b3MouseJoint* m_mouseJoint;
|
||||
};
|
||||
|
||||
#endif
|
95
examples/testbed/tests/thin.h
Normal file
95
examples/testbed/tests/thin.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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 THIN_H
|
||||
#define THIN_H
|
||||
|
||||
class Thin : public Test
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
e_rowCount = 1,
|
||||
e_columnCount = 10,
|
||||
e_depthCount = 1
|
||||
};
|
||||
|
||||
Thin()
|
||||
{
|
||||
g_camera.m_center.Set(2.5f, -2.0f, 5.5f);
|
||||
g_camera.m_zoom = 40.0f;
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_staticBody;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.friction = 1.0f;
|
||||
|
||||
b3Shape* shape = body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
b3Vec3 stackOrigin;
|
||||
stackOrigin.Set(0.0f, 4.05f, 0.0f);
|
||||
|
||||
b3Vec3 boxScale;
|
||||
boxScale.Set(4.05f, 2.05f, 4.05f);
|
||||
|
||||
for (u32 i = 0; i < e_rowCount; ++i)
|
||||
{
|
||||
for (u32 j = 0; j < e_columnCount; ++j)
|
||||
{
|
||||
for (u32 k = 0; k < e_depthCount; ++k)
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.type = b3BodyType::e_dynamicBody;
|
||||
|
||||
bdef.position.x = float32(i) * boxScale.x;
|
||||
bdef.position.y = 1.5f * float32(j) * boxScale.y;
|
||||
bdef.position.z = float32(k) * boxScale.z;
|
||||
bdef.position += stackOrigin;
|
||||
|
||||
b3Body* body = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_thinHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.density = 0.5f;
|
||||
sdef.friction = 0.2f;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new Thin();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
165
examples/testbed/tests/varying_friction.h
Normal file
165
examples/testbed/tests/varying_friction.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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()
|
||||
{
|
||||
g_camera.m_zoom = 200.0f;
|
||||
g_camera.m_q = b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.1f * B3_PI);
|
||||
g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.1f * B3_PI) * g_camera.m_q;
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
b3Body* ground = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
ground->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.position.Set(-20.0f, 20.0f, 0.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), -0.1f * B3_PI);
|
||||
|
||||
b3Body* ramp = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_rampHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.friction = 0.4f;
|
||||
ramp->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.position.Set(20.0f, 30.0f, 0.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.1f * B3_PI);
|
||||
|
||||
b3Body* ramp = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_rampHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.friction = 0.3f;
|
||||
ramp->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.position.Set(-20.0f, 40.0f, 0.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), -0.1f * B3_PI);
|
||||
|
||||
b3Body* ramp = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_rampHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.friction = 0.2f;
|
||||
ramp->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bdef;
|
||||
bdef.position.Set(20.0f, 50.0f, 0.0f);
|
||||
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.1f * B3_PI);
|
||||
|
||||
b3Body* ramp = m_world.CreateBody(bdef);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_rampHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.shape = &hs;
|
||||
sdef.friction = 0.1f;
|
||||
ramp->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(40.0f, 70.0f, -10.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.2f;
|
||||
sdef.shape = &hs;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(40.0f, 70.0f, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.5f;
|
||||
sdef.shape = &hs;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(40.0f, 70.0f, 10.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_boxHull;
|
||||
|
||||
b3ShapeDef sdef;
|
||||
sdef.density = 1.0f;
|
||||
sdef.friction = 0.8f;
|
||||
sdef.shape = &hs;
|
||||
|
||||
body->CreateShape(sdef);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new VaryingFriction();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
137
examples/testbed/tests/varying_restitution.h
Normal file
137
examples/testbed/tests/varying_restitution.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
|
||||
*
|
||||
* 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
|
||||
|
||||
class VaryingRestitution : public Test
|
||||
{
|
||||
public:
|
||||
VaryingRestitution()
|
||||
{
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* ground = m_world.CreateBody(bd);
|
||||
|
||||
b3HullShape hs;
|
||||
hs.m_hull = &m_groundHull;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &hs;
|
||||
|
||||
ground->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(-10.0f, 10.0f, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape ball;
|
||||
ball.m_center.SetZero();
|
||||
ball.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ball;
|
||||
sd.density = 1.0f;
|
||||
sd.restitution = 0.2f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(-5.0f, 10.0f, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape ball;
|
||||
ball.m_center.SetZero();
|
||||
ball.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ball;
|
||||
sd.density = 1.0f;
|
||||
sd.restitution = 0.4f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(0.0f, 10.0f, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape ball;
|
||||
ball.m_center.SetZero();
|
||||
ball.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ball;
|
||||
sd.density = 1.0f;
|
||||
sd.restitution = 0.6f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(5.0f, 10.0f, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape ball;
|
||||
ball.m_center.SetZero();
|
||||
ball.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ball;
|
||||
sd.density = 1.0f;
|
||||
sd.restitution = 0.8f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
bd.type = b3BodyType::e_dynamicBody;
|
||||
bd.position.Set(10.0f, 10.0f, 0.0f);
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
||||
b3SphereShape ball;
|
||||
ball.m_center.SetZero();
|
||||
ball.m_radius = 1.0f;
|
||||
|
||||
b3ShapeDef sd;
|
||||
sd.shape = &ball;
|
||||
sd.density = 1.0f;
|
||||
sd.restitution = 1.0f;
|
||||
|
||||
body->CreateShape(sd);
|
||||
}
|
||||
}
|
||||
|
||||
static Test* Create()
|
||||
{
|
||||
return new VaryingRestitution();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user