add ImplicitCloth demo, by Stan Melax
add SimpleOpenGL3App, used in ImplicitCloth demo. The Bullet 3.x demos should use this as a template, it will clean up some of the mess.
This commit is contained in:
@@ -65,7 +65,7 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3SimParams
|
||||
m_gravity.setValue(0,-.3,0.f);
|
||||
m_particleRad = 0.01f;
|
||||
m_globalDamping = 1.0f;
|
||||
m_boundaryDamping = -1.f;
|
||||
m_boundaryDamping = -0.99f;
|
||||
m_collisionDamping = 0.025f;//0.02f;
|
||||
m_spring = 0.5f;
|
||||
m_shear = 0.1f;
|
||||
@@ -187,7 +187,7 @@ void ParticleDemo::setupScene(const ConstructionInfo& ci)
|
||||
|
||||
cl_int pErrNum;
|
||||
|
||||
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clData->m_clContext,m_clData->m_clDevice,particleKernelsString,0,"",INTEROPKERNEL_SRC_PATH);
|
||||
cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clData->m_clContext,m_clData->m_clDevice,particleKernelsString,0,"",INTEROPKERNEL_SRC_PATH,true);
|
||||
m_data->m_updatePositionsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice,particleKernelsString, "updatePositionsKernel" ,&pErrNum,prog);
|
||||
oclCHECKERROR(pErrNum, CL_SUCCESS);
|
||||
m_data->m_updatePositionsKernel2 = b3OpenCLUtils::compileCLKernelFromString(m_clData->m_clContext, m_clData->m_clDevice,particleKernelsString, "integrateMotionKernel" ,&pErrNum,prog);
|
||||
@@ -415,7 +415,7 @@ void ParticleDemo::clientMoveAndDisplay()
|
||||
cl_mem pairsGPU = 0;
|
||||
|
||||
{
|
||||
m_data->m_broadphaseGPU->calculateOverlappingPairs(64*numParticles);
|
||||
//m_data->m_broadphaseGPU->calculateOverlappingPairs(64*numParticles);
|
||||
pairsGPU = m_data->m_broadphaseGPU->getOverlappingPairBuffer();
|
||||
numPairsGPU = m_data->m_broadphaseGPU->getNumOverlap();
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ __kernel void integrateMotionKernel( int numParticles,
|
||||
if(pos.y < (worldMin.y + 2*particleRad))
|
||||
{
|
||||
pos.y = worldMin.y + 2*particleRad;
|
||||
vel.y *= -1.f;//1000*boundaryDamping;
|
||||
vel.y *= boundaryDamping;
|
||||
}
|
||||
/*
|
||||
if(pos.y > (worldMax.y - 2*particleRad))
|
||||
|
||||
@@ -84,12 +84,13 @@ enum
|
||||
};
|
||||
|
||||
b3AlignedObjectArray<const char*> demoNames;
|
||||
int selectedDemo = 0;
|
||||
int selectedDemo = 1;
|
||||
GpuDemo::CreateFunc* allDemos[]=
|
||||
{
|
||||
//ConcaveCompound2Scene::MyCreateFunc,
|
||||
|
||||
|
||||
|
||||
|
||||
//ConcaveSphereScene::MyCreateFunc,
|
||||
|
||||
@@ -100,6 +101,7 @@ GpuDemo::CreateFunc* allDemos[]=
|
||||
|
||||
ConcaveScene::MyCreateFunc,
|
||||
|
||||
|
||||
GpuBoxPlaneScene::MyCreateFunc,
|
||||
GpuConstraintsDemo::MyCreateFunc,
|
||||
//GpuConvexPlaneScene::MyCreateFunc,
|
||||
|
||||
83
Demos3/ImplicitCloth/main.cpp
Normal file
83
Demos3/ImplicitCloth/main.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "stan/vecmath.h"
|
||||
#include "stan/Cloth.h"
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
#include "../../btgui/OpenGLWindow/SimpleOpenGL3App.h"
|
||||
|
||||
Cloth* cloth = 0;
|
||||
|
||||
int numX = 60, numY=60;
|
||||
const size_t total_points = (numX)*(numY);
|
||||
|
||||
void drawCloth(class GLInstancingRenderer* renderer)
|
||||
{
|
||||
GLint err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
|
||||
|
||||
err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
|
||||
b3AlignedObjectArray<unsigned int> indices;
|
||||
|
||||
for (int i=0;i<cloth->springs.count;i++)
|
||||
{
|
||||
indices.push_back(cloth->springs[i].a);
|
||||
indices.push_back(cloth->springs[i].b);
|
||||
}
|
||||
float lineColor[4]={0.4,0.4,1.0,1};
|
||||
renderer->drawLines(&cloth->X[0].x,lineColor,total_points,sizeof(float3),&indices[0],indices.size(),1);
|
||||
err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
float pointColor[4]={1,0.4,0.4,1};
|
||||
renderer->drawPoints(&cloth->X[0].x,pointColor,total_points,sizeof(float3),6);
|
||||
err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
float size=10;
|
||||
cloth = ClothCreate(numX,numY,size);
|
||||
|
||||
float dt = 1./120.f;
|
||||
|
||||
SimpleOpenGL3App* app = new SimpleOpenGL3App("title",1024,768);
|
||||
app->m_instancingRenderer->setCameraDistance(13);
|
||||
app->m_instancingRenderer->setCameraPitch(0);
|
||||
app->m_instancingRenderer->setCameraTargetPosition(b3MakeVector3(0,0,0));
|
||||
|
||||
GLint err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
|
||||
do
|
||||
{
|
||||
GLint err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
app->m_instancingRenderer->init();
|
||||
app->m_instancingRenderer->updateCamera();
|
||||
|
||||
app->drawGrid();
|
||||
app->drawText("Cloth simulation using implicit integration, by Stan Melax",10,10);
|
||||
cloth->Simulate(dt);
|
||||
cloth->cloth_gravity.y = -9.8;//-9.8;//-9.8;//-9.8;//0;//-9.8;//0;//-9.8;//0;//-9.8;
|
||||
cloth->cloth_gravity.z =-9.8;//0;//-9.8;//0;//-9.8;
|
||||
|
||||
cloth->spring_struct=10000000.0f;
|
||||
cloth->spring_shear=10000000.0f;
|
||||
|
||||
//cloth->spring_struct=1000000.0f;
|
||||
//cloth->spring_shear=1000000.0f;
|
||||
|
||||
cloth->spring_damp = 0;//100;
|
||||
|
||||
drawCloth(app->m_instancingRenderer);
|
||||
|
||||
app->swapBuffer();
|
||||
} while (!app->m_window->requestedExit());
|
||||
|
||||
delete cloth;
|
||||
delete app;
|
||||
return 0;
|
||||
}
|
||||
70
Demos3/ImplicitCloth/premake4.lua
Normal file
70
Demos3/ImplicitCloth/premake4.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
project "App_ImplicitCloth"
|
||||
|
||||
language "C++"
|
||||
|
||||
kind "ConsoleApp"
|
||||
targetdir "../../bin"
|
||||
|
||||
includedirs {
|
||||
".",
|
||||
"../../btgui"
|
||||
}
|
||||
|
||||
initOpenGL()
|
||||
initGlew()
|
||||
|
||||
--links{"gwen"}
|
||||
|
||||
files {
|
||||
"**.cpp",
|
||||
"**.h",
|
||||
"../../btgui/OpenGLWindow/SimpleOpenGL3App.cpp",
|
||||
"../../btgui/OpenGLWindow/SimpleOpenGL3App.h",
|
||||
"../../btgui/OpenGLWindow/TwFonts.cpp",
|
||||
"../../btgui/OpenGLWindow/TwFonts.h",
|
||||
"../../btgui/OpenGLWindow/LoadShader.cpp",
|
||||
"../../btgui/OpenGLWindow/LoadShader.h",
|
||||
"../../btgui/OpenGLWindow/GLPrimitiveRenderer.cpp",
|
||||
"../../btgui/OpenGLWindow/GLPrimitiveRenderer.h",
|
||||
"../../btgui/OpenGLWindow/GwenOpenGL3CoreRenderer.h",
|
||||
"../../btgui/OpenGLWindow/GLInstancingRenderer.cpp",
|
||||
"../../btgui/OpenGLWindow/GLInstancingRenderer.h",
|
||||
"../../btgui/OpenGLWindow/GLRenderToTexture.cpp",
|
||||
"../../btgui/OpenGLWindow/GLRenderToTexture.h",
|
||||
"../../btgui/OpenGLWindow/TwFonts.cpp",
|
||||
"../../btgui/OpenGLWindow/TwFonts.h",
|
||||
"../../btgui/FontFiles/OpenSans.cpp",
|
||||
"../../btgui/OpenGLTrueTypeFont/fontstash.cpp",
|
||||
"../../btgui/OpenGLTrueTypeFont/fontstash.h",
|
||||
"../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.cpp",
|
||||
"../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.h",
|
||||
"../../btgui/Bullet3Common/**.cpp",
|
||||
"../../btgui/Bullet3Common/**.h",
|
||||
"../../btgui/Timing/b3Clock.cpp",
|
||||
"../../btgui/Timing/b3Clock.h"
|
||||
|
||||
}
|
||||
|
||||
if os.is("Windows") then
|
||||
files {
|
||||
"../../btgui/OpenGLWindow/Win32OpenGLWindow.cpp",
|
||||
"../../btgui/OpenGLWindow/Win32OpenGLWindow.h",
|
||||
"../../btgui/OpenGLWindow/Win32Window.cpp",
|
||||
"../../btgui/OpenGLWindow/Win32Window.h",
|
||||
}
|
||||
end
|
||||
if os.is("Linux") then
|
||||
links ("X11")
|
||||
files{
|
||||
"../../btgui/OpenGLWindow/X11OpenGLWindow.h",
|
||||
"../../btgui/OpenGLWindow/X11OpenGLWindow.cpp"
|
||||
}
|
||||
end
|
||||
if os.is("MacOSX") then
|
||||
links{"Cocoa.framework"}
|
||||
files{
|
||||
"../../btgui/OpenGLWindow/MacOpenGLWindow.mm",
|
||||
"../../btgui/OpenGLWindow/MacOpenGLWindow.h",
|
||||
}
|
||||
end
|
||||
96
Demos3/ImplicitCloth/stan/Cloth.cpp
Normal file
96
Demos3/ImplicitCloth/stan/Cloth.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
//
|
||||
// The remainder of this file shows how to use the spring network class with backward integration
|
||||
// in order to implement a cloth system within a 3D game environment.
|
||||
// The cloth class extends the springnetwork class in order to provide
|
||||
// import/export, rendering support, and hooks into the game.
|
||||
//
|
||||
|
||||
#include "Cloth.h"
|
||||
|
||||
Array<Cloth*> cloths;
|
||||
|
||||
Cloth::Cloth(const char *_name,int _n):SpringNetwork(_n),
|
||||
color(0,0.5f,1.0f)
|
||||
{
|
||||
|
||||
cloths.Add(this);
|
||||
}
|
||||
Cloth::~Cloth()
|
||||
{
|
||||
cloths.Remove(this);
|
||||
}
|
||||
|
||||
//
|
||||
// I/O support for serialization of our springnetwork and cloth objects.
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
int cloth_showbbox = 0; // for debug visualization shows bounding box.
|
||||
float cloth_showvert = 0.025f; // size of box to put around current vert selected, 0 turns off
|
||||
|
||||
|
||||
|
||||
Cloth *ClothCreate(int w,int h,float size)
|
||||
{
|
||||
// simple cloth generation routine that creates a typical square cloth.
|
||||
// better to use a real pipeline to generate these, this is just for testing.
|
||||
int i,j;
|
||||
Cloth *cloth = new Cloth("cloth",w*h);
|
||||
cloth->w=w;
|
||||
cloth->h=h; // later for rendering.
|
||||
for(i=0;i<h;i++)
|
||||
for(j=0;j<w;j++)
|
||||
{
|
||||
cloth->X[i*w+j] = (float3(-0.5f,-0.5f,0)+float3((float)j/(w-1.0f),1.0f-(float)i/(h-1.0f),0)) * size;
|
||||
}
|
||||
for(i=0;i<h;i++)
|
||||
for(j=0;j<w;j++)
|
||||
{
|
||||
if(i<h-1) cloth->CreateSpring(SPRING_STRUCT,i*w+j,(i+1)*w+j); // structural
|
||||
if(j<w-1) cloth->CreateSpring(SPRING_STRUCT,i*w+j,i*w+(j+1)); // structural
|
||||
if(j<w-1&&i<h-1) cloth->CreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j+1)); // shear
|
||||
if(j>0 &&i<h-1) cloth->CreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j-1)); // shear
|
||||
if(i<h-2) cloth->CreateSpring(SPRING_BEND ,i*w+j,(i+2)*w+j); // benders
|
||||
if(j<w-2) cloth->CreateSpring(SPRING_BEND ,i*w+j,i*w+(j+2)); // benders
|
||||
}
|
||||
cloth->UpdateLimits();
|
||||
return cloth;
|
||||
}
|
||||
|
||||
|
||||
int cloth_tess = 20;
|
||||
float3 cloth_spawnpoint(0,3,5.0f);
|
||||
|
||||
|
||||
|
||||
static void ClothDrawSprings(Cloth *cloth)
|
||||
{
|
||||
static const float3 color[3]={float3(1,1,0),float3(1,0,1),float3(0,1,1)};
|
||||
float3N &X = cloth->X;
|
||||
for(int i=0;i<cloth->springs.count;i++)
|
||||
{
|
||||
SpringNetwork::Spring &s = cloth->springs[i];
|
||||
extern void Line(const float3 &,const float3 &,const float3 &color_rgb);
|
||||
Line(X[s.a],X[s.b],color[s.type]);
|
||||
}
|
||||
}
|
||||
|
||||
int cloth_showsprings=0;
|
||||
|
||||
void DoCloths()
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<cloths.count;i++)
|
||||
{
|
||||
Cloth *cloth=cloths[i];
|
||||
|
||||
// cloth->Simulate((cloth->cloth_step<0)?DeltaT:cloth->cloth_step);
|
||||
//if(cloth_showsprings)
|
||||
// ClothDrawSprings(cloth); // debug visualization
|
||||
|
||||
}
|
||||
}
|
||||
18
Demos3/ImplicitCloth/stan/Cloth.h
Normal file
18
Demos3/ImplicitCloth/stan/Cloth.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef STAN_CLOTH_H
|
||||
#define STAN_CLOTH_H
|
||||
|
||||
#include "SpringNetwork.h"
|
||||
|
||||
class Cloth : public SpringNetwork
|
||||
{
|
||||
public:
|
||||
int w,h;
|
||||
|
||||
float3 color; // for debug rendering
|
||||
Cloth(const char* _name,int _n);
|
||||
~Cloth();
|
||||
};
|
||||
|
||||
Cloth *ClothCreate(int w,int h,float size);
|
||||
|
||||
#endif //STAN_CLOTH_H
|
||||
198
Demos3/ImplicitCloth/stan/SpringNetwork.cpp
Normal file
198
Demos3/ImplicitCloth/stan/SpringNetwork.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "vec3n.h"
|
||||
//#include "console.h"
|
||||
|
||||
|
||||
extern int numX;
|
||||
|
||||
|
||||
//
|
||||
// Cloth - Backward Integrated Spring Network
|
||||
//
|
||||
// (c) Stan Melax 2006
|
||||
// http://www.melax.com/cloth
|
||||
// freeware demo and source
|
||||
// Although its free software, I'll gaurantee and support this software as much as is reasonable.
|
||||
// However, if you choose to use any of this code, then you agree that
|
||||
// I assume no financial liability should the software not meet your expectations.
|
||||
// But do feel free to send any feedback.
|
||||
//
|
||||
// The core backward integration functionality has all been extracted into the SpringNetwork class.
|
||||
// This makes it easy for you if you just want to look at or use the math and the algorithms.
|
||||
// The remainder of the code builds a cloth system with basic render support, I/O, and manipulators,
|
||||
// so its possible to make use of the technology within a 3D application.
|
||||
// This code is separated from the SpringNetwork class in order to avoid pushing a particular style
|
||||
// and prevent any dependancies of the algorithms onto unrelated systems.
|
||||
// Feel free to adapt any of this into your own 3D engine/environment.
|
||||
//
|
||||
// Instead of having unique Hooke force and damping coefficients on each spring, the SpringNetwork
|
||||
// code uses a spring 'type' that indexes a short list of shared named coefficients.
|
||||
// This was just more practical for the typical application of this technology.
|
||||
// Over-designed systems that are too general can be slower for
|
||||
// the next guy to understand and more painful to use.
|
||||
// Editing/creation is easier when only 1 number needs to be changed.
|
||||
// Nonetheless, feel free to adapt to your own needs.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "vec3n.h"
|
||||
//#include "console.h"
|
||||
//#include "manipulatori.h"
|
||||
//#include "object.h"
|
||||
//#include "xmlparse.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const float3x3 I(1,0,0,0,1,0,0,0,1);
|
||||
|
||||
inline float3x3 dfdx_spring(const float3 &dir,float length,float rest,float k)
|
||||
{
|
||||
// dir is unit length direction, rest is spring's restlength, k is spring constant.
|
||||
return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k;
|
||||
}
|
||||
inline float3x3 dfdx_damp(const float3 &dir,float length,const float3& vel,float rest,float damping)
|
||||
{
|
||||
// inner spring damping vel is the relative velocity of the endpoints.
|
||||
return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest)));
|
||||
}
|
||||
inline float3x3 dfdv_damp(const float3 &dir,float damping)
|
||||
{
|
||||
// derivative of force wrt velocity.
|
||||
return outerprod(dir,dir) * damping;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "SpringNetwork.h"
|
||||
|
||||
|
||||
SpringNetwork::SpringNetwork(int _n):X(_n),V(_n),F(_n),dV(_n),A(_n),dFdX(_n),dFdV(_n)
|
||||
{
|
||||
assert(SPRING_STRUCT==0);
|
||||
assert(&spring_shear == &spring_struct +SPRING_SHEAR);
|
||||
assert(&spring_bend == &spring_struct +SPRING_BEND);
|
||||
assert(&spring_struct== &spring_k[SPRING_STRUCT]);
|
||||
assert(&spring_shear == &spring_k[SPRING_SHEAR ]);
|
||||
assert(&spring_bend == &spring_k[SPRING_BEND ]);
|
||||
// spring_struct=1000000.0f;
|
||||
// spring_shear=1000000.0f;
|
||||
|
||||
spring_struct=1000.0f;
|
||||
spring_shear=100.0f;
|
||||
|
||||
spring_bend=25.0f;
|
||||
spring_damp=5.0f;
|
||||
spring_air=1.0f;
|
||||
spring_air=1.0f;
|
||||
cloth_step = 0.25f; // delta time for cloth
|
||||
cloth_gravity=float3(0,-10,0);
|
||||
cloth_sleepthreshold = 0.001f;
|
||||
cloth_sleepcount = 100;
|
||||
awake = cloth_sleepcount;
|
||||
|
||||
//fix/pin two points in worldspace
|
||||
float3Nx3N::Block zero;
|
||||
zero.m = float3x3(0,0,0,0,0,0,0,0,0);
|
||||
zero.c = 0;
|
||||
zero.r = 0;
|
||||
S.blocks.Add(zero);
|
||||
zero.r = numX-1;
|
||||
S.blocks.Add(zero);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
SpringNetwork::Spring &SpringNetwork::AddBlocks(Spring &s)
|
||||
{
|
||||
// Called during initial creation of springs in our spring network.
|
||||
// Sets up the sparse matrices corresponding to connections.
|
||||
// Note the indices (s.iab,s.iba) are also stored with spring to avoid looking them up each time a spring is applied
|
||||
// All 3 matrices A,dFdX, and dFdV are contstructed identically so the block array layout will be the same for each.
|
||||
s.iab = A.blocks.count; // added 'ab' blocks will have this index.
|
||||
A.blocks.Add(float3Nx3N::Block(s.a,s.b));
|
||||
dFdX.blocks.Add(float3Nx3N::Block(s.a,s.b));
|
||||
dFdV.blocks.Add(float3Nx3N::Block(s.a,s.b));
|
||||
s.iba = A.blocks.count; // added 'ba' blocks will have this index.
|
||||
A.blocks.Add(float3Nx3N::Block(s.b,s.a));
|
||||
dFdX.blocks.Add(float3Nx3N::Block(s.b,s.a));
|
||||
dFdV.blocks.Add(float3Nx3N::Block(s.b,s.a));
|
||||
return s;
|
||||
}
|
||||
|
||||
void SpringNetwork::PreSolveSpring(const SpringNetwork::Spring &s)
|
||||
{
|
||||
// Adds this spring's contribution into force vector F and force derivitves dFdX and dFdV
|
||||
// One optimization would be premultiply dfdx by dt*dt and F and dFdV by dt right here in this function.
|
||||
// However, for educational purposes we wont do that now and intead just follow the paper directly.
|
||||
//assert(dFdX.blocks[s.a].c==s.a); // delete this assert, no bugs here
|
||||
//assert(dFdX.blocks[s.a].r==s.a);
|
||||
float3 extent = X[s.b] - X[s.a];
|
||||
float length = magnitude(extent);
|
||||
float3 dir = (length==0)?float3(0,0,0): extent * 1.0f/length;
|
||||
float3 vel = V[s.b] - V[s.a];
|
||||
float k = spring_k[s.type];
|
||||
float3 f = dir * ((k * (length-s.restlen) ) + spring_damp * dot(vel,dir)); // spring force + damping force
|
||||
F[s.a] += f;
|
||||
F[s.b] -= f;
|
||||
float3x3 dfdx = dfdx_spring(dir,length,s.restlen,k) + dfdx_damp(dir,length,vel,s.restlen,spring_damp);
|
||||
dFdX.blocks[s.a].m -= dfdx; // diagonal chunk dFdX[a,a]
|
||||
dFdX.blocks[s.b].m -= dfdx; // diagonal chunk dFdX[b,b]
|
||||
dFdX.blocks[s.iab].m += dfdx; // off-diag chunk dFdX[a,b]
|
||||
dFdX.blocks[s.iba].m += dfdx; // off-diag chunk dFdX[b,a]
|
||||
float3x3 dfdv = dfdv_damp(dir,spring_damp);
|
||||
dFdV.blocks[s.a].m -= dfdv; // diagonal chunk dFdV[a,a]
|
||||
dFdV.blocks[s.b].m -= dfdv; // diagonal chunk dFdV[b,b]
|
||||
dFdV.blocks[s.iab].m += dfdv; // off-diag chunk dFdV[a,b]
|
||||
dFdV.blocks[s.iba].m += dfdv; // off-diag chunk dFdV[b,a]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SpringNetwork::CalcForces()
|
||||
{
|
||||
// Collect forces and derivatives: F,dFdX,dFdV
|
||||
dFdX.Zero();
|
||||
dFdV.InitDiagonal(-spring_air);
|
||||
F.Init(cloth_gravity);
|
||||
|
||||
F.element[0]=float3(0,0,0);
|
||||
F.element[numX-1]=float3(0,0,0);
|
||||
|
||||
F -= V * spring_air;
|
||||
for(int i=0;i<springs.count;i++)
|
||||
{
|
||||
PreSolveSpring(springs[i]); // will add to F,dFdX,dFdV
|
||||
}
|
||||
}
|
||||
|
||||
void SpringNetwork::Simulate(float dt)
|
||||
{
|
||||
// Get ready for conjugate gradient iterative solver step.
|
||||
// Initialize operands.
|
||||
if(!awake) return;
|
||||
CalcForces();
|
||||
int n=X.count; // all our big vectors are of this size
|
||||
float3N dFdXmV(n); // temp to store result of matrix multiply
|
||||
float3N B(n);
|
||||
dV.Zero();
|
||||
A.Identity(); // build up the big matrix we feed to solver
|
||||
A -= dFdV * dt + dFdX * (dt*dt) ;
|
||||
|
||||
dFdXmV = dFdX * V;
|
||||
B = F * dt + dFdXmV * (dt*dt);
|
||||
|
||||
ConjGradientFiltered(dV,A,B,S);
|
||||
V = V + dV;
|
||||
// V.element[0] = float3(0,0,0);
|
||||
// V.element[numX-1] = float3(0,0,0);
|
||||
|
||||
X = X + V*dt;
|
||||
|
||||
UpdateLimits();
|
||||
awake = (dot(V,V)<cloth_sleepthreshold)?awake-1:awake=cloth_sleepcount;
|
||||
}
|
||||
63
Demos3/ImplicitCloth/stan/SpringNetwork.h
Normal file
63
Demos3/ImplicitCloth/stan/SpringNetwork.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef STAN_SPRING_NETWORK_H
|
||||
#define STAN_SPRING_NETWORK_H
|
||||
|
||||
#include "vec3n.h"
|
||||
|
||||
#define SPRING_STRUCT (0)
|
||||
#define SPRING_SHEAR (1)
|
||||
#define SPRING_BEND (2)
|
||||
|
||||
|
||||
class SpringNetwork
|
||||
{
|
||||
public:
|
||||
class Spring
|
||||
{
|
||||
public:
|
||||
int type; // index into coefficients spring_k[]
|
||||
float restlen;
|
||||
int a,b; // spring endpoints vector indices
|
||||
int iab,iba; // indices into off-diagonal blocks of sparse matrix
|
||||
Spring(){}
|
||||
Spring(int _type,int _a,int _b,float _restlen):type(_type),a(_a),b(_b),restlen(_restlen){iab=iba=-1;}
|
||||
};
|
||||
Array<Spring> springs;
|
||||
float3N X; // positions of all points
|
||||
float3N V; // velocities
|
||||
float3N F; // force on each point
|
||||
float3N dV; // change in velocity
|
||||
float3Nx3N A; // big matrix we solve system with
|
||||
float3Nx3N dFdX; // big matrix of derivative of force wrt position
|
||||
float3Nx3N dFdV; // big matrix of derivative of force wrt velocity
|
||||
float3Nx3N S; // used for our constraints - contains only some diagonal blocks as needed S[i,i]
|
||||
int awake;
|
||||
float3 bmin,bmax;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float spring_struct;
|
||||
float spring_shear;
|
||||
float spring_bend;
|
||||
};
|
||||
float spring_k[3];
|
||||
};
|
||||
float spring_damp;
|
||||
float spring_air;
|
||||
float cloth_step; // delta time for cloth
|
||||
float3 cloth_gravity;
|
||||
float cloth_sleepthreshold;
|
||||
int cloth_sleepcount;
|
||||
|
||||
SpringNetwork(int _n);
|
||||
Spring &AddBlocks(Spring &s);
|
||||
Spring &CreateSpring(int type,int a,int b,float restlen){return AddBlocks(springs.Add(Spring(type,a,b,restlen)));}
|
||||
Spring &CreateSpring(int type,int a,int b){return CreateSpring(type,a,b,magnitude(X[b]-X[a]));}
|
||||
void UpdateLimits() { BoxLimits(X.element,X.count,bmin,bmax);}
|
||||
void Wake(){awake=cloth_sleepcount;}
|
||||
void Simulate(float dt);
|
||||
void PreSolveSpring(const Spring &s);
|
||||
void CalcForces();
|
||||
};
|
||||
|
||||
#endif //STAN_SPRING_NETWORK_H
|
||||
284
Demos3/ImplicitCloth/stan/array.h
Normal file
284
Demos3/ImplicitCloth/stan/array.h
Normal file
@@ -0,0 +1,284 @@
|
||||
//
|
||||
// Typical template dynamic array container class.
|
||||
// By S Melax 1998
|
||||
//
|
||||
// anyone is free to use, inspect, learn from, or ignore
|
||||
// the code here as they see fit.
|
||||
//
|
||||
// A very simple template array class.
|
||||
// Its easiest to understand this array
|
||||
// class by seeing how it is used in code.
|
||||
//
|
||||
// For example:
|
||||
// for(i=0;i<myarray.count;i++)
|
||||
// myarray[i] = somefunction(i);
|
||||
//
|
||||
// When the array runs out of room, it
|
||||
// reallocates memory and doubles the size of its
|
||||
// storage buffer. The reason for *doubleing* the amount of
|
||||
// memory is so the order of any algorithm using this class
|
||||
// is the same as it would be had you used a regular C array.
|
||||
// The penalty for reallocating and copying
|
||||
// For example consider adding n elements to a list.
|
||||
// Lets sum the number of times elements are "copied".
|
||||
// The worst case occurs when n=2^k+1 where k is integer.
|
||||
// In this case we do a big reallocation when we add the last element.
|
||||
// n elements are copied once, n/2 elements are copied twice,
|
||||
// n/4 elements are copied 3 times, and so on ...
|
||||
// total == n* (1+1/2 + 1/4 + 1/8 + ...) == n * 2
|
||||
// So we do n*2 copies. Therefore adding n
|
||||
// elements to an Array is still O(n).
|
||||
// The memory usage is also of the same order as if a C array was used.
|
||||
// An Array uses less than double the minimum needed space. Again, we
|
||||
// see that we are within a small constant multiple.
|
||||
//
|
||||
// Why no "realloc" to avoid the copy when reallocating memory?
|
||||
// You have a choice to either use malloc/free and friends
|
||||
// or to use new/delete. Its bad mojo to mix these. new/delete was
|
||||
// chosen to be C++ish and have the array elements constructors/destructors
|
||||
// invoked as expected.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef SM_ARRAY_H
|
||||
#define SM_ARRAY_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
template <class Type> class Array {
|
||||
public:
|
||||
Array(int s=0);
|
||||
Array(Array<Type> &array);
|
||||
~Array();
|
||||
void allocate(int s);
|
||||
void SetSize(int s);
|
||||
void Pack();
|
||||
Type& Add(Type);
|
||||
void AddUnique(Type);
|
||||
int Contains(Type);
|
||||
void Insert(Type,int);
|
||||
int IndexOf(Type);
|
||||
void Remove(Type);
|
||||
void DelIndex(int i);
|
||||
Type& DelIndexWithLast(int i);
|
||||
Type * element;
|
||||
int count;
|
||||
int array_size;
|
||||
const Type &operator[](int i) const { assert(i>=0 && i<count); return element[i]; }
|
||||
Type &operator[](int i) { assert(i>=0 && i<count); return element[i]; }
|
||||
Type &Pop() { assert(count); count--; return element[count]; }
|
||||
Array<Type> ©(const Array<Type> &array);
|
||||
Array<Type> &operator=(Array<Type> &array);
|
||||
};
|
||||
|
||||
|
||||
template <class Type> Array<Type>::Array(int s)
|
||||
{
|
||||
if(s==-1) return;
|
||||
count=0;
|
||||
array_size = 0;
|
||||
element = NULL;
|
||||
if(s)
|
||||
{
|
||||
allocate(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Type> Array<Type>::Array(Array<Type> &array)
|
||||
{
|
||||
count=0;
|
||||
array_size = 0;
|
||||
element = NULL;
|
||||
*this = array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class Type> Array<Type> &Array<Type>::copy(const Array<Type> &array)
|
||||
{
|
||||
assert(array.array_size>=0);
|
||||
count=0;
|
||||
for(int i=0;i<array.count;i++)
|
||||
{
|
||||
Add(array[i]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <class Type> Array<Type> &Array<Type>::operator=( Array<Type> &array)
|
||||
{
|
||||
if(array.array_size<0) // negative number means steal the data buffer instead of copying
|
||||
{
|
||||
delete[] element;
|
||||
element = array.element;
|
||||
array_size = -array.array_size;
|
||||
count = array.count;
|
||||
array.count =array.array_size = 0;
|
||||
array.element = NULL;
|
||||
return *this;
|
||||
}
|
||||
count=0;
|
||||
for(int i=0;i<array.count;i++)
|
||||
{
|
||||
Add(array[i]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Type> Array<Type>::~Array()
|
||||
{
|
||||
if (element != NULL && array_size!=0)
|
||||
{
|
||||
delete[] element;
|
||||
}
|
||||
count=0;array_size=0;element=NULL;
|
||||
}
|
||||
|
||||
template <class Type> void Array<Type>::allocate(int s)
|
||||
{
|
||||
assert(s>0);
|
||||
assert(s>=count);
|
||||
if(s==array_size) return;
|
||||
Type *old = element;
|
||||
array_size =s;
|
||||
element = new Type[array_size];
|
||||
assert(element);
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
element[i]=old[i];
|
||||
}
|
||||
if(old) delete[] old;
|
||||
}
|
||||
|
||||
template <class Type> void Array<Type>::SetSize(int s)
|
||||
{
|
||||
if(s==0)
|
||||
{
|
||||
if(element)
|
||||
{
|
||||
delete[] element;
|
||||
element = NULL;
|
||||
}
|
||||
array_size = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
allocate(s);
|
||||
}
|
||||
count=s;
|
||||
}
|
||||
|
||||
template <class Type> void Array<Type>::Pack()
|
||||
{
|
||||
allocate(count);
|
||||
}
|
||||
|
||||
template <class Type> Type& Array<Type>::Add(Type t)
|
||||
{
|
||||
assert(count<=array_size);
|
||||
if(count==array_size)
|
||||
{
|
||||
allocate((array_size)?array_size *2:16);
|
||||
}
|
||||
//int i;
|
||||
//for(i=0;i<count;i++) {
|
||||
// dissallow duplicates
|
||||
// assert(element[i] != t);
|
||||
//}
|
||||
element[count++] = t;
|
||||
return element[count-1];
|
||||
}
|
||||
|
||||
template <class Type> int Array<Type>::Contains(Type t)
|
||||
{
|
||||
int i;
|
||||
int found=0;
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if(element[i] == t) found++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
template <class Type> void Array<Type>::AddUnique(Type t)
|
||||
{
|
||||
if(!Contains(t)) Add(t);
|
||||
}
|
||||
|
||||
|
||||
template <class Type> void Array<Type>::DelIndex(int i)
|
||||
{
|
||||
assert(i<count);
|
||||
count--;
|
||||
while(i<count)
|
||||
{
|
||||
element[i] = element[i+1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Type> Type& Array<Type>::DelIndexWithLast(int i)
|
||||
{
|
||||
assert(i<count);
|
||||
count--;
|
||||
if(i<count)
|
||||
{
|
||||
Type r=element[i];
|
||||
element[i] = element[count];
|
||||
element[count]=r;
|
||||
}
|
||||
return element[count];
|
||||
}
|
||||
|
||||
template <class Type> void Array<Type>::Remove(Type t)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if(element[i] == t)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(i<count); // assert object t is in the array.
|
||||
DelIndex(i);
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
assert(element[i] != t);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Type> void Array<Type>::Insert(Type t,int k)
|
||||
{
|
||||
int i=count;
|
||||
Add(t); // to allocate space
|
||||
while(i>k)
|
||||
{
|
||||
element[i]=element[i-1];
|
||||
i--;
|
||||
}
|
||||
assert(i==k);
|
||||
element[k]=t;
|
||||
}
|
||||
|
||||
|
||||
template <class Type> int Array<Type>::IndexOf(Type t)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if(element[i] == t)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
152
Demos3/ImplicitCloth/stan/vec3n.cpp
Normal file
152
Demos3/ImplicitCloth/stan/vec3n.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
//
|
||||
// Big Vector and Sparse Matrix Classes
|
||||
//
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "vec3n.h"
|
||||
|
||||
|
||||
float conjgrad_lasterror;
|
||||
float conjgrad_epsilon = 0.1f;
|
||||
int conjgrad_loopcount;
|
||||
int conjgrad_looplimit = 100;
|
||||
|
||||
/*EXPORTVAR(conjgrad_lasterror);
|
||||
EXPORTVAR(conjgrad_epsilon );
|
||||
EXPORTVAR(conjgrad_loopcount);
|
||||
EXPORTVAR(conjgrad_looplimit);
|
||||
*/
|
||||
|
||||
int ConjGradient(float3N &X, float3Nx3N &A, float3N &B)
|
||||
{
|
||||
// Solves for unknown X in equation AX=B
|
||||
conjgrad_loopcount=0;
|
||||
int n=B.count;
|
||||
float3N q(n),d(n),tmp(n),r(n);
|
||||
r = B - Mul(tmp,A,X); // just use B if X known to be zero
|
||||
d = r;
|
||||
float s = dot(r,r);
|
||||
float starget = s * squared(conjgrad_epsilon);
|
||||
while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
|
||||
{
|
||||
Mul(q,A,d); // q = A*d;
|
||||
float a = s/dot(d,q);
|
||||
X = X + d*a;
|
||||
if(conjgrad_loopcount%50==0)
|
||||
{
|
||||
r = B - Mul(tmp,A,X);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r - q*a;
|
||||
}
|
||||
float s_prev = s;
|
||||
s = dot(r,r);
|
||||
d = r+d*(s/s_prev);
|
||||
}
|
||||
conjgrad_lasterror = s;
|
||||
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
|
||||
}
|
||||
|
||||
|
||||
int ConjGradientMod(float3N &X, float3Nx3N &A, float3N &B,int3 hack)
|
||||
{
|
||||
// obsolete!!!
|
||||
// Solves for unknown X in equation AX=B
|
||||
conjgrad_loopcount=0;
|
||||
int n=B.count;
|
||||
float3N q(n),d(n),tmp(n),r(n);
|
||||
r = B - Mul(tmp,A,X); // just use B if X known to be zero
|
||||
r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0);
|
||||
d = r;
|
||||
float s = dot(r,r);
|
||||
float starget = s * squared(conjgrad_epsilon);
|
||||
while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
|
||||
{
|
||||
Mul(q,A,d); // q = A*d;
|
||||
q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0,0,0);
|
||||
float a = s/dot(d,q);
|
||||
X = X + d*a;
|
||||
if(conjgrad_loopcount%50==0)
|
||||
{
|
||||
r = B - Mul(tmp,A,X);
|
||||
r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r - q*a;
|
||||
}
|
||||
float s_prev = s;
|
||||
s = dot(r,r);
|
||||
d = r+d*(s/s_prev);
|
||||
d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0,0,0);
|
||||
}
|
||||
conjgrad_lasterror = s;
|
||||
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void filter(float3N &V,const float3Nx3N &S)
|
||||
{
|
||||
for(int i=0;i<S.blocks.count;i++)
|
||||
{
|
||||
V[S.blocks[i].r] = V[S.blocks[i].r]*S.blocks[i].m;
|
||||
}
|
||||
}
|
||||
|
||||
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S)
|
||||
{
|
||||
// Solves for unknown X in equation AX=B
|
||||
conjgrad_loopcount=0;
|
||||
int n=B.count;
|
||||
float3N q(n),d(n),tmp(n),r(n);
|
||||
r = B - Mul(tmp,A,X); // just use B if X known to be zero
|
||||
filter(r,S);
|
||||
d = r;
|
||||
float s = dot(r,r);
|
||||
float starget = s * squared(conjgrad_epsilon);
|
||||
while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
|
||||
{
|
||||
Mul(q,A,d); // q = A*d;
|
||||
filter(q,S);
|
||||
float a = s/dot(d,q);
|
||||
X = X + d*a;
|
||||
if(conjgrad_loopcount%50==0)
|
||||
{
|
||||
r = B - Mul(tmp,A,X);
|
||||
filter(r,S);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r - q*a;
|
||||
}
|
||||
float s_prev = s;
|
||||
s = dot(r,r);
|
||||
d = r+d*(s/s_prev);
|
||||
filter(d,S);
|
||||
}
|
||||
conjgrad_lasterror = s;
|
||||
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// test big vector math library:
|
||||
static void testfloat3N()
|
||||
{
|
||||
float3N a(2),b(2),c(2);
|
||||
a[0] = float3(1,2,3);
|
||||
a[1] = float3(4,5,6);
|
||||
b[0] = float3(10,20,30);
|
||||
b[1] = float3(40,50,60);
|
||||
// c = a+b+b * 10.0f;
|
||||
// float d = dot(a+b,-b);
|
||||
int k;
|
||||
k=0;
|
||||
}
|
||||
class dotest{public:dotest(){testfloat3N();}}do_test_at_program_startup;
|
||||
|
||||
|
||||
340
Demos3/ImplicitCloth/stan/vec3n.h
Normal file
340
Demos3/ImplicitCloth/stan/vec3n.h
Normal file
@@ -0,0 +1,340 @@
|
||||
//
|
||||
// Big Vector and Sparse Matrix Classes
|
||||
//
|
||||
// (c) S Melax 2006
|
||||
//
|
||||
// The focus is on 3D applications, so
|
||||
// the big vector is an array of float3s
|
||||
// and the matrix class uses 3x3 blocks.
|
||||
//
|
||||
// This file includes both:
|
||||
// - basic non-optimized version
|
||||
// - an expression optimized version
|
||||
//
|
||||
// Optimized Expressions
|
||||
//
|
||||
// We want to write sweet looking code such as V=As+Bt with big vectors.
|
||||
// However, we dont want the extra overheads with allocating memory for temps and excessing copying.
|
||||
// Instead of a full Template Metaprogramming approach, we explicitly write
|
||||
// classes to specifically handle all the expressions we are likely to use.
|
||||
// Most applicable lines of code will be of the same handful of basic forms,
|
||||
// but with different parameters for the operands.
|
||||
// In the future, if we ever need a longer expression with more operands,
|
||||
// then we will just add whatever additional building blocks that are necessary - not a big deal.
|
||||
// This approach is much simpler to develop, debug and optimize (restrict keyword, simd etc)
|
||||
// than template metaprogramming is. We do not rely on the implementation
|
||||
// of a particular compiler to be able to expand extensive nested inline codes.
|
||||
// Additionally, we reliably get our optimizations even within a debug build.
|
||||
// Therefore we believe that our Optimized Expressions
|
||||
// are a good compromise that give us the best of both worlds.
|
||||
// The code within those important algorithms, which use this library,
|
||||
// can now remain clean and readable yet still execute quickly.
|
||||
//
|
||||
|
||||
#ifndef SM_VEC3N_H
|
||||
#define SM_VEC3N_H
|
||||
|
||||
#include "vecmath.h"
|
||||
#include "array.h"
|
||||
|
||||
//#include <malloc.h>
|
||||
//template <class T> void * vec4<T>::operator new[](size_t n){ return _mm_malloc(n,64); }
|
||||
//template <class T> void vec4<T>::operator delete[](void *a) { _mm_free(a); }
|
||||
|
||||
|
||||
struct HalfConstraint {
|
||||
float3 n;int vi;
|
||||
float s,t;
|
||||
HalfConstraint(const float3& _n,int _vi,float _t):n(_n),vi(_vi),s(0),t(_t){}
|
||||
HalfConstraint():vi(-1){}
|
||||
};
|
||||
|
||||
class float3Nx3N
|
||||
{
|
||||
public:
|
||||
class Block
|
||||
{
|
||||
public:
|
||||
|
||||
float3x3 m;
|
||||
int r,c;
|
||||
float unused[16];
|
||||
|
||||
|
||||
Block(){}
|
||||
Block(short _r,short _c):r(_r),c(_c){m.x=m.y=m.z=float3(0,0,0);}
|
||||
};
|
||||
Array<Block> blocks; // the first n blocks use as the diagonal.
|
||||
int n;
|
||||
void Zero();
|
||||
void InitDiagonal(float d);
|
||||
void Identity(){InitDiagonal(1.0f);}
|
||||
float3Nx3N():n(0){}
|
||||
float3Nx3N(int _n):n(_n) {for(int i=0;i<n;i++) blocks.Add(Block((short)i,(short)i));}
|
||||
template<class E> float3Nx3N &operator= (const E& expression) {expression.evalequals(*this);return *this;}
|
||||
template<class E> float3Nx3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;}
|
||||
template<class E> float3Nx3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;}
|
||||
};
|
||||
|
||||
class float3N: public Array<float3>
|
||||
{
|
||||
public:
|
||||
float3N(int _count=0)
|
||||
{
|
||||
SetSize(_count);
|
||||
}
|
||||
void Zero();
|
||||
void Init(const float3 &v); // sets each subvector to v
|
||||
template<class E> float3N &operator= (const E& expression) {expression.evalequals(*this);return *this;}
|
||||
template<class E> float3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;}
|
||||
template<class E> float3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;}
|
||||
float3N &operator=( const float3N &V) { this->copy(V); return *this;}
|
||||
};
|
||||
|
||||
int ConjGradient(float3N &X, float3Nx3N &A, float3N &B);
|
||||
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S,Array<HalfConstraint> &H);
|
||||
int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S);
|
||||
|
||||
inline float3N& Mul(float3N &r,const float3Nx3N &m, const float3N &v)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<r.count;i++) r[i]=float3(0,0,0);
|
||||
for(i=0;i<m.blocks.count;i++)
|
||||
{
|
||||
r[m.blocks[i].r] += m.blocks[i].m * v[m.blocks[i].c];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline float dot(const float3N &a,const float3N &b)
|
||||
{
|
||||
float d=0;
|
||||
for(int i=0;i<a.count;i++)
|
||||
{
|
||||
d+= dot(a[i],b[i]);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
inline void float3Nx3N::Zero()
|
||||
{
|
||||
for(int i=0;i<blocks.count;i++)
|
||||
{
|
||||
blocks[i].m = float3x3(0,0,0,0,0,0,0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void float3Nx3N::InitDiagonal(float d)
|
||||
{
|
||||
|
||||
for(int i=0;i<blocks.count;i++)
|
||||
{
|
||||
blocks[i].m = (blocks[i].c==blocks[i].r) ? float3x3(d,0,0,0,d,0,0,0,d) : float3x3(0,0,0,0,0,0,0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void float3N::Zero()
|
||||
{
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
element[i] = float3(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void float3N::Init(const float3 &v)
|
||||
{
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
element[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WE_LIKE_SLOW_CODE
|
||||
|
||||
// Unoptimized Slow Basic Version of big vector operators.
|
||||
// Uses typical implmentation for operators +/-*=
|
||||
// These operators cause lots of unnecessary construction, memory allocation, and copying.
|
||||
|
||||
inline float3N operator +(const float3N &a,const float3N &b)
|
||||
{
|
||||
float3N r(a.count);
|
||||
for(int i=0;i<a.count;i++) r[i]=a[i]+b[i];
|
||||
return r;
|
||||
}
|
||||
|
||||
inline float3N operator *(const float3N &a,const float &s)
|
||||
{
|
||||
float3N r(a.count);
|
||||
for(int i=0;i<a.count;i++) r[i]=a[i]*s;
|
||||
return r;
|
||||
}
|
||||
inline float3N operator /(const float3N &a,const float &s)
|
||||
{
|
||||
float3N r(a.count);
|
||||
return Mul(r,a, 1.0f/s );
|
||||
}
|
||||
inline float3N operator -(const float3N &a,const float3N &b)
|
||||
{
|
||||
float3N r(a.count);
|
||||
for(int i=0;i<a.count;i++) r[i]=a[i]-b[i];
|
||||
return r;
|
||||
}
|
||||
inline float3N operator -(const float3N &a)
|
||||
{
|
||||
float3N r(a.count);
|
||||
for(int i=0;i<a.count;i++) r[i]=-a[i];
|
||||
return r;
|
||||
}
|
||||
|
||||
inline float3N operator *(const float3Nx3N &m,const float3N &v)
|
||||
{
|
||||
float3N r(v.count);
|
||||
return Mul(r,m,v);
|
||||
}
|
||||
inline float3N &operator-=(float3N &A, const float3N &B)
|
||||
{
|
||||
assert(A.count==B.count);
|
||||
for(int i=0;i<A.count;i++) A[i] -= B[i];
|
||||
return A;
|
||||
}
|
||||
inline float3N &operator+=(float3N &A, const float3N &B)
|
||||
{
|
||||
assert(A.count==B.count);
|
||||
for(int i=0;i<A.count;i++) A[i] += B[i];
|
||||
return A;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// Optimized Expressions
|
||||
|
||||
class exVneg
|
||||
{
|
||||
public:
|
||||
const float3N &v;
|
||||
exVneg(const float3N &_v): v(_v){}
|
||||
void evalequals(float3N &r)const { for(int i=0;i<v.count;i++) r[i] =-v[i];}
|
||||
void evalpluseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]+=-v[i];}
|
||||
void evalmnuseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]-=-v[i];}
|
||||
};
|
||||
|
||||
class exVaddV
|
||||
{
|
||||
public:
|
||||
const float3N &a;
|
||||
const float3N &b;
|
||||
exVaddV(const float3N &_a,const float3N &_b): a(_a),b(_b){}
|
||||
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]+b[i];}
|
||||
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]+b[i];}
|
||||
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]+b[i];}
|
||||
};
|
||||
|
||||
class exVsubV
|
||||
{
|
||||
public:
|
||||
const float3N &a;
|
||||
const float3N &b;
|
||||
exVsubV(const float3N &_a,const float3N &_b): a(_a),b(_b){}
|
||||
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]-b[i];}
|
||||
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]-b[i];}
|
||||
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]-b[i];}
|
||||
};
|
||||
|
||||
class exVs
|
||||
{
|
||||
public:
|
||||
const float3N &v;
|
||||
const float s;
|
||||
exVs(const float3N &_v,const float &_s): v(_v),s(_s){}
|
||||
void evalequals(float3N &r)const { for(int i=0;i<v.count;i++) r[i] =v[i]*s;}
|
||||
void evalpluseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]+=v[i]*s;}
|
||||
void evalmnuseq(float3N &r)const { for(int i=0;i<v.count;i++) r[i]-=v[i]*s;}
|
||||
};
|
||||
class exAsaddB
|
||||
{
|
||||
public:
|
||||
const float3N &a;
|
||||
const float3N &b;
|
||||
const float s;
|
||||
exAsaddB(const float3N &_a,const float &_s,const float3N &_b): a(_a),s(_s),b(_b){}
|
||||
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]*s+b[i];}
|
||||
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]*s+b[i];}
|
||||
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]*s+b[i];}
|
||||
};
|
||||
class exAsaddBt
|
||||
{
|
||||
public:
|
||||
const float3N &a;
|
||||
const float3N &b;
|
||||
const float s;
|
||||
const float t;
|
||||
exAsaddBt(const float3N &_a,const float &_s,const float3N &_b,const float &_t): a(_a),s(_s),b(_b),t(_t){}
|
||||
void evalequals(float3N &r)const { for(int i=0;i<a.count;i++) r[i] =a[i]*s+b[i]*t;}
|
||||
void evalpluseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]+=a[i]*s+b[i]*t;}
|
||||
void evalmnuseq(float3N &r)const { for(int i=0;i<a.count;i++) r[i]-=a[i]*s+b[i]*t;}
|
||||
};
|
||||
|
||||
|
||||
class exMv
|
||||
{
|
||||
public:
|
||||
const float3Nx3N &m;
|
||||
const float3N &v;
|
||||
exMv(const float3Nx3N &_m,const float3N &_v): m(_m),v(_v){}
|
||||
void evalequals(float3N &r)const { Mul(r,m,v);}
|
||||
};
|
||||
|
||||
class exMs
|
||||
{
|
||||
public:
|
||||
const float3Nx3N &m;
|
||||
const float s;
|
||||
exMs(const float3Nx3N &_m,const float &_s): m(_m),s(_s){}
|
||||
void evalequals(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m = m.blocks[i].m*s;}
|
||||
void evalpluseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m += m.blocks[i].m*s;}
|
||||
void evalmnuseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m -= m.blocks[i].m*s;}
|
||||
};
|
||||
|
||||
class exMAsMBt
|
||||
{
|
||||
public:
|
||||
const float3Nx3N &a;
|
||||
const float s;
|
||||
const float3Nx3N &b;
|
||||
const float t;
|
||||
exMAsMBt(const float3Nx3N &_a,const float &_s,const float3Nx3N &_b,const float &_t): a(_a),s(_s),b(_b),t(_t){}
|
||||
void evalequals(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m = a.blocks[i].m*s + b.blocks[i].m*t;}
|
||||
void evalpluseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m += a.blocks[i].m*s + b.blocks[i].m*t;}
|
||||
void evalmnuseq(float3Nx3N &r)const { for(int i=0;i<r.blocks.count;i++) r.blocks[i].m -= a.blocks[i].m*s + b.blocks[i].m*t;}
|
||||
};
|
||||
|
||||
inline exVaddV operator +(const float3N &a,const float3N &b) {return exVaddV(a,b);}
|
||||
inline exVsubV operator +(const exVneg &E,const float3N &b) {return exVsubV(b,E.v);}
|
||||
inline exVsubV operator -(const float3N &a,const float3N &b) {return exVsubV(a,b);}
|
||||
inline exVs operator *(const float3N &V,const float &s) {return exVs(V,s); }
|
||||
inline exVs operator *(const exVs &E,const float &s) {return exVs(E.v,E.s*s); }
|
||||
inline exAsaddB operator +(const exVs &E,const float3N &b) {return exAsaddB(E.v, E.s,b);}
|
||||
inline exAsaddB operator +(const float3N &b,const exVs &E) {return exAsaddB(E.v, E.s,b);}
|
||||
inline exAsaddB operator -(const float3N &b,const exVs &E) {return exAsaddB(E.v,-E.s,b);}
|
||||
inline exAsaddBt operator +(const exVs &Ea,const exVs &Eb) {return exAsaddBt(Ea.v,Ea.s,Eb.v, Eb.s);}
|
||||
inline exAsaddBt operator -(const exVs &Ea,const exVs &Eb) {return exAsaddBt(Ea.v,Ea.s,Eb.v,-Eb.s);}
|
||||
inline exMv operator *(const float3Nx3N &m,const float3N &v) {return exMv(m,v); }
|
||||
inline exMs operator *(const exMs &E,const float &s) {return exMs(E.m,E.s*s); }
|
||||
inline exMs operator *(const float3Nx3N &m,const float &s) {return exMs(m,s); }
|
||||
inline exMAsMBt operator +(const exMs &Ea,const exMs &Eb) {return exMAsMBt(Ea.m,Ea.s, Eb.m,Eb.s);}
|
||||
inline exMAsMBt operator -(const exMs &Ea,const exMs &Eb) {return exMAsMBt(Ea.m,Ea.s, Eb.m,-Eb.s);}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1183
Demos3/ImplicitCloth/stan/vecmath.cpp
Normal file
1183
Demos3/ImplicitCloth/stan/vecmath.cpp
Normal file
File diff suppressed because it is too large
Load Diff
466
Demos3/ImplicitCloth/stan/vecmath.h
Normal file
466
Demos3/ImplicitCloth/stan/vecmath.h
Normal file
@@ -0,0 +1,466 @@
|
||||
//
|
||||
//
|
||||
// Typical 3d vector math code.
|
||||
// By S Melax 1998-2008
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef SM_VEC_MATH_H
|
||||
#define SM_VEC_MATH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define M_PIf (3.1415926535897932384626433832795f)
|
||||
|
||||
inline float DegToRad(float angle_degrees) { return angle_degrees * M_PIf / 180.0f; } // returns Radians.
|
||||
inline float RadToDeg(float angle_radians) { return angle_radians * 180.0f / M_PIf; } // returns Degrees.
|
||||
|
||||
#define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL))
|
||||
|
||||
|
||||
|
||||
|
||||
int argmin(const float a[],int n);
|
||||
int argmax(const float a[],int n);
|
||||
float squared(float a);
|
||||
float clamp(float a,const float minval=0.0f, const float maxval=1.0f);
|
||||
int clamp(int a,const int minval,const int maxval) ;
|
||||
float Round(float a,float precision);
|
||||
float Interpolate(const float &f0,const float &f1,float alpha) ;
|
||||
|
||||
template <class T>
|
||||
void Swap(T &a,T &b)
|
||||
{
|
||||
T tmp = a;
|
||||
a=b;
|
||||
b=tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
T Max(const T &a,const T &b)
|
||||
{
|
||||
return (a>b)?a:b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T Min(const T &a,const T &b)
|
||||
{
|
||||
return (a<b)?a:b;
|
||||
}
|
||||
|
||||
//for template normalize functions:
|
||||
inline float squareroot(float a){return sqrtf(a);}
|
||||
inline double squareroot(double a){return sqrt(a); }
|
||||
|
||||
//----------------------------------
|
||||
|
||||
|
||||
|
||||
//-------- 2D --------
|
||||
|
||||
|
||||
template<class T>
|
||||
class vec2
|
||||
{
|
||||
public:
|
||||
T x,y;
|
||||
inline vec2(){x=0;y=0;}
|
||||
inline vec2(const T &_x, const T &_y){x=_x;y=_y;}
|
||||
inline T& operator[](int i) {return ((T*)this)[i];}
|
||||
inline const T& operator[](int i) const {return ((T*)this)[i];}
|
||||
};
|
||||
|
||||
typedef vec2<int> int2;
|
||||
typedef vec2<float> float2;
|
||||
|
||||
|
||||
template<class T> inline int operator ==(const vec2<T> &a,const vec2<T> &b) {return (a.x==b.x && a.y==b.y);}
|
||||
template<class T> inline vec2<T> operator-( const vec2<T>& a, const vec2<T>& b ){return vec2<T>(a.x-b.x,a.y-b.y);}
|
||||
template<class T> inline vec2<T> operator+( const vec2<T>& a, const vec2<T>& b ){return float2(a.x+b.x,a.y+b.y);}
|
||||
|
||||
//--------- 3D ---------
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
class vec3
|
||||
{
|
||||
public:
|
||||
T x,y,z;
|
||||
inline vec3(){x=0;y=0;z=0;};
|
||||
inline vec3(const T &_x,const T &_y,const T &_z){x=_x;y=_y;z=_z;};
|
||||
inline T& operator[](int i) {return ((T*)this)[i];}
|
||||
inline const T& operator[](int i) const {return ((T*)this)[i];}
|
||||
};
|
||||
|
||||
|
||||
typedef vec3<int> int3;
|
||||
typedef vec3<short> short3;
|
||||
typedef vec3<float> float3;
|
||||
|
||||
// due to ambiguity there is no overloaded operators for v3*v3 use dot,cross,outerprod,cmul
|
||||
template<class T> inline int operator==(const vec3<T> &a,const vec3<T> &b) {return (a.x==b.x && a.y==b.y && a.z==b.z);}
|
||||
template<class T> inline int operator!=(const vec3<T> &a,const vec3<T> &b) {return !(a==b);}
|
||||
template<class T> inline vec3<T> operator+(const vec3<T>& a, const vec3<T>& b ){return vec3<T>(a.x+b.x, a.y+b.y, a.z+b.z);}
|
||||
template<class T> inline vec3<T> operator-(const vec3<T>& a, const vec3<T>& b ){return vec3<T>(a.x-b.x, a.y-b.y, a.z-b.z);}
|
||||
template<class T> inline vec3<T> operator-(const vec3<T>& v){return vec3<T>(-v.x,-v.y,-v.z );}
|
||||
template<class T> inline vec3<T> operator*(const vec3<T>& v, const T &s ){ return vec3<T>( v.x*s, v.y*s, v.z*s );}
|
||||
template<class T> inline vec3<T> operator*(T s, const vec3<T>& v ){return v*s;}
|
||||
template<class T> inline vec3<T> operator/(const vec3<T>& v, T s ){return vec3<T>( v.x/s, v.y/s, v.z/s );}
|
||||
template<class T> inline T dot (const vec3<T>& a, const vec3<T>& b){return a.x*b.x + a.y*b.y + a.z*b.z;}
|
||||
template<class T> inline vec3<T> cmul (const vec3<T>& a, const vec3<T>& b){return vec3<T>(a.x*b.x, a.y*b.y, a.z*b.z);}
|
||||
template<class T> inline vec3<T> cross(const vec3<T>& a, const vec3<T>& b){return vec3<T>(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);}
|
||||
template<class T> inline T magnitude( const vec3<T>& v ){return squareroot(dot(v,v));}
|
||||
template<class T> inline vec3<T> normalize( const vec3<T>& v ){return v/magnitude(v);}
|
||||
template<class T> inline vec3<T>& operator+=(vec3<T>& a, const vec3<T>& b){a.x+=b.x;a.y+=b.y;a.z+=b.z;return a;}
|
||||
template<class T> inline vec3<T>& operator-=(vec3<T>& a, const vec3<T>& b){a.x-=b.x;a.y-=b.y;a.z-=b.z;return a;}
|
||||
template<class T> inline vec3<T>& operator*=(vec3<T>& v, T s){v.x*=s;v.y*=s;v.z*= s;return v;}
|
||||
template<class T> inline vec3<T>& operator/=(vec3<T>& v, T s){v.x/=s;v.y/=s;v.z/=s;return v;}
|
||||
|
||||
|
||||
float3 safenormalize(const float3 &v);
|
||||
float3 vabs(const float3 &v);
|
||||
float3 Interpolate(const float3 &v0,const float3 &v1,float alpha);
|
||||
float3 Round(const float3& a,float precision);
|
||||
template<class T> inline vec3<T>VectorMin(const vec3<T> &a,const vec3<T> &b) {return vec3<T>(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z));}
|
||||
template<class T> inline vec3<T>VectorMax(const vec3<T> &a,const vec3<T> &b) {return vec3<T>(Max(a.x,b.x),Max(a.y,b.y),Max(a.z,b.z));}
|
||||
int overlap(const float3 &bmina,const float3 &bmaxa,const float3 &bminb,const float3 &bmaxb);
|
||||
|
||||
template <class T>
|
||||
class mat3x3
|
||||
{
|
||||
public:
|
||||
vec3<T> x,y,z; // the 3 rows of the Matrix
|
||||
inline mat3x3(){}
|
||||
inline mat3x3(const T &xx,const T &xy,const T &xz,const T &yx,const T &yy,const T &yz,const T &zx,const T &zy,const T &zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){}
|
||||
inline mat3x3(const vec3<T> &_x,const vec3<T> &_y,const vec3<T> &_z):x(_x),y(_y),z(_z){}
|
||||
inline vec3<T>& operator[](int i) {return (&x)[i];}
|
||||
inline const vec3<T>& operator[](int i) const {return (&x)[i];}
|
||||
inline T& operator()(int r, int c) {return ((&x)[r])[c];}
|
||||
inline const T& operator()(int r, int c) const {return ((&x)[r])[c];}
|
||||
};
|
||||
typedef mat3x3<float> float3x3;
|
||||
|
||||
float3x3 Transpose( const float3x3& m );
|
||||
template<class T> vec3<T> operator*( const vec3<T>& v , const mat3x3<T>& m )
|
||||
{
|
||||
return vec3<T>((m.x.x*v.x + m.y.x*v.y + m.z.x*v.z),
|
||||
(m.x.y*v.x + m.y.y*v.y + m.z.y*v.z),
|
||||
(m.x.z*v.x + m.y.z*v.y + m.z.z*v.z));
|
||||
}
|
||||
|
||||
float3 operator*( const float3x3& m , const float3& v );
|
||||
float3x3 operator*( const float3x3& m , const float& s );
|
||||
float3x3 operator*( const float3x3& ma, const float3x3& mb );
|
||||
float3x3 operator/( const float3x3& a, const float& s ) ;
|
||||
float3x3 operator+( const float3x3& a, const float3x3& b );
|
||||
float3x3 operator-( const float3x3& a, const float3x3& b );
|
||||
float3x3 &operator+=( float3x3& a, const float3x3& b );
|
||||
float3x3 &operator-=( float3x3& a, const float3x3& b );
|
||||
float3x3 &operator*=( float3x3& a, const float& s );
|
||||
float Determinant(const float3x3& m );
|
||||
float3x3 Inverse(const float3x3& a); // its just 3x3 so we simply do that cofactor method
|
||||
float3x3 outerprod(const float3& a,const float3& b);
|
||||
|
||||
//-------- 4D Math --------
|
||||
|
||||
template<class T>
|
||||
class vec4
|
||||
{
|
||||
public:
|
||||
T x,y,z,w;
|
||||
inline vec4(){x=0;y=0;z=0;w=0;};
|
||||
inline vec4(const T &_x, const T &_y, const T &_z, const T &_w){x=_x;y=_y;z=_z;w=_w;}
|
||||
inline vec4(const vec3<T> &v,const T &_w){x=v.x;y=v.y;z=v.z;w=_w;}
|
||||
//operator float *() { return &x;};
|
||||
T& operator[](int i) {return ((T*)this)[i];}
|
||||
const T& operator[](int i) const {return ((T*)this)[i];}
|
||||
inline const vec3<T>& xyz() const { return *((vec3<T>*)this);}
|
||||
inline vec3<T>& xyz() { return *((vec3<T>*)this);}
|
||||
};
|
||||
|
||||
|
||||
typedef vec4<float> float4;
|
||||
typedef vec4<int> int4;
|
||||
typedef vec4<unsigned char> byte4;
|
||||
|
||||
|
||||
template<class T> inline int operator==(const vec4<T> &a,const vec4<T> &b) {return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);}
|
||||
template<class T> inline int operator!=(const vec4<T> &a,const vec4<T> &b) {return !(a==b);}
|
||||
template<class T> inline vec4<T> operator+(const vec4<T>& a, const vec4<T>& b ){return vec4<T>(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);}
|
||||
template<class T> inline vec4<T> operator-(const vec4<T>& a, const vec4<T>& b ){return vec4<T>(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);}
|
||||
template<class T> inline vec4<T> operator-(const vec4<T>& v){return vec4<T>(-v.x,-v.y,-v.z,-v.w);}
|
||||
template<class T> inline vec4<T> operator*(const vec4<T>& v, const T &s ){ return vec4<T>( v.x*s, v.y*s, v.z*s,v.w*s);}
|
||||
template<class T> inline vec4<T> operator*(T s, const vec4<T>& v ){return v*s;}
|
||||
template<class T> inline vec4<T> operator/(const vec4<T>& v, T s ){return vec4<T>( v.x/s, v.y/s, v.z/s,v.w/s );}
|
||||
template<class T> inline T dot(const vec4<T>& a, const vec4<T>& b ){return a.x*b.x + a.y*b.y + a.z*b.z+a.w*b.w;}
|
||||
template<class T> inline vec4<T> cmul(const vec4<T> &a, const vec4<T> &b) {return vec4<T>(a.x*b.x, a.y*b.y, a.z*b.z,a.w*b.w);}
|
||||
template<class T> inline vec4<T>& operator+=(vec4<T>& a, const vec4<T>& b ){a.x+=b.x;a.y+=b.y;a.z+=b.z;a.w+=b.w;return a;}
|
||||
template<class T> inline vec4<T>& operator-=(vec4<T>& a, const vec4<T>& b ){a.x-=b.x;a.y-=b.y;a.z-=b.z;a.w-=b.w;return a;}
|
||||
template<class T> inline vec4<T>& operator*=(vec4<T>& v, T s){v.x*=s;v.y*=s;v.z*=s;v.w*=s;return v;}
|
||||
template<class T> inline vec4<T>& operator/=(vec4<T>& v, T s){v.x/=s;v.y/=s;v.z/=s;v.w/=s;return v;}
|
||||
template<class T> inline T magnitude( const vec4<T>& v ){return squareroot(dot(v,v));}
|
||||
template<class T> inline vec4<T> normalize( const vec4<T>& v ){return v/magnitude(v);}
|
||||
|
||||
|
||||
|
||||
struct D3DXMATRIX;
|
||||
|
||||
template<class T>
|
||||
class mat4x4
|
||||
{
|
||||
public:
|
||||
vec4<T> x,y,z,w; // the 4 rows
|
||||
inline mat4x4(){}
|
||||
inline mat4x4(const vec4<T> &_x, const vec4<T> &_y, const vec4<T> &_z, const vec4<T> &_w):x(_x),y(_y),z(_z),w(_w){}
|
||||
inline mat4x4(const T& m00, const T& m01, const T& m02, const T& m03,
|
||||
const T& m10, const T& m11, const T& m12, const T& m13,
|
||||
const T& m20, const T& m21, const T& m22, const T& m23,
|
||||
const T& m30, const T& m31, const T& m32, const T& m33 )
|
||||
:x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){}
|
||||
inline vec4<T>& operator[](int i) {assert(i>=0&&i<4);return (&x)[i];}
|
||||
inline const vec4<T>& operator[](int i) const {assert(i>=0&&i<4);return (&x)[i];}
|
||||
inline T& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];}
|
||||
inline const T& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];}
|
||||
inline operator T* () {return &x.x;}
|
||||
inline operator const T* () const {return &x.x;}
|
||||
operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;}
|
||||
operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;}
|
||||
};
|
||||
|
||||
typedef mat4x4<float> float4x4;
|
||||
|
||||
|
||||
float4x4 operator*( const float4x4& a, const float4x4& b );
|
||||
float4 operator*( const float4& v, const float4x4& m );
|
||||
float4x4 Inverse(const float4x4 &m);
|
||||
float4x4 MatrixRigidInverse(const float4x4 &m);
|
||||
float4x4 MatrixTranspose(const float4x4 &m);
|
||||
float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf );
|
||||
float4x4 MatrixTranslation(const float3 &t);
|
||||
float4x4 MatrixRotationZ(const float angle_radians);
|
||||
float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up);
|
||||
int operator==( const float4x4 &a, const float4x4 &b );
|
||||
|
||||
|
||||
//-------- Quaternion ------------
|
||||
|
||||
template<class T>
|
||||
class quaternion : public vec4<T>
|
||||
{
|
||||
public:
|
||||
inline quaternion() { this->x = this->y = this->z = 0.0f; this->w = 1.0f; }
|
||||
inline quaternion(const T &_x, const T &_y, const T &_z, const T &_w){this->x=_x;this->y=_y;this->z=_z;this->w=_w;}
|
||||
inline explicit quaternion(const vec4<T> &v):vec4<T>(v){}
|
||||
T angle() const { return acosf(this->w)*2.0f; }
|
||||
vec3<T> axis() const { vec3<T> a(this->x,this->y,this->z); if(fabsf(angle())<0.0000001f) return vec3<T>(1,0,0); return a*(1/sinf(angle()/2.0f)); }
|
||||
inline vec3<T> xdir() const { return vec3<T>( 1-2*(this->y*this->y+this->z*this->z), 2*(this->x*this->y+this->w*this->z),
|
||||
2*(this->x*this->z-this->w*this->y) ); }
|
||||
inline vec3<T> ydir() const { return vec3<T>( 2*(this->x*this->y-this->w*this->z),1-2*(this->x*this->x+this->z*this->z), 2*(this->y*this->z+this->w*this->x) ); }
|
||||
inline vec3<T> zdir() const { return vec3<T>( 2*(this->x*this->z+this->w*this->y),
|
||||
2*(this->y*this->z-this->w*this->x),1-
|
||||
2*(this->x*this->x+this->y*this->y) ); }
|
||||
inline mat3x3<T> getmatrix() const { return mat3x3<T>( xdir(), ydir(), zdir() ); }
|
||||
//operator float3x3() { return getmatrix(); }
|
||||
void Normalize();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline quaternion<T> quatfrommat(const mat3x3<T> &m)
|
||||
{
|
||||
T magw = m[0 ][ 0] + m[1 ][ 1] + m[2 ][ 2];
|
||||
T magxy;
|
||||
T magzw;
|
||||
vec3<T> pre;
|
||||
vec3<T> prexy;
|
||||
vec3<T> prezw;
|
||||
quaternion<T> postxy;
|
||||
quaternion<T> postzw;
|
||||
quaternion<T> post;
|
||||
int wvsz = (magw > m[2][2] ) ;
|
||||
magzw = (wvsz) ? magw : m[2][2];
|
||||
prezw = (wvsz) ? vec3<T>(1.0f,1.0f,1.0f) : vec3<T>(-1.0f,-1.0f,1.0f) ;
|
||||
postzw = (wvsz) ? quaternion<T>(0.0f,0.0f,0.0f,1.0f): quaternion<T>(0.0f,0.0f,1.0f,0.0f);
|
||||
int xvsy = (m[0][0]>m[1][1]);
|
||||
magxy = (xvsy) ? m[0][0] : m[1][1];
|
||||
prexy = (xvsy) ? vec3<T>(1.0f,-1.0f,-1.0f) : vec3<T>(-1.0f,1.0f,-1.0f) ;
|
||||
postxy = (xvsy) ? quaternion<T>(1.0f,0.0f,0.0f,0.0f): quaternion<T>(0.0f,1.0f,0.0f,0.0f);
|
||||
int zwvsxy = (magzw > magxy);
|
||||
pre = (zwvsxy) ? prezw : prexy ;
|
||||
post = (zwvsxy) ? postzw : postxy;
|
||||
|
||||
T t = pre.x * m[0 ][ 0] + pre.y * m[1 ][ 1] + pre.z * m[2 ][ 2] + 1.0f;
|
||||
T s = 1/sqrt(t) * 0.5f;
|
||||
quaternion<T> qp;
|
||||
qp.x = ( pre.y * m[1][2] - pre.z * m[2][1] ) * s;
|
||||
qp.y = ( pre.z * m[2][0] - pre.x * m[0][2] ) * s;
|
||||
qp.z = ( pre.x * m[0][1] - pre.y * m[1][0] ) * s;
|
||||
qp.w = t * s ;
|
||||
return qp * post ;
|
||||
}
|
||||
|
||||
typedef quaternion<float> Quaternion;
|
||||
|
||||
inline Quaternion QuatFromAxisAngle(const float3 &_v, float angle_radians )
|
||||
{
|
||||
float3 v = normalize(_v)*sinf(angle_radians/2.0f);
|
||||
return Quaternion(v.x,v.y,v.z,cosf(angle_radians/2.0f));
|
||||
}
|
||||
|
||||
template<class T> inline quaternion<T> Conjugate(const quaternion<T> &q){return quaternion<T>(-q.x,-q.y,-q.z,q.w);}
|
||||
template<class T> inline quaternion<T> Inverse(const quaternion<T> &q){return Conjugate(q);}
|
||||
template<class T> inline quaternion<T> normalize( const quaternion<T> & a ){return quaternion<T> (normalize((vec4<T>&)a));}
|
||||
template<class T> inline quaternion<T>& operator*=(quaternion<T>& a, T s ){return (quaternion<T>&)((vec4<T>&)a *=s);}
|
||||
template<class T> inline quaternion<T> operator*( const quaternion<T>& a, float s ){return quaternion<T>((vec4<T>&)a*s);}
|
||||
template<class T> inline quaternion<T> operator+( const quaternion<T>& a, const quaternion<T>& b){return quaternion<T>((vec4<T>&)a+(vec4<T>&)b);}
|
||||
template<class T> inline quaternion<T> operator-( const quaternion<T>& a, const quaternion<T>& b){return quaternion<T>((vec4<T>&)a-(vec4<T>&)b);}
|
||||
template<class T> inline quaternion<T> operator-( const quaternion<T>& b){return quaternion<T>(-(vec4<T>&)b);}
|
||||
template<class T> inline quaternion<T> operator*( const quaternion<T>& a, const quaternion<T>& b)
|
||||
{
|
||||
return quaternion<T>(
|
||||
a.w*b.x + a.x*b.w + a.y*b.z - a.z*b.y, //x
|
||||
a.w*b.y - a.x*b.z + a.y*b.w + a.z*b.x, //y
|
||||
a.w*b.z + a.x*b.y - a.y*b.x + a.z*b.w, //z
|
||||
a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z ); //w
|
||||
}
|
||||
|
||||
|
||||
float3 rotate( const Quaternion& q, const float3& v );
|
||||
//float3 operator*( const Quaternion& q, const float3& v );
|
||||
//float3 operator*( const float3& v, const Quaternion& q );
|
||||
|
||||
Quaternion slerp(const Quaternion &a, const Quaternion& b, float t );
|
||||
Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float t);
|
||||
Quaternion RotationArc(float3 v0, float3 v1 ); // returns quat q where q*v0*q^-1=v1
|
||||
float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v);
|
||||
|
||||
inline Quaternion QuatFromMat(const float3 &t, const float3 &b, const float3 &n)
|
||||
{
|
||||
return normalize(quatfrommat<float>(float3x3(t,b,n)));
|
||||
}
|
||||
|
||||
|
||||
//---------------- Pose ------------------
|
||||
|
||||
class Pose
|
||||
{
|
||||
public:
|
||||
float3 position;
|
||||
Quaternion orientation;
|
||||
Pose(){}
|
||||
Pose(const float3 &p,const Quaternion &q):position(p),orientation(q){}
|
||||
Pose &pose(){return *this;}
|
||||
const Pose &pose() const {return *this;}
|
||||
};
|
||||
|
||||
inline float3 operator*(const Pose &a,const float3 &v)
|
||||
{
|
||||
return a.position + rotate(a.orientation,v);
|
||||
}
|
||||
|
||||
inline Pose operator*(const Pose &a,const Pose &b)
|
||||
{
|
||||
return Pose(a.position + rotate(a.orientation,b.position),a.orientation*b.orientation);
|
||||
}
|
||||
|
||||
inline Pose Inverse(const Pose &a)
|
||||
{
|
||||
Quaternion q = Inverse(a.orientation);
|
||||
return Pose(rotate(q,-a.position),q);
|
||||
}
|
||||
|
||||
inline Pose slerp(const Pose &p0,const Pose &p1,float t)
|
||||
{
|
||||
return Pose(p0.position * (1.0f-t) + p1.position * t,slerp(p0.orientation,p1.orientation,t));
|
||||
}
|
||||
|
||||
inline float4x4 MatrixFromPose(const Pose &pose)
|
||||
{
|
||||
return MatrixFromQuatVec(pose.orientation,pose.position);
|
||||
}
|
||||
|
||||
//------ Euler Angle -----
|
||||
|
||||
Quaternion YawPitchRoll( float yaw, float pitch, float roll );
|
||||
float Yaw( const Quaternion& q );
|
||||
float Pitch( const Quaternion& q );
|
||||
float Roll( const Quaternion &q );
|
||||
float Yaw( const float3& v );
|
||||
float Pitch( const float3& v );
|
||||
|
||||
//------- Plane ----------
|
||||
class Plane : public float4
|
||||
{
|
||||
public:
|
||||
float3& normal(){ return xyz(); }
|
||||
const float3& normal() const { return xyz(); }
|
||||
float& dist(){return w;} // distance below origin - the D from plane equasion Ax+By+Cz+D=0
|
||||
const float& dist() const{return w;} // distance below origin - the D from plane equasion Ax+By+Cz+D=0
|
||||
Plane(const float3 &n,float d):float4(n,d){}
|
||||
Plane(){dist()=0;}
|
||||
explicit Plane(const float4 &v):float4(v){}
|
||||
};
|
||||
|
||||
Plane Transform(const Plane &p, const float3 &translation, const Quaternion &rotation);
|
||||
|
||||
inline Plane PlaneFlip(const Plane &p){return Plane(-p.normal(),-p.dist());}
|
||||
inline int operator==( const Plane &a, const Plane &b ) { return (a.normal()==b.normal() && a.dist()==b.dist()); }
|
||||
inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); }
|
||||
|
||||
float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1);
|
||||
float3 PlaneProject(const Plane &plane, const float3 &point);
|
||||
float3 PlanesIntersection(const Plane &p0,const Plane &p1, const Plane &p2);
|
||||
float3 PlanesIntersection(const Plane *planes,int planes_count,const float3 &seed=float3(0,0,0));
|
||||
|
||||
int Clip(const Plane &p,const float3 *verts_in,int count,float* verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave
|
||||
int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch); //scratch must be preallocated
|
||||
|
||||
|
||||
//--------- Utility Functions ------
|
||||
|
||||
float3 PlaneLineIntersection(const float3 &normal,const float dist, const float3 &p0, const float3 &p1);
|
||||
float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1
|
||||
float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a);
|
||||
int BoxInside(const float3 &p,const float3 &bmin, const float3 &bmax) ;
|
||||
int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact);
|
||||
float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint=NULL, float3 *vpoint=NULL);
|
||||
float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2);
|
||||
float3 NormalOf(const float3 *vert, const int n);
|
||||
Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir0, const float3 &dir1);
|
||||
int Clip(const float3 &plane_normal,float plane_dist,const float3 *verts_in,int count,float* verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave
|
||||
int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch); //scratch must be preallocated
|
||||
float3 Diagonal(const float3x3 &M);
|
||||
Quaternion Diagonalizer(const float3x3 &A);
|
||||
float3 Orth(const float3& v);
|
||||
int SolveQuadratic(float a,float b,float c,float *ta,float *tb); // if true returns roots ta,tb where ta<=tb
|
||||
int HitCheckPoly(const float3 *vert,const int n,const float3 &v0, const float3 &v1, float3 *impact=NULL, float3 *normal=NULL);
|
||||
int HitCheckRaySphere(const float3& sphereposition,float radius, const float3& _v0, const float3& _v1, float3 *impact,float3 *normal);
|
||||
int HitCheckRayCylinder(const float3 &p0,const float3 &p1,float radius,const float3& _v0,const float3& _v1, float3 *impact,float3 *normal);
|
||||
int HitCheckSweptSphereTri(const float3 &p0,const float3 &p1,const float3 &p2,float radius, const float3& v0,const float3& _v1, float3 *impact,float3 *normal);
|
||||
void BoxLimits(const float3 *verts,int verts_count, float3 &bmin_out,float3 &bmax_out);
|
||||
void BoxLimits(const float4 *verts,int verts_count, float3 &bmin_out,float3 &bmax_out);
|
||||
|
||||
|
||||
template<class T>
|
||||
inline int maxdir(const T *p,int count,const T &dir)
|
||||
{
|
||||
assert(count);
|
||||
int m=0;
|
||||
for(int i=1;i<count;i++)
|
||||
{
|
||||
if(dot(p[i],dir)>dot(p[m],dir)) m=i;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
float3 CenterOfMass(const float3 *vertices, const int3 *tris, const int count) ;
|
||||
float3x3 Inertia(const float3 *vertices, const int3 *tris, const int count, const float3& com=float3(0,0,0)) ;
|
||||
float Volume(const float3 *vertices, const int3 *tris, const int count) ;
|
||||
int calchull(float3 *verts,int verts_count, int3 *&tris_out, int &tris_count,int vlimit); // computes convex hull see hull.cpp
|
||||
|
||||
#endif // VEC_MATH_H
|
||||
@@ -1,28 +0,0 @@
|
||||
#include "Bullet2GpuDemo.h"
|
||||
#include "../b3GpuDynamicsWorld.h"
|
||||
#include "GpuRigidBodyDemoInternalData.h"
|
||||
#include "BulletCollision/CollisionShapes/b3BoxShape.h"
|
||||
#include "gpu_rigidbody/host/b3RigidBody.h"
|
||||
|
||||
void Bullet2GpuDemo::setupScene(const ConstructionInfo& ci)
|
||||
{
|
||||
|
||||
// m_data->m_np = np;
|
||||
// m_data->m_bp = bp;
|
||||
// m_data->m_rigidBodyPipeline
|
||||
m_gpuDynamicsWorld = new b3GpuDynamicsWorld(m_data->m_bp,m_data->m_np,m_data->m_rigidBodyPipeline);
|
||||
|
||||
b3Vector3 halfExtents(100,1,100);
|
||||
b3BoxShape* boxShape = new b3BoxShape(halfExtents);
|
||||
b3Vector3 localInertia;
|
||||
b3Scalar mass=1.f;
|
||||
boxShape->calculateLocalInertia(mass,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(mass,0,boxShape,localInertia);
|
||||
m_gpuDynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
void Bullet2GpuDemo::destroyScene()
|
||||
{
|
||||
delete m_gpuDynamicsWorld;
|
||||
m_gpuDynamicsWorld = 0;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef BULLET2_GPU_DEMO_H
|
||||
#define BULLET2_GPU_DEMO_H
|
||||
|
||||
#include "GpuRigidBodyDemo.h"
|
||||
|
||||
class Bullet2GpuDemo : public GpuRigidBodyDemo
|
||||
{
|
||||
protected:
|
||||
|
||||
class b3GpuDynamicsWorld* m_gpuDynamicsWorld;
|
||||
|
||||
public:
|
||||
|
||||
Bullet2GpuDemo(){}
|
||||
virtual ~Bullet2GpuDemo(){}
|
||||
virtual const char* getName()
|
||||
{
|
||||
return "Bullet2Gpu";
|
||||
}
|
||||
|
||||
static GpuDemo* MyCreateFunc()
|
||||
{
|
||||
GpuDemo* demo = new Bullet2GpuDemo;
|
||||
return demo;
|
||||
}
|
||||
|
||||
virtual void setupScene(const ConstructionInfo& ci);
|
||||
virtual void destroyScene();
|
||||
};
|
||||
#endif //BULLET2_GPU_DEMO_H
|
||||
|
||||
@@ -1,611 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 "b3CpuDynamicsWorld.h"
|
||||
#include "b3GpuDynamicsWorld.h"
|
||||
|
||||
|
||||
#define SCALING 1.
|
||||
#define START_POS_X -5
|
||||
#define START_POS_Y 10
|
||||
#define START_POS_Z -3
|
||||
|
||||
#include "LinearMath/b3Vector3.h"
|
||||
|
||||
#include "GpuDemo.h"
|
||||
//#include "GlutStuff.h"
|
||||
///b3BulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
|
||||
//#include "b3BulletDynamicsCommon.h"
|
||||
|
||||
|
||||
#include "BulletCollision/CollisionShapes/b3TriangleMesh.h"
|
||||
#include "BulletCollision/CollisionShapes/b3BvhTriangleMeshShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3SphereShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3ConvexHullShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3BoxShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3CompoundShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3StaticPlaneShape.h"
|
||||
|
||||
#include "BulletDynamics/Dynamics/b3RigidBody.h"
|
||||
#include "LinearMath/b3DefaultMotionState.h"
|
||||
#include "LinearMath/b3Quickprof.h"
|
||||
|
||||
|
||||
#include <stdio.h> //printf debugging
|
||||
|
||||
|
||||
void GpuDemo::clientMoveAndDisplay()
|
||||
{
|
||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//simple dynamics world doesn't handle fixed-time-stepping
|
||||
float dt = getDeltaTimeInSeconds();
|
||||
|
||||
///step the simulation
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
static bool once = true;
|
||||
if (once)
|
||||
{
|
||||
once=false;
|
||||
b3DefaultSerializer* serializer = new b3DefaultSerializer();
|
||||
m_dynamicsWorld->serialize(serializer);
|
||||
|
||||
FILE* file = fopen("testFile.bullet","wb");
|
||||
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
m_dynamicsWorld->stepSimulation(dt);
|
||||
static int count=0;
|
||||
count++;
|
||||
if (count==25)
|
||||
{
|
||||
//b3ProfileManager::dumpAll();
|
||||
}
|
||||
}
|
||||
|
||||
// renderme();
|
||||
|
||||
|
||||
//swapBuffers();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
b3AlignedObjectArray<b3Vector3> vertices;
|
||||
|
||||
void EmptyDemo::setupScene(const ConstructionInfo& ci)
|
||||
{
|
||||
//empty test
|
||||
}
|
||||
|
||||
void SpheresDemo::setupScene(const ConstructionInfo& ci)
|
||||
{
|
||||
|
||||
|
||||
if (1)
|
||||
{
|
||||
b3SphereShape* sphere = new b3SphereShape(1);
|
||||
m_collisionShapes.push_back(sphere);
|
||||
|
||||
/// Create Dynamic Objects
|
||||
b3Transform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
|
||||
|
||||
float start_x = START_POS_X - ci.gapX*ci.arraySizeX/2;
|
||||
float start_y = START_POS_Y;
|
||||
float start_z = START_POS_Z - ci.gapZ*ci.arraySizeZ/2;
|
||||
|
||||
for (int k=0;k<ci.arraySizeY;k++)
|
||||
{
|
||||
int sizeX = ci.arraySizeX;
|
||||
int startX = -sizeX/2;
|
||||
float gapX = ci.gapX;
|
||||
|
||||
for (int i=0;i<sizeX;i++)
|
||||
{
|
||||
int sizeZ = ci.arraySizeZ;
|
||||
int startZ = -sizeX/2;
|
||||
float gapZ =ci.gapZ;
|
||||
for(int j = 0;j<sizeZ;j++)
|
||||
{
|
||||
//b3CollisionShape* shape = k==0? boxShape : colShape;
|
||||
|
||||
b3CollisionShape* shape = sphere;
|
||||
|
||||
|
||||
b3Scalar mass = 1;
|
||||
if (!ci.m_useConcaveMesh && k==0)
|
||||
mass = k==0? 0.f : 1.f;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
b3Vector3 localInertia(0,0,0);
|
||||
if (isDynamic)
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
startTransform.setOrigin(SCALING*b3Vector3(
|
||||
b3Scalar(gapX*i + start_x),
|
||||
b3Scalar(ci.gapY*k + start_y),
|
||||
b3Scalar(gapZ*j + start_z)));
|
||||
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(startTransform);
|
||||
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(rbInfo);
|
||||
|
||||
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
b3Vector3 planeNormal(0,1,0);
|
||||
b3Scalar planeConstant=0;
|
||||
|
||||
b3CollisionShape* shape = new b3StaticPlaneShape(planeNormal,planeConstant);
|
||||
//b3BoxShape* plane = new b3BoxShape(b3Vector3(100,1,100));
|
||||
//plane->initializePolyhedralFeatures();
|
||||
//b3SphereShape* shape = new b3SphereShape(1000);
|
||||
|
||||
b3Scalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
b3Vector3 localInertia(0,0,0);
|
||||
b3Transform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setRotation(b3Quaternion(b3Vector3(1,0,0),0.3));
|
||||
groundTransform.setOrigin(b3Vector3(0,0,0));
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(groundTransform);
|
||||
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(rbInfo);
|
||||
|
||||
//add the body to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GpuCompoundDemo::setupScene(const ConstructionInfo& ci)
|
||||
{
|
||||
b3CollisionShape* groundShape =0;
|
||||
// b3CollisionShape* groundShape = new b3StaticPlaneShape(b3Vector3(0,1,0),50);
|
||||
|
||||
if (ci.m_useConcaveMesh)
|
||||
{
|
||||
b3TriangleMesh* meshInterface = new b3TriangleMesh();
|
||||
|
||||
b3AlignedObjectArray<b3Vector3> concaveVertices;
|
||||
concaveVertices.push_back(b3Vector3(0,-20,0));
|
||||
concaveVertices.push_back(b3Vector3(80,10,80));
|
||||
concaveVertices.push_back(b3Vector3(80,10,-80));
|
||||
concaveVertices.push_back(b3Vector3(-80,10,-80));
|
||||
concaveVertices.push_back(b3Vector3(-80,10,80));
|
||||
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[1],concaveVertices[2],true);
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[2],concaveVertices[3],true);
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[3],concaveVertices[4],true);
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[4],concaveVertices[1],true);
|
||||
|
||||
#if 0
|
||||
groundShape = new b3BvhTriangleMeshShape(meshInterface,true);//b3StaticPlaneShape(b3Vector3(0,1,0),50);
|
||||
#else
|
||||
b3BoxShape* shape =new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(10.),b3Scalar(250.)));
|
||||
shape->initializePolyhedralFeatures();
|
||||
groundShape = shape;
|
||||
#endif
|
||||
|
||||
} else
|
||||
{
|
||||
groundShape = new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(50.),b3Scalar(250.)));
|
||||
}
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
b3Transform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(b3Vector3(0,0,0));
|
||||
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
if (ci.m_useConcaveMesh)
|
||||
{
|
||||
b3Scalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
b3Vector3 localInertia(0,0,0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(groundTransform);
|
||||
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(rbInfo);
|
||||
|
||||
//add the body to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//create a few dynamic rigidbodies
|
||||
// Re-using the same collision is better for memory usage and performance
|
||||
|
||||
//vertices.push_back(b3Vector3(0,1,0));
|
||||
vertices.push_back(b3Vector3(1,1,1));
|
||||
vertices.push_back(b3Vector3(1,1,-1));
|
||||
vertices.push_back(b3Vector3(-1,1,-1));
|
||||
vertices.push_back(b3Vector3(-1,1,1));
|
||||
vertices.push_back(b3Vector3(1,-1,1));
|
||||
vertices.push_back(b3Vector3(1,-1,-1));
|
||||
vertices.push_back(b3Vector3(-1,-1,-1));
|
||||
vertices.push_back(b3Vector3(-1,-1,1));
|
||||
|
||||
#if 0
|
||||
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
|
||||
colShape->initializePolyhedralFeatures();
|
||||
#else
|
||||
b3CompoundShape* compoundShape = 0;
|
||||
{
|
||||
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
|
||||
colShape->initializePolyhedralFeatures();
|
||||
compoundShape = new b3CompoundShape();
|
||||
b3Transform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(b3Vector3(0,-1,0));
|
||||
compoundShape->addChildShape(tr,colShape);
|
||||
tr.setOrigin(b3Vector3(0,0,2));
|
||||
compoundShape->addChildShape(tr,colShape);
|
||||
tr.setOrigin(b3Vector3(2,0,0));
|
||||
compoundShape->addChildShape(tr,colShape);
|
||||
}
|
||||
b3CollisionShape* colShape = compoundShape;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
b3PolyhedralConvexShape* boxShape = new b3BoxShape(b3Vector3(SCALING*1,SCALING*1,SCALING*1));
|
||||
boxShape->initializePolyhedralFeatures();
|
||||
|
||||
|
||||
|
||||
|
||||
//b3CollisionShape* colShape = new b3SphereShape(b3Scalar(1.));
|
||||
m_collisionShapes.push_back(colShape);
|
||||
m_collisionShapes.push_back(boxShape);
|
||||
|
||||
/// Create Dynamic Objects
|
||||
b3Transform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
|
||||
|
||||
float start_x = START_POS_X - ci.arraySizeX/2;
|
||||
float start_y = START_POS_Y;
|
||||
float start_z = START_POS_Z - ci.arraySizeZ/2;
|
||||
|
||||
for (int k=0;k<ci.arraySizeY;k++)
|
||||
{
|
||||
int sizeX = ci.arraySizeX;
|
||||
if (!ci.m_useConcaveMesh && k==0)
|
||||
sizeX = 50;
|
||||
|
||||
int startX = !ci.m_useConcaveMesh&&k==0? -20 : 0;
|
||||
float gapX = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapX;
|
||||
for (int i=0;i<sizeX;i++)
|
||||
{
|
||||
int sizeZ = !ci.m_useConcaveMesh&&k==0? 50 : ci.arraySizeZ;
|
||||
int startZ = (!ci.m_useConcaveMesh)&&k==0? -20 : 0;
|
||||
float gapZ = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapZ;
|
||||
for(int j = 0;j<sizeZ;j++)
|
||||
{
|
||||
//b3CollisionShape* shape = k==0? boxShape : colShape;
|
||||
|
||||
b3CollisionShape* shape = colShape;
|
||||
|
||||
|
||||
b3Scalar mass = 1;
|
||||
if (!ci.m_useConcaveMesh && k==0)
|
||||
mass = k==0? 0.f : 1.f;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
b3Vector3 localInertia(0,0,0);
|
||||
if (isDynamic)
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
startTransform.setOrigin(SCALING*b3Vector3(
|
||||
b3Scalar(startX+gapX*i + start_x),
|
||||
b3Scalar(20+ci.gapY*k + start_y),
|
||||
b3Scalar(startZ+gapZ*j + start_z)));
|
||||
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(startTransform);
|
||||
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(rbInfo);
|
||||
|
||||
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GpuBoxDemo::setupScene(const ConstructionInfo& ci)
|
||||
{
|
||||
b3CollisionShape* groundShape =0;
|
||||
// b3CollisionShape* groundShape = new b3StaticPlaneShape(b3Vector3(0,1,0),50);
|
||||
|
||||
if (ci.m_useConcaveMesh)
|
||||
{
|
||||
b3TriangleMesh* meshInterface = new b3TriangleMesh();
|
||||
|
||||
b3AlignedObjectArray<b3Vector3> concaveVertices;
|
||||
concaveVertices.push_back(b3Vector3(0,-20,0));
|
||||
concaveVertices.push_back(b3Vector3(80,10,80));
|
||||
concaveVertices.push_back(b3Vector3(80,10,-80));
|
||||
concaveVertices.push_back(b3Vector3(-80,10,-80));
|
||||
concaveVertices.push_back(b3Vector3(-80,10,80));
|
||||
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[1],concaveVertices[2],true);
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[2],concaveVertices[3],true);
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[3],concaveVertices[4],true);
|
||||
meshInterface->addTriangle(concaveVertices[0],concaveVertices[4],concaveVertices[1],true);
|
||||
|
||||
#if 0
|
||||
groundShape = new b3BvhTriangleMeshShape(meshInterface,true);//b3StaticPlaneShape(b3Vector3(0,1,0),50);
|
||||
#else
|
||||
b3BoxShape* shape =new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(10.),b3Scalar(250.)));
|
||||
shape->initializePolyhedralFeatures();
|
||||
groundShape = shape;
|
||||
#endif
|
||||
|
||||
} else
|
||||
{
|
||||
groundShape = new b3BoxShape(b3Vector3(b3Scalar(250.),b3Scalar(50.),b3Scalar(250.)));
|
||||
}
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
b3Transform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(b3Vector3(0,0,0));
|
||||
|
||||
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
|
||||
if (ci.m_useConcaveMesh)
|
||||
{
|
||||
b3Scalar mass(0.);
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
b3Vector3 localInertia(0,0,0);
|
||||
if (isDynamic)
|
||||
groundShape->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(groundTransform);
|
||||
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(rbInfo);
|
||||
|
||||
//add the body to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//create a few dynamic rigidbodies
|
||||
// Re-using the same collision is better for memory usage and performance
|
||||
|
||||
//vertices.push_back(b3Vector3(0,1,0));
|
||||
vertices.push_back(b3Vector3(1,1,1));
|
||||
vertices.push_back(b3Vector3(1,1,-1));
|
||||
vertices.push_back(b3Vector3(-1,1,-1));
|
||||
vertices.push_back(b3Vector3(-1,1,1));
|
||||
vertices.push_back(b3Vector3(1,-1,1));
|
||||
vertices.push_back(b3Vector3(1,-1,-1));
|
||||
vertices.push_back(b3Vector3(-1,-1,-1));
|
||||
vertices.push_back(b3Vector3(-1,-1,1));
|
||||
|
||||
#if 1
|
||||
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
|
||||
colShape->initializePolyhedralFeatures();
|
||||
#else
|
||||
b3CompoundShape* compoundShape = 0;
|
||||
{
|
||||
b3PolyhedralConvexShape* colShape = new b3ConvexHullShape(&vertices[0].getX(),vertices.size());
|
||||
colShape->initializePolyhedralFeatures();
|
||||
compoundShape = new b3CompoundShape();
|
||||
b3Transform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(b3Vector3(0,-1,0));
|
||||
compoundShape->addChildShape(tr,colShape);
|
||||
tr.setOrigin(b3Vector3(0,0,2));
|
||||
compoundShape->addChildShape(tr,colShape);
|
||||
tr.setOrigin(b3Vector3(2,0,0));
|
||||
compoundShape->addChildShape(tr,colShape);
|
||||
}
|
||||
b3CollisionShape* colShape = compoundShape;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
b3PolyhedralConvexShape* boxShape = new b3BoxShape(b3Vector3(SCALING*1,SCALING*1,SCALING*1));
|
||||
boxShape->initializePolyhedralFeatures();
|
||||
|
||||
|
||||
|
||||
|
||||
//b3CollisionShape* colShape = new b3SphereShape(b3Scalar(1.));
|
||||
m_collisionShapes.push_back(colShape);
|
||||
m_collisionShapes.push_back(boxShape);
|
||||
|
||||
/// Create Dynamic Objects
|
||||
b3Transform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
|
||||
|
||||
float start_x = START_POS_X - ci.arraySizeX/2;
|
||||
float start_y = START_POS_Y;
|
||||
float start_z = START_POS_Z - ci.arraySizeZ/2;
|
||||
|
||||
for (int k=0;k<ci.arraySizeY;k++)
|
||||
{
|
||||
int sizeX = ci.arraySizeX;
|
||||
if (!ci.m_useConcaveMesh && k==0)
|
||||
sizeX = 50;
|
||||
|
||||
int startX = !ci.m_useConcaveMesh&&k==0? -20 : 0;
|
||||
float gapX = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapX;
|
||||
for (int i=0;i<sizeX;i++)
|
||||
{
|
||||
int sizeZ = !ci.m_useConcaveMesh&&k==0? 50 : ci.arraySizeZ;
|
||||
int startZ = (!ci.m_useConcaveMesh)&&k==0? -20 : 0;
|
||||
float gapZ = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapZ;
|
||||
for(int j = 0;j<sizeZ;j++)
|
||||
{
|
||||
//b3CollisionShape* shape = k==0? boxShape : colShape;
|
||||
|
||||
b3CollisionShape* shape = colShape;
|
||||
|
||||
|
||||
b3Scalar mass = 1;
|
||||
if (!ci.m_useConcaveMesh && k==0)
|
||||
mass = k==0? 0.f : 1.f;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
bool isDynamic = (mass != 0.f);
|
||||
|
||||
b3Vector3 localInertia(0,0,0);
|
||||
if (isDynamic)
|
||||
shape->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
startTransform.setOrigin(SCALING*b3Vector3(
|
||||
b3Scalar(startX+gapX*i + start_x),
|
||||
b3Scalar(ci.gapY*(k+0.5) + start_y),
|
||||
b3Scalar(startZ+gapZ*j + start_z)));
|
||||
|
||||
|
||||
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
b3DefaultMotionState* myMotionState = new b3DefaultMotionState(startTransform);
|
||||
b3RigidBody::b3RigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
|
||||
b3RigidBody* body = new b3RigidBody(rbInfo);
|
||||
|
||||
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GpuDemo::initPhysics(const ConstructionInfo& ci)
|
||||
{
|
||||
|
||||
// setTexturing(true);
|
||||
//setShadows(false);
|
||||
|
||||
// setCameraDistance(b3Scalar(SCALING*250.));
|
||||
|
||||
///collision configuration contains default setup for memory, collision setup
|
||||
if (ci.useOpenCL)
|
||||
{
|
||||
m_dynamicsWorld = new b3GpuDynamicsWorld(ci.preferredOpenCLPlatformIndex,ci.preferredOpenCLDeviceIndex);
|
||||
} else
|
||||
{
|
||||
m_dynamicsWorld = new b3CpuDynamicsWorld();
|
||||
}
|
||||
|
||||
|
||||
m_dynamicsWorld->setGravity(b3Vector3(0,-10,0));
|
||||
|
||||
///create a few basic rigid bodies
|
||||
|
||||
setupScene(ci);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*void GpuDemo::clientResetScene()
|
||||
{
|
||||
exitPhysics();
|
||||
initPhysics();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void GpuDemo::exitPhysics()
|
||||
{
|
||||
|
||||
//cleanup in the reverse order of creation/initialization
|
||||
|
||||
//remove the rigidbodies from the dynamics world and delete them
|
||||
int i;
|
||||
if (m_dynamicsWorld)
|
||||
{
|
||||
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
||||
{
|
||||
b3CollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
|
||||
b3RigidBody* body = b3RigidBody::upcast(obj);
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
delete body->getMotionState();
|
||||
}
|
||||
m_dynamicsWorld->removeCollisionObject( obj );
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
//delete collision shapes
|
||||
for (int j=0;j<m_collisionShapes.size();j++)
|
||||
{
|
||||
b3CollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
m_collisionShapes.clear();
|
||||
|
||||
delete m_dynamicsWorld;
|
||||
m_dynamicsWorld=0;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 GPU_DEMO_H
|
||||
#define GPU_DEMO_H
|
||||
|
||||
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
|
||||
|
||||
class b3BroadphaseInterface;
|
||||
class b3CollisionShape;
|
||||
class b3OverlappingPairCache;
|
||||
class b3CollisionDispatcher;
|
||||
class b3ConstraintSolver;
|
||||
struct b3CollisionAlgorithmCreateFunc;
|
||||
class b3DefaultCollisionConfiguration;
|
||||
class b3DynamicsWorld;
|
||||
class GLInstancingRenderer;
|
||||
|
||||
///GpuDemo is good starting point for learning the code base and porting.
|
||||
|
||||
|
||||
|
||||
class GpuDemo
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
b3DynamicsWorld* m_dynamicsWorld;
|
||||
|
||||
//keep the collision shapes, for deletion/cleanup
|
||||
b3AlignedObjectArray<b3CollisionShape*> m_collisionShapes;
|
||||
|
||||
float getDeltaTimeInSeconds()
|
||||
{
|
||||
return 1./60.f;
|
||||
}
|
||||
public:
|
||||
|
||||
typedef class GpuDemo* (CreateFunc)();
|
||||
|
||||
struct ConstructionInfo
|
||||
{
|
||||
bool useOpenCL;
|
||||
int preferredOpenCLPlatformIndex;
|
||||
int preferredOpenCLDeviceIndex;
|
||||
int arraySizeX;
|
||||
int arraySizeY;
|
||||
int arraySizeZ;
|
||||
bool m_useConcaveMesh;
|
||||
float gapX;
|
||||
float gapY;
|
||||
float gapZ;
|
||||
GLInstancingRenderer* m_instancingRenderer;
|
||||
ConstructionInfo()
|
||||
:useOpenCL(false),//true),
|
||||
preferredOpenCLPlatformIndex(-1),
|
||||
preferredOpenCLDeviceIndex(-1),
|
||||
arraySizeX(10),
|
||||
arraySizeY(10 ),
|
||||
arraySizeZ(10),
|
||||
m_useConcaveMesh(false),
|
||||
gapX(4.3),
|
||||
gapY(4.0),
|
||||
gapZ(4.3),
|
||||
m_instancingRenderer(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void setupScene(const ConstructionInfo& ci)=0;
|
||||
public:
|
||||
|
||||
GpuDemo()
|
||||
{
|
||||
m_dynamicsWorld=0;
|
||||
|
||||
}
|
||||
virtual ~GpuDemo()
|
||||
{
|
||||
exitPhysics();
|
||||
}
|
||||
virtual void initPhysics(const ConstructionInfo& ci);
|
||||
|
||||
virtual const char* getName()=0;
|
||||
|
||||
virtual void exitPhysics();
|
||||
|
||||
virtual const b3DynamicsWorld* getDynamicsWorld() const
|
||||
{
|
||||
return m_dynamicsWorld;
|
||||
}
|
||||
|
||||
virtual void renderScene()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void clientMoveAndDisplay();
|
||||
|
||||
|
||||
//virtual void clientResetScene();
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
class GpuCompoundDemo : public GpuDemo
|
||||
{
|
||||
public:
|
||||
virtual void setupScene(const ConstructionInfo& ci);
|
||||
virtual const char* getName()
|
||||
{
|
||||
return "GpuCompoundDemo";
|
||||
}
|
||||
static GpuDemo* CreateFunc()
|
||||
{
|
||||
GpuDemo* demo = new GpuCompoundDemo;
|
||||
return demo;
|
||||
}
|
||||
};
|
||||
|
||||
class GpuBoxDemo : public GpuDemo
|
||||
{
|
||||
public:
|
||||
virtual void setupScene(const ConstructionInfo& ci);
|
||||
virtual const char* getName()
|
||||
{
|
||||
return "GpuBoxDemo";
|
||||
}
|
||||
static GpuDemo* CreateFunc()
|
||||
{
|
||||
GpuDemo* demo = new GpuBoxDemo;
|
||||
return demo;
|
||||
}
|
||||
};
|
||||
|
||||
class EmptyDemo : public GpuDemo
|
||||
{
|
||||
public:
|
||||
virtual void setupScene(const ConstructionInfo& ci);
|
||||
virtual const char* getName()
|
||||
{
|
||||
return "EmptyDemo";
|
||||
}
|
||||
static GpuDemo* CreateFunc()
|
||||
{
|
||||
GpuDemo* demo = new EmptyDemo;
|
||||
return demo;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class SpheresDemo : public GpuDemo
|
||||
{
|
||||
public:
|
||||
virtual void setupScene(const ConstructionInfo& ci);
|
||||
virtual const char* getName()
|
||||
{
|
||||
return "SpheresDemo";
|
||||
}
|
||||
static GpuDemo* CreateFunc()
|
||||
{
|
||||
GpuDemo* demo = new SpheresDemo;
|
||||
return demo;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //GPU_DEMO_H
|
||||
@@ -1,678 +0,0 @@
|
||||
|
||||
#include "OpenGL3CoreRenderer.h"
|
||||
#include "OpenGLWindow/GLInstancingRenderer.h"
|
||||
#include "OpenGLWindow/ShapeData.h"
|
||||
//#include "BulletDynamics/Dynamics/b3DiscreteDynamicsWorld.h"
|
||||
//#include "BulletCollision/CollisionDispatch/b3CollisionObject.h"
|
||||
#include "Bullet3Common/b3Quickprof.h"
|
||||
|
||||
/*#include "BulletCollision/CollisionShapes/b3BvhTriangleMeshShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3ConvexPolyhedron.h"
|
||||
#include "BulletCollision/CollisionShapes/b3ConvexHullShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3CollisionShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3BoxShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3CompoundShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3SphereShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3StaticPlaneShape.h"
|
||||
|
||||
#include "../../rendering/WavefrontObjLoader/objLoader.h"
|
||||
*/
|
||||
|
||||
OpenGL3CoreRenderer::OpenGL3CoreRenderer()
|
||||
{
|
||||
int maxNumObjects = 2*1024*1024;
|
||||
m_instancingRenderer = new GLInstancingRenderer(maxNumObjects);
|
||||
m_instancingRenderer->setCameraDistance(150);
|
||||
}
|
||||
OpenGL3CoreRenderer::~OpenGL3CoreRenderer()
|
||||
{
|
||||
delete m_instancingRenderer;
|
||||
}
|
||||
|
||||
void OpenGL3CoreRenderer::init()
|
||||
{
|
||||
m_instancingRenderer->InitShaders();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OpenGL3CoreRenderer::reshape(int w, int h)
|
||||
{
|
||||
m_instancingRenderer->resize(w,h);
|
||||
}
|
||||
void OpenGL3CoreRenderer::keyboardCallback(unsigned char key)
|
||||
{
|
||||
}
|
||||
|
||||
struct GraphicsVertex
|
||||
{
|
||||
float xyzw[4];
|
||||
float normal[3];
|
||||
float uv[2];
|
||||
};
|
||||
struct GraphicsShape
|
||||
{
|
||||
const float* m_vertices;
|
||||
int m_numvertices;
|
||||
const int* m_indices;
|
||||
int m_numIndices;
|
||||
float m_scaling[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
GraphicsShape* createGraphicsShapeFromConvexHull(const b3ConvexPolyhedron* utilPtr)
|
||||
{
|
||||
|
||||
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
|
||||
{
|
||||
int numVertices = utilPtr->m_vertices.size();
|
||||
int numIndices = 0;
|
||||
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
|
||||
for (int f=0;f<utilPtr->m_faces.size();f++)
|
||||
{
|
||||
const b3Face& face = utilPtr->m_faces[f];
|
||||
b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
|
||||
if (face.m_indices.size()>2)
|
||||
{
|
||||
|
||||
GraphicsVertex vtx;
|
||||
const b3Vector3& orgVertex = utilPtr->m_vertices[face.m_indices[0]];
|
||||
vtx.xyzw[0] = orgVertex[0];vtx.xyzw[1] = orgVertex[1];vtx.xyzw[2] = orgVertex[2];vtx.xyzw[3] = 0.f;
|
||||
vtx.normal[0] = normal[0];vtx.normal[1] = normal[1];vtx.normal[2] = normal[2];
|
||||
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f;
|
||||
int newvtxindex0 = vertices->size();
|
||||
vertices->push_back(vtx);
|
||||
|
||||
for (int j=1;j<face.m_indices.size()-1;j++)
|
||||
{
|
||||
indicesPtr->push_back(newvtxindex0);
|
||||
{
|
||||
GraphicsVertex vtx;
|
||||
const b3Vector3& orgVertex = utilPtr->m_vertices[face.m_indices[j]];
|
||||
vtx.xyzw[0] = orgVertex[0];vtx.xyzw[1] = orgVertex[1];vtx.xyzw[2] = orgVertex[2];vtx.xyzw[3] = 0.f;
|
||||
vtx.normal[0] = normal[0];vtx.normal[1] = normal[1];vtx.normal[2] = normal[2];
|
||||
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f;
|
||||
int newvtxindexj = vertices->size();
|
||||
vertices->push_back(vtx);
|
||||
indicesPtr->push_back(newvtxindexj);
|
||||
}
|
||||
|
||||
{
|
||||
GraphicsVertex vtx;
|
||||
const b3Vector3& orgVertex = utilPtr->m_vertices[face.m_indices[j+1]];
|
||||
vtx.xyzw[0] = orgVertex[0];vtx.xyzw[1] = orgVertex[1];vtx.xyzw[2] = orgVertex[2];vtx.xyzw[3] = 0.f;
|
||||
vtx.normal[0] = normal[0];vtx.normal[1] = normal[1];vtx.normal[2] = normal[2];
|
||||
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f;
|
||||
int newvtxindexj1 = vertices->size();
|
||||
vertices->push_back(vtx);
|
||||
indicesPtr->push_back(newvtxindexj1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphicsShape* gfxShape = new GraphicsShape;
|
||||
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
|
||||
gfxShape->m_numvertices = vertices->size();
|
||||
gfxShape->m_indices = &indicesPtr->at(0);
|
||||
gfxShape->m_numIndices = indicesPtr->size();
|
||||
for (int i=0;i<4;i++)
|
||||
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
|
||||
return gfxShape;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsShape* createGraphicsShapeFromCompoundShape(b3CompoundShape* compound)
|
||||
{
|
||||
GraphicsShape* gfxShape = new GraphicsShape();
|
||||
b3AlignedObjectArray<GraphicsVertex>* vertexArray = new b3AlignedObjectArray<GraphicsVertex>;
|
||||
b3AlignedObjectArray<int>* indexArray = new b3AlignedObjectArray<int>;
|
||||
|
||||
|
||||
|
||||
//create a graphics shape for each child, combine them into a single graphics shape using their child transforms
|
||||
for (int i=0;i<compound->getNumChildShapes();i++)
|
||||
{
|
||||
b3Assert(compound->getChildShape(i)->isPolyhedral());
|
||||
if (compound->getChildShape(i)->isPolyhedral())
|
||||
{
|
||||
b3PolyhedralConvexShape* convexHull = (b3PolyhedralConvexShape*) compound->getChildShape(i);
|
||||
b3Transform tr = compound->getChildTransform(i);
|
||||
|
||||
const b3ConvexPolyhedron* polyhedron = convexHull->getConvexPolyhedron();
|
||||
GraphicsShape* childGfxShape = createGraphicsShapeFromConvexHull(polyhedron);
|
||||
int baseIndex = vertexArray->size();
|
||||
|
||||
for (int j=0;j<childGfxShape->m_numIndices;j++)
|
||||
indexArray->push_back(childGfxShape->m_indices[j]+baseIndex);
|
||||
|
||||
GraphicsVertex* orgVerts = (GraphicsVertex*)childGfxShape->m_vertices;
|
||||
|
||||
for (int j=0;j<childGfxShape->m_numvertices;j++)
|
||||
{
|
||||
GraphicsVertex vtx;
|
||||
b3Vector3 pos(orgVerts[j].xyzw[0],orgVerts[j].xyzw[1],orgVerts[j].xyzw[2]);
|
||||
pos = tr*pos;
|
||||
vtx.xyzw[0] = childGfxShape->m_scaling[0]*pos.getX();
|
||||
vtx.xyzw[1] = childGfxShape->m_scaling[1]*pos.getY();
|
||||
vtx.xyzw[2] = childGfxShape->m_scaling[2]*pos.getZ();
|
||||
vtx.xyzw[3] = 10.f;
|
||||
|
||||
vtx.uv[0] = 0.5f;
|
||||
vtx.uv[1] = 0.5f;
|
||||
|
||||
b3Vector3 normal(orgVerts[j].normal[0],orgVerts[j].normal[1],orgVerts[j].normal[2]);
|
||||
normal = tr.getBasis()*normal;
|
||||
vtx.normal[0] = normal.getX();
|
||||
vtx.normal[1] = normal.getY();
|
||||
vtx.normal[2] = normal.getZ();
|
||||
vertexArray->push_back(vtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b3PolyhedralConvexShape* convexHull = (b3PolyhedralConvexShape*) compound->getChildShape(0);
|
||||
const b3ConvexPolyhedron* polyhedron = convexHull->getConvexPolyhedron();
|
||||
GraphicsShape* childGfxShape = createGraphicsShapeFromConvexHull(polyhedron);
|
||||
|
||||
gfxShape->m_indices = &indexArray->at(0);
|
||||
gfxShape->m_numIndices = indexArray->size();
|
||||
gfxShape->m_vertices = &vertexArray->at(0).xyzw[0];
|
||||
gfxShape->m_numvertices = vertexArray->size();
|
||||
gfxShape->m_scaling[0] = 1;
|
||||
gfxShape->m_scaling[1] = 1;
|
||||
gfxShape->m_scaling[2] = 1;
|
||||
gfxShape->m_scaling[3] = 1;
|
||||
|
||||
return gfxShape;
|
||||
}
|
||||
|
||||
GraphicsShape* createGraphicsShapeFromConcaveMesh(const b3BvhTriangleMeshShape* trimesh)
|
||||
{
|
||||
|
||||
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
|
||||
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
|
||||
|
||||
const b3StridingMeshInterface* meshInterface = trimesh->getMeshInterface();
|
||||
|
||||
b3Vector3 trimeshScaling(1,1,1);
|
||||
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
|
||||
{
|
||||
|
||||
const unsigned char *vertexbase = 0;
|
||||
int numverts = 0;
|
||||
PHY_ScalarType type = PHY_INTEGER;
|
||||
int stride = 0;
|
||||
const unsigned char *indexbase = 0;
|
||||
int indexstride = 0;
|
||||
int numfaces = 0;
|
||||
PHY_ScalarType indicestype = PHY_INTEGER;
|
||||
//PHY_ScalarType indexType=0;
|
||||
|
||||
b3Vector3 triangleVerts[3];
|
||||
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
|
||||
b3Vector3 aabbMin,aabbMax;
|
||||
|
||||
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
|
||||
{
|
||||
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
|
||||
|
||||
for (int j=2;j>=0;j--)
|
||||
{
|
||||
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = b3Vector3(
|
||||
graphicsbase[0]*trimeshScaling.getX(),
|
||||
graphicsbase[1]*trimeshScaling.getY(),
|
||||
graphicsbase[2]*trimeshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = b3Vector3( b3Scalar(graphicsbase[0]*trimeshScaling.getX()),
|
||||
b3Scalar(graphicsbase[1]*trimeshScaling.getY()),
|
||||
b3Scalar(graphicsbase[2]*trimeshScaling.getZ()));
|
||||
}
|
||||
}
|
||||
b3Vector3 normal = (triangleVerts[2]-triangleVerts[0]).cross(triangleVerts[1]-triangleVerts[0]);
|
||||
normal.normalize();
|
||||
|
||||
GraphicsVertex vtx0,vtx1,vtx2;
|
||||
vtx0.xyzw[0] = triangleVerts[0].getX();
|
||||
vtx0.xyzw[1] = triangleVerts[0].getY();
|
||||
vtx0.xyzw[2] = triangleVerts[0].getZ();
|
||||
vtx0.xyzw[3] = 0;
|
||||
vtx0.uv[0] = 0.5f;
|
||||
vtx0.uv[1] = 0.5f;
|
||||
vtx0.normal[0] = normal[0];
|
||||
vtx0.normal[1] = normal[1];
|
||||
vtx0.normal[2] = normal[2];
|
||||
|
||||
vtx1.xyzw[0] = triangleVerts[1].getX();
|
||||
vtx1.xyzw[1] = triangleVerts[1].getY();
|
||||
vtx1.xyzw[2] = triangleVerts[1].getZ();
|
||||
vtx1.xyzw[3] = 0;
|
||||
vtx1.uv[0] = 0.5f;
|
||||
vtx1.uv[1] = 0.5f;
|
||||
vtx1.normal[0] = normal[0];
|
||||
vtx1.normal[1] = normal[1];
|
||||
vtx1.normal[2] = normal[2];
|
||||
|
||||
vtx2.xyzw[0] = triangleVerts[2].getX();
|
||||
vtx2.xyzw[1] = triangleVerts[2].getY();
|
||||
vtx2.xyzw[2] = triangleVerts[2].getZ();
|
||||
vtx2.xyzw[3] = 0;
|
||||
vtx2.uv[0] = 0.5f;
|
||||
vtx2.uv[1] = 0.5f;
|
||||
vtx2.normal[0] = normal[0];
|
||||
vtx2.normal[1] = normal[1];
|
||||
vtx2.normal[2] = normal[2];
|
||||
|
||||
// triangleVerts[1]
|
||||
// triangleVerts[1]
|
||||
// triangleVerts[2]
|
||||
vertices->push_back(vtx0);
|
||||
vertices->push_back(vtx1);
|
||||
vertices->push_back(vtx2);
|
||||
indicesPtr->push_back(indicesPtr->size());
|
||||
indicesPtr->push_back(indicesPtr->size());
|
||||
indicesPtr->push_back(indicesPtr->size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphicsShape* gfxShape = new GraphicsShape;
|
||||
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
|
||||
gfxShape->m_numvertices = vertices->size();
|
||||
gfxShape->m_indices = &indicesPtr->at(0);
|
||||
gfxShape->m_numIndices = indicesPtr->size();
|
||||
for (int i=0;i<4;i++)
|
||||
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
|
||||
return gfxShape;
|
||||
}
|
||||
|
||||
|
||||
GraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj)
|
||||
{
|
||||
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
|
||||
{
|
||||
// int numVertices = obj->vertexCount;
|
||||
// int numIndices = 0;
|
||||
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
|
||||
/*
|
||||
for (int v=0;v<obj->vertexCount;v++)
|
||||
{
|
||||
vtx.xyzw[0] = obj->vertexList[v]->e[0];
|
||||
vtx.xyzw[1] = obj->vertexList[v]->e[1];
|
||||
vtx.xyzw[2] = obj->vertexList[v]->e[2];
|
||||
b3Vector3 n(vtx.xyzw[0],vtx.xyzw[1],vtx.xyzw[2]);
|
||||
if (n.length2()>B3_EPSILON)
|
||||
{
|
||||
n.normalize();
|
||||
vtx.normal[0] = n[0];
|
||||
vtx.normal[1] = n[1];
|
||||
vtx.normal[2] = n[2];
|
||||
|
||||
} else
|
||||
{
|
||||
vtx.normal[0] = 0; //todo
|
||||
vtx.normal[1] = 1;
|
||||
vtx.normal[2] = 0;
|
||||
}
|
||||
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f; //todo
|
||||
vertices->push_back(vtx);
|
||||
}
|
||||
*/
|
||||
|
||||
for (int f=0;f<obj->faceCount;f++)
|
||||
{
|
||||
obj_face* face = obj->faceList[f];
|
||||
//b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
|
||||
if (face->vertex_count>=3)
|
||||
{
|
||||
b3Vector3 normal(0,1,0);
|
||||
int vtxBaseIndex = vertices->size();
|
||||
|
||||
if (face->vertex_count<=4)
|
||||
{
|
||||
indicesPtr->push_back(vtxBaseIndex);
|
||||
indicesPtr->push_back(vtxBaseIndex+1);
|
||||
indicesPtr->push_back(vtxBaseIndex+2);
|
||||
|
||||
GraphicsVertex vtx0;
|
||||
vtx0.xyzw[0] = obj->vertexList[face->vertex_index[0]]->e[0];
|
||||
vtx0.xyzw[1] = obj->vertexList[face->vertex_index[0]]->e[1];
|
||||
vtx0.xyzw[2] = obj->vertexList[face->vertex_index[0]]->e[2];
|
||||
vtx0.uv[0] = obj->textureList[face->vertex_index[0]]->e[0];
|
||||
vtx0.uv[1] = obj->textureList[face->vertex_index[0]]->e[1];
|
||||
|
||||
GraphicsVertex vtx1;
|
||||
vtx1.xyzw[0] = obj->vertexList[face->vertex_index[1]]->e[0];
|
||||
vtx1.xyzw[1] = obj->vertexList[face->vertex_index[1]]->e[1];
|
||||
vtx1.xyzw[2] = obj->vertexList[face->vertex_index[1]]->e[2];
|
||||
vtx1.uv[0] = obj->textureList[face->vertex_index[1]]->e[0];
|
||||
vtx1.uv[1] = obj->textureList[face->vertex_index[1]]->e[1];
|
||||
|
||||
GraphicsVertex vtx2;
|
||||
vtx2.xyzw[0] = obj->vertexList[face->vertex_index[2]]->e[0];
|
||||
vtx2.xyzw[1] = obj->vertexList[face->vertex_index[2]]->e[1];
|
||||
vtx2.xyzw[2] = obj->vertexList[face->vertex_index[2]]->e[2];
|
||||
vtx2.uv[0] = obj->textureList[face->vertex_index[2]]->e[0];
|
||||
vtx2.uv[1] = obj->textureList[face->vertex_index[2]]->e[1];
|
||||
|
||||
|
||||
b3Vector3 v0(vtx0.xyzw[0],vtx0.xyzw[1],vtx0.xyzw[2]);
|
||||
b3Vector3 v1(vtx1.xyzw[0],vtx1.xyzw[1],vtx1.xyzw[2]);
|
||||
b3Vector3 v2(vtx2.xyzw[0],vtx2.xyzw[1],vtx2.xyzw[2]);
|
||||
|
||||
normal = (v1-v0).cross(v2-v0);
|
||||
normal.normalize();
|
||||
vtx0.normal[0] = normal[0];
|
||||
vtx0.normal[1] = normal[1];
|
||||
vtx0.normal[2] = normal[2];
|
||||
vtx1.normal[0] = normal[0];
|
||||
vtx1.normal[1] = normal[1];
|
||||
vtx1.normal[2] = normal[2];
|
||||
vtx2.normal[0] = normal[0];
|
||||
vtx2.normal[1] = normal[1];
|
||||
vtx2.normal[2] = normal[2];
|
||||
vertices->push_back(vtx0);
|
||||
vertices->push_back(vtx1);
|
||||
vertices->push_back(vtx2);
|
||||
}
|
||||
if (face->vertex_count==4)
|
||||
{
|
||||
|
||||
indicesPtr->push_back(vtxBaseIndex);
|
||||
indicesPtr->push_back(vtxBaseIndex+1);
|
||||
indicesPtr->push_back(vtxBaseIndex+2);
|
||||
indicesPtr->push_back(vtxBaseIndex+3);
|
||||
//
|
||||
GraphicsVertex vtx3;
|
||||
vtx3.xyzw[0] = obj->vertexList[face->vertex_index[3]]->e[0];
|
||||
vtx3.xyzw[1] = obj->vertexList[face->vertex_index[3]]->e[1];
|
||||
vtx3.xyzw[2] = obj->vertexList[face->vertex_index[3]]->e[2];
|
||||
vtx3.uv[0] = 0.5;
|
||||
vtx3.uv[1] = 0.5;
|
||||
|
||||
vtx3.normal[0] = normal[0];
|
||||
vtx3.normal[1] = normal[1];
|
||||
vtx3.normal[2] = normal[2];
|
||||
|
||||
vertices->push_back(vtx3);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphicsShape* gfxShape = new GraphicsShape;
|
||||
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
|
||||
gfxShape->m_numvertices = vertices->size();
|
||||
gfxShape->m_indices = &indicesPtr->at(0);
|
||||
gfxShape->m_numIndices = indicesPtr->size();
|
||||
for (int i=0;i<4;i++)
|
||||
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
|
||||
return gfxShape;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//very incomplete conversion from physics to graphics
|
||||
void graphics_from_physics(GLInstancingRenderer& renderer, bool syncTransformsOnly, int numObjects, b3CollisionObject** colObjArray)
|
||||
{
|
||||
///@todo: we need to sort the objects based on collision shape type, so we can share instances
|
||||
B3_PROFILE("graphics_from_physics");
|
||||
|
||||
int strideInBytes = sizeof(float)*9;
|
||||
|
||||
int prevGraphicsShapeIndex = -1;
|
||||
b3CollisionShape* prevShape = 0;
|
||||
|
||||
|
||||
int numColObj = numObjects;
|
||||
int curGraphicsIndex = 0;
|
||||
|
||||
float localScaling[4] = {1,1,1,1};
|
||||
|
||||
|
||||
for (int i=0;i<numColObj;i++)
|
||||
{
|
||||
b3CollisionObject* colObj = colObjArray[i];
|
||||
|
||||
b3Vector3 pos = colObj->getWorldTransform().getOrigin();
|
||||
b3Quaternion orn = colObj->getWorldTransform().getRotation();
|
||||
|
||||
float position[4] = {pos.getX(),pos.getY(),pos.getZ(),0.f};
|
||||
float orientation[4] = {orn.getX(),orn.getY(),orn.getZ(),orn.getW()};
|
||||
float color[4] = {0,0,0,1};
|
||||
b3Vector3 localScaling = colObj->getCollisionShape()->getLocalScaling();
|
||||
|
||||
|
||||
if (colObj->isStaticOrKinematicObject())
|
||||
{
|
||||
color[0]=1.f;
|
||||
}else
|
||||
{
|
||||
color[1]=1.f;
|
||||
}
|
||||
|
||||
if (!syncTransformsOnly)
|
||||
{
|
||||
|
||||
if (prevShape != colObj->getCollisionShape())
|
||||
{
|
||||
if (colObj->getCollisionShape()->isPolyhedral())
|
||||
{
|
||||
b3PolyhedralConvexShape* polyShape = (b3PolyhedralConvexShape*)colObj->getCollisionShape();
|
||||
const b3ConvexPolyhedron* pol = polyShape->getConvexPolyhedron();
|
||||
GraphicsShape* gfxShape = createGraphicsShapeFromConvexHull(pol);
|
||||
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
|
||||
prevShape = colObj->getCollisionShape();
|
||||
const b3Vector3& scaling = prevShape->getLocalScaling();
|
||||
localScaling[0] = scaling.getX();localScaling[1] = scaling.getY();localScaling[2] = scaling.getZ();
|
||||
} else
|
||||
{
|
||||
if (colObj->getCollisionShape()->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
b3BvhTriangleMeshShape* trimesh = (b3BvhTriangleMeshShape*) colObj->getCollisionShape();
|
||||
GraphicsShape* gfxShape = createGraphicsShapeFromConcaveMesh(trimesh);
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
|
||||
prevShape = colObj->getCollisionShape();
|
||||
const b3Vector3& scaling = prevShape->getLocalScaling();
|
||||
localScaling[0] = scaling.getX();localScaling[1] = scaling.getY();localScaling[2] = scaling.getZ();
|
||||
} else
|
||||
{
|
||||
if (colObj->getCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
|
||||
{
|
||||
b3CompoundShape* compound = (b3CompoundShape*) colObj->getCollisionShape();
|
||||
GraphicsShape* gfxShape = createGraphicsShapeFromCompoundShape(compound);
|
||||
if (gfxShape)
|
||||
{
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
|
||||
prevShape = colObj->getCollisionShape();
|
||||
const b3Vector3& scaling = prevShape->getLocalScaling();
|
||||
localScaling[0] = scaling.getX();localScaling[1] = scaling.getY();localScaling[2] = scaling.getZ();
|
||||
} else
|
||||
{
|
||||
prevGraphicsShapeIndex = -1;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (colObj->getCollisionShape()->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
|
||||
{
|
||||
b3SphereShape* sphere = (b3SphereShape*) colObj->getCollisionShape();
|
||||
b3Scalar radius = sphere->getRadius();
|
||||
|
||||
//b3ConvexHullShape* spherePoly = new b3ConvexHullShape(
|
||||
//const b3ConvexPolyhedron* pol = polyShape->getConvexPolyhedron();
|
||||
|
||||
/*
|
||||
objLoader loader;
|
||||
|
||||
int result = loader.load("../../bin/wavefront/sphere_low.obj");
|
||||
|
||||
|
||||
GraphicsShape* gfxShape = createGraphicsShapeFromWavefrontObj(&loader);
|
||||
|
||||
|
||||
int vertexStrideInBytes = 9*sizeof(float);
|
||||
|
||||
|
||||
printf("vertices (%d):\n",gfxShape->m_numvertices);
|
||||
for (int i=0;i<gfxShape->m_numvertices;i++)
|
||||
{
|
||||
gfxShape->m_vertices[i*9+4] = gfxShape->m_vertices[i*9];
|
||||
gfxShape->m_vertices[i*9+5] = gfxShape->m_vertices[i*9+1];
|
||||
gfxShape->m_vertices[i*9+6] = gfxShape->m_vertices[i*9+2];
|
||||
|
||||
printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,\n",
|
||||
gfxShape->m_vertices[i*9],
|
||||
gfxShape->m_vertices[i*9+1],
|
||||
gfxShape->m_vertices[i*9+2],
|
||||
0.f,//gfxShape->m_vertices[i*9+3],
|
||||
//gfxShape->m_vertices[i*9+4],//face normals
|
||||
//gfxShape->m_vertices[i*9+5],
|
||||
//gfxShape->m_vertices[i*9+6],
|
||||
|
||||
gfxShape->m_vertices[i*9+0],
|
||||
gfxShape->m_vertices[i*9+1],
|
||||
gfxShape->m_vertices[i*9+2],
|
||||
|
||||
gfxShape->m_vertices[i*9+7],
|
||||
gfxShape->m_vertices[i*9+8]);
|
||||
}
|
||||
printf("indices (%d):\n",gfxShape->m_numIndices);
|
||||
for (int i=0;i<gfxShape->m_numIndices/3;i++)
|
||||
{
|
||||
printf("%d,%d,%d,\n",gfxShape->m_indices[i*3],
|
||||
gfxShape->m_indices[i*3+1],
|
||||
gfxShape->m_indices[i*3+2]);
|
||||
}
|
||||
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&gfxShape->m_vertices[0],gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
|
||||
*/
|
||||
|
||||
if (radius>=100)
|
||||
{
|
||||
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
|
||||
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
|
||||
} else
|
||||
{
|
||||
bool usePointSprites = true;
|
||||
if (usePointSprites)
|
||||
{
|
||||
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
|
||||
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS);
|
||||
} else
|
||||
{
|
||||
if (radius>=10)
|
||||
{
|
||||
int numVertices = sizeof(medium_sphere_vertices)/strideInBytes;
|
||||
int numIndices = sizeof(medium_sphere_indices)/sizeof(int);
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&medium_sphere_vertices[0],numVertices,medium_sphere_indices,numIndices);
|
||||
} else
|
||||
{
|
||||
int numVertices = sizeof(low_sphere_vertices)/strideInBytes;
|
||||
int numIndices = sizeof(low_sphere_indices)/sizeof(int);
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
|
||||
}
|
||||
}
|
||||
}
|
||||
prevShape = sphere;
|
||||
const b3Vector3& scaling = prevShape->getLocalScaling();
|
||||
//assume uniform scaling, using X component
|
||||
float sphereScale = radius*scaling.getX();
|
||||
localScaling[0] = sphereScale;
|
||||
localScaling[1] = sphereScale;
|
||||
localScaling[2] = sphereScale;
|
||||
} else
|
||||
{
|
||||
if (colObj->getCollisionShape()->getShapeType()==STATIC_PLANE_PROXYTYPE)
|
||||
{
|
||||
b3StaticPlaneShape* plane= (b3StaticPlaneShape*) colObj->getCollisionShape();
|
||||
prevShape = colObj->getCollisionShape();
|
||||
|
||||
//plane->getPlaneNormal()
|
||||
//plane->getPlaneConstant()
|
||||
if (1)
|
||||
{
|
||||
int numVertices = sizeof(quad_vertices)/strideInBytes;
|
||||
int numIndices = sizeof(quad_indices)/sizeof(int);
|
||||
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&quad_vertices[0],numVertices,quad_indices,numIndices);
|
||||
} else
|
||||
{
|
||||
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
|
||||
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
|
||||
prevGraphicsShapeIndex = renderer.registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
|
||||
}
|
||||
|
||||
localScaling[0] = 100;
|
||||
localScaling[1] = 1;
|
||||
localScaling[2] = 100;
|
||||
} else
|
||||
{
|
||||
printf("Error: unsupported collision shape type in %s %d\n", __FILE__, __LINE__);
|
||||
prevGraphicsShapeIndex = -1;
|
||||
b3Assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
if (!syncTransformsOnly)
|
||||
{
|
||||
if (prevShape && prevGraphicsShapeIndex>=0)
|
||||
{
|
||||
|
||||
renderer.registerGraphicsInstance(prevGraphicsShapeIndex,position,orientation,color,localScaling);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.writeSingleInstanceTransformToCPU(position,orientation,curGraphicsIndex);
|
||||
|
||||
}
|
||||
curGraphicsIndex++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OpenGL3CoreRenderer::renderPhysicsWorld(int numObjects, b3CollisionObject** colObjArray, bool syncOnly)
|
||||
{
|
||||
//sync changes from physics world to render world
|
||||
//for now, we don't deal with adding/removing objects to the world during the simulation, to keep the rendererer simpler
|
||||
|
||||
|
||||
m_instancingRenderer->writeTransforms();
|
||||
|
||||
graphics_from_physics(*m_instancingRenderer,syncOnly,numObjects, colObjArray);
|
||||
|
||||
|
||||
//render
|
||||
|
||||
m_instancingRenderer->RenderScene();
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef OPENGL3_CORE_RENDERER_H
|
||||
#define OPENGL3_CORE_RENDERER_H
|
||||
|
||||
class b3CollisionObject;
|
||||
class GLInstancingRenderer;
|
||||
|
||||
class OpenGL3CoreRenderer
|
||||
{
|
||||
|
||||
GLInstancingRenderer* m_instancingRenderer;
|
||||
public:
|
||||
OpenGL3CoreRenderer();
|
||||
virtual ~OpenGL3CoreRenderer();
|
||||
void init();
|
||||
void reshape(int w, int h);
|
||||
void keyboardCallback(unsigned char key);
|
||||
void renderPhysicsWorld(int numObjects, b3CollisionObject** colObjArray, bool syncOnly);
|
||||
|
||||
GLInstancingRenderer* getInstancingRenderer()
|
||||
{
|
||||
return m_instancingRenderer;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //OPENGL3_CORE_RENDERER_H
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#include "b3CpuDynamicsWorld.h"
|
||||
|
||||
#include "b3BulletDynamicsCommon.h"
|
||||
|
||||
b3CpuDynamicsWorld::b3CpuDynamicsWorld()
|
||||
:b3DiscreteDynamicsWorld(
|
||||
new b3CollisionDispatcher(new b3DefaultCollisionConfiguration()),
|
||||
new b3DynamicBvhBroadphase(),new b3SequentialImpulseConstraintSolver(),
|
||||
new b3DefaultCollisionConfiguration()//todo: remove this!
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
b3CpuDynamicsWorld::~b3CpuDynamicsWorld()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
#ifndef B3_CPU_DYNAMICS_WORLD_H
|
||||
#define B3_CPU_DYNAMICS_WORLD_H
|
||||
|
||||
class b3DefaultCollisionConfiguration;
|
||||
class b3CollisionDispatcher;
|
||||
struct b3DynamicBvhBroadphase;
|
||||
class b3SequentialImpulseConstraintSolver;
|
||||
|
||||
#include "BulletDynamics/Dynamics/b3DiscreteDynamicsWorld.h"
|
||||
|
||||
class b3CpuDynamicsWorld : public b3DiscreteDynamicsWorld
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
b3CpuDynamicsWorld();
|
||||
|
||||
virtual ~b3CpuDynamicsWorld();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //B3_CPU_DYNAMICS_WORLD_H
|
||||
@@ -1,300 +0,0 @@
|
||||
#include "b3GpuDynamicsWorld.h"
|
||||
#include "BulletDynamics/Dynamics/b3RigidBody.h"
|
||||
|
||||
#include "../../../opencl/gpu_rigidbody_pipeline2/CLPhysicsDemo.h"
|
||||
#include "../../../opencl/gpu_rigidbody_pipeline/b3GpuNarrowPhaseAndSolver.h"
|
||||
#include "BulletCollision/CollisionShapes/b3PolyhedralConvexShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3BvhTriangleMeshShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3CompoundShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3SphereShape.h"
|
||||
#include "BulletCollision/CollisionShapes/b3StaticPlaneShape.h"
|
||||
|
||||
#include "LinearMath/b3Quickprof.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wiNdOws.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
b3GpuDynamicsWorld::b3GpuDynamicsWorld(int preferredOpenCLPlatformIndex,int preferredOpenCLDeviceIndex)
|
||||
:b3DynamicsWorld(0,0,0),
|
||||
m_gravity(0,-10,0),
|
||||
m_once(true)
|
||||
{
|
||||
m_gpuPhysics = new CLPhysicsDemo(512*1024, MAX_CONVEX_BODIES_CL);
|
||||
bool useInterop = false;
|
||||
///platform and device are swapped, todo: fix this and make it consistent
|
||||
m_gpuPhysics->init(preferredOpenCLDeviceIndex,preferredOpenCLPlatformIndex,useInterop);
|
||||
}
|
||||
|
||||
b3GpuDynamicsWorld::~b3GpuDynamicsWorld()
|
||||
{
|
||||
delete m_gpuPhysics;
|
||||
}
|
||||
|
||||
void b3GpuDynamicsWorld::exitOpenCL()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int b3GpuDynamicsWorld::stepSimulation( b3Scalar timeStep,int maxSubSteps, b3Scalar fixedTimeStep)
|
||||
{
|
||||
#ifndef B3_NO_PROFILE
|
||||
// b3ProfileManager::Reset();
|
||||
#endif //B3_NO_PROFILE
|
||||
|
||||
B3_PROFILE("stepSimulation");
|
||||
|
||||
//convert all shapes now, and if any change, reset all (todo)
|
||||
|
||||
if (m_once)
|
||||
{
|
||||
m_once = false;
|
||||
m_gpuPhysics->writeBodiesToGpu();
|
||||
}
|
||||
|
||||
m_gpuPhysics->stepSimulation();
|
||||
|
||||
{
|
||||
{
|
||||
B3_PROFILE("readbackBodiesToCpu");
|
||||
//now copy info back to rigid bodies....
|
||||
m_gpuPhysics->readbackBodiesToCpu();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
B3_PROFILE("scatter transforms into rigidbody (CPU)");
|
||||
for (int i=0;i<this->m_collisionObjects.size();i++)
|
||||
{
|
||||
b3Vector3 pos;
|
||||
b3Quaternion orn;
|
||||
m_gpuPhysics->getObjectTransformFromCpu(&pos[0],&orn[0],i);
|
||||
b3Transform newTrans;
|
||||
newTrans.setOrigin(pos);
|
||||
newTrans.setRotation(orn);
|
||||
this->m_collisionObjects[i]->setWorldTransform(newTrans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef B3_NO_PROFILE
|
||||
//b3ProfileManager::Increment_Frame_Counter();
|
||||
#endif //B3_NO_PROFILE
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void b3GpuDynamicsWorld::setGravity(const b3Vector3& gravity)
|
||||
{
|
||||
}
|
||||
|
||||
int b3GpuDynamicsWorld::findOrRegisterCollisionShape(const b3CollisionShape* colShape)
|
||||
{
|
||||
int index = m_uniqueShapes.findLinearSearch(colShape);
|
||||
if (index==m_uniqueShapes.size())
|
||||
{
|
||||
if (colShape->isPolyhedral())
|
||||
{
|
||||
m_uniqueShapes.push_back(colShape);
|
||||
|
||||
b3PolyhedralConvexShape* convex = (b3PolyhedralConvexShape*)colShape;
|
||||
int numVertices=convex->getNumVertices();
|
||||
|
||||
int strideInBytes=sizeof(b3Vector3);
|
||||
b3AlignedObjectArray<b3Vector3> tmpVertices;
|
||||
tmpVertices.resize(numVertices);
|
||||
for (int i=0;i<numVertices;i++)
|
||||
convex->getVertex(i,tmpVertices[i]);
|
||||
const float scaling[4]={1,1,1,1};
|
||||
bool noHeightField=true;
|
||||
|
||||
int gpuShapeIndex = m_gpuPhysics->registerConvexPolyhedron(&tmpVertices[0].getX(), strideInBytes, numVertices, scaling, noHeightField);
|
||||
m_uniqueShapeMapping.push_back(gpuShapeIndex);
|
||||
} else
|
||||
{
|
||||
if (colShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
m_uniqueShapes.push_back(colShape);
|
||||
|
||||
b3BvhTriangleMeshShape* trimesh = (b3BvhTriangleMeshShape*) colShape;
|
||||
b3StridingMeshInterface* meshInterface = trimesh->getMeshInterface();
|
||||
b3AlignedObjectArray<b3Vector3> vertices;
|
||||
b3AlignedObjectArray<int> indices;
|
||||
|
||||
b3Vector3 trimeshScaling(1,1,1);
|
||||
for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
|
||||
{
|
||||
|
||||
const unsigned char *vertexbase = 0;
|
||||
int numverts = 0;
|
||||
PHY_ScalarType type = PHY_INTEGER;
|
||||
int stride = 0;
|
||||
const unsigned char *indexbase = 0;
|
||||
int indexstride = 0;
|
||||
int numfaces = 0;
|
||||
PHY_ScalarType indicestype = PHY_INTEGER;
|
||||
//PHY_ScalarType indexType=0;
|
||||
|
||||
b3Vector3 triangleVerts[3];
|
||||
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
|
||||
b3Vector3 aabbMin,aabbMax;
|
||||
|
||||
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
|
||||
{
|
||||
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
|
||||
|
||||
for (int j=2;j>=0;j--)
|
||||
{
|
||||
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = b3Vector3(
|
||||
graphicsbase[0]*trimeshScaling.getX(),
|
||||
graphicsbase[1]*trimeshScaling.getY(),
|
||||
graphicsbase[2]*trimeshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = b3Vector3( b3Scalar(graphicsbase[0]*trimeshScaling.getX()),
|
||||
b3Scalar(graphicsbase[1]*trimeshScaling.getY()),
|
||||
b3Scalar(graphicsbase[2]*trimeshScaling.getZ()));
|
||||
}
|
||||
}
|
||||
vertices.push_back(triangleVerts[0]);
|
||||
vertices.push_back(triangleVerts[1]);
|
||||
vertices.push_back(triangleVerts[2]);
|
||||
indices.push_back(indices.size());
|
||||
indices.push_back(indices.size());
|
||||
indices.push_back(indices.size());
|
||||
}
|
||||
}
|
||||
//GraphicsShape* gfxShape = 0;//b3BulletDataExtractor::createGraphicsShapeFromWavefrontObj(objData);
|
||||
|
||||
//GraphicsShape* gfxShape = b3BulletDataExtractor::createGraphicsShapeFromConvexHull(&sUnitSpherePoints[0],MY_UNITSPHERE_POINTS);
|
||||
float meshScaling[4] = {1,1,1,1};
|
||||
//int shapeIndex = renderer.registerShape(gfxShape->m_vertices,gfxShape->m_numvertices,gfxShape->m_indices,gfxShape->m_numIndices);
|
||||
float groundPos[4] = {0,0,0,0};
|
||||
|
||||
//renderer.registerGraphicsInstance(shapeIndex,groundPos,rotOrn,color,meshScaling);
|
||||
if (vertices.size() && indices.size())
|
||||
{
|
||||
int gpuShapeIndex = m_gpuPhysics->registerConcaveMesh(&vertices,&indices, meshScaling);
|
||||
m_uniqueShapeMapping.push_back(gpuShapeIndex);
|
||||
} else
|
||||
{
|
||||
printf("Error: no vertices in mesh in b3GpuDynamicsWorld::addRigidBody\n");
|
||||
index = -1;
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
|
||||
} else
|
||||
{
|
||||
if (colShape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
|
||||
{
|
||||
|
||||
b3CompoundShape* compound = (b3CompoundShape*) colShape;
|
||||
b3AlignedObjectArray<b3GpuChildShape> childShapes;
|
||||
|
||||
for (int i=0;i<compound->getNumChildShapes();i++)
|
||||
{
|
||||
//for now, only support polyhedral child shapes
|
||||
b3Assert(compound->getChildShape(i)->isPolyhedral());
|
||||
b3GpuChildShape child;
|
||||
child.m_shapeIndex = findOrRegisterCollisionShape(compound->getChildShape(i));
|
||||
b3Vector3 pos = compound->getChildTransform(i).getOrigin();
|
||||
b3Quaternion orn = compound->getChildTransform(i).getRotation();
|
||||
for (int v=0;v<4;v++)
|
||||
{
|
||||
child.m_childPosition[v] = pos[v];
|
||||
child.m_childOrientation[v] = orn[v];
|
||||
}
|
||||
childShapes.push_back(child);
|
||||
}
|
||||
index = m_uniqueShapes.size();
|
||||
m_uniqueShapes.push_back(colShape);
|
||||
|
||||
int gpuShapeIndex = m_gpuPhysics->registerCompoundShape(&childShapes);
|
||||
m_uniqueShapeMapping.push_back(gpuShapeIndex);
|
||||
|
||||
|
||||
|
||||
|
||||
/*printf("Error: unsupported compound type (%d) in b3GpuDynamicsWorld::addRigidBody\n",colShape->getShapeType());
|
||||
index = -1;
|
||||
b3Assert(0);
|
||||
*/
|
||||
} else
|
||||
{
|
||||
if (colShape->getShapeType()==SPHERE_SHAPE_PROXYTYPE)
|
||||
{
|
||||
m_uniqueShapes.push_back(colShape);
|
||||
b3SphereShape* sphere = (b3SphereShape*)colShape;
|
||||
|
||||
int gpuShapeIndex = m_gpuPhysics->registerSphereShape(sphere->getRadius());
|
||||
m_uniqueShapeMapping.push_back(gpuShapeIndex);
|
||||
} else
|
||||
{
|
||||
if (colShape->getShapeType()==STATIC_PLANE_PROXYTYPE)
|
||||
{
|
||||
m_uniqueShapes.push_back(colShape);
|
||||
b3StaticPlaneShape* plane = (b3StaticPlaneShape*)colShape;
|
||||
|
||||
int gpuShapeIndex = m_gpuPhysics->registerPlaneShape(plane->getPlaneNormal(),plane->getPlaneConstant());
|
||||
m_uniqueShapeMapping.push_back(gpuShapeIndex);
|
||||
} else
|
||||
{
|
||||
printf("Error: unsupported shape type (%d) in b3GpuDynamicsWorld::addRigidBody\n",colShape->getShapeType());
|
||||
index = -1;
|
||||
b3Assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void b3GpuDynamicsWorld::addRigidBody(b3RigidBody* body)
|
||||
{
|
||||
|
||||
body->setMotionState(0);
|
||||
|
||||
|
||||
int index = findOrRegisterCollisionShape(body->getCollisionShape());
|
||||
|
||||
if (index>=0)
|
||||
{
|
||||
int gpuShapeIndex= m_uniqueShapeMapping[index];
|
||||
float mass = body->getInvMass() ? 1.f/body->getInvMass() : 0.f;
|
||||
b3Vector3 pos = body->getWorldTransform().getOrigin();
|
||||
b3Quaternion orn = body->getWorldTransform().getRotation();
|
||||
|
||||
m_gpuPhysics->registerPhysicsInstance(mass,&pos.getX(),&orn.getX(),gpuShapeIndex,m_collisionObjects.size());
|
||||
|
||||
m_collisionObjects.push_back(body);
|
||||
}
|
||||
}
|
||||
|
||||
void b3GpuDynamicsWorld::removeCollisionObject(b3CollisionObject* colObj)
|
||||
{
|
||||
b3DynamicsWorld::removeCollisionObject(colObj);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#ifndef B3_GPU_DYNAMICS_WORLD_H
|
||||
#define B3_GPU_DYNAMICS_WORLD_H
|
||||
|
||||
class b3Vector3;
|
||||
class b3RigidBody;
|
||||
class b3CollisionObject;
|
||||
struct b3GpuInternalData;//use this struct to avoid 'leaking' all OpenCL headers into clients code base
|
||||
class CLPhysicsDemo;
|
||||
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
//#include "BulletDynamics/Dynamics/b3DynamicsWorld.h"
|
||||
|
||||
|
||||
class b3GpuDynamicsWorld //: public b3DynamicsWorld
|
||||
{
|
||||
|
||||
b3AlignedObjectArray<const class b3CollisionShape*> m_uniqueShapes;
|
||||
b3AlignedObjectArray<int> m_uniqueShapeMapping;
|
||||
|
||||
|
||||
CLPhysicsDemo* m_gpuPhysics;
|
||||
b3Vector3 m_gravity;
|
||||
bool m_once;
|
||||
|
||||
bool initOpenCL(int preferredDeviceIndex, int preferredPlatformIndex, bool useInterop);
|
||||
void exitOpenCL();
|
||||
|
||||
int findOrRegisterCollisionShape(const b3CollisionShape* colShape);
|
||||
|
||||
|
||||
public:
|
||||
b3GpuDynamicsWorld(int preferredOpenCLPlatformIndex,int preferredOpenCLDeviceIndex);
|
||||
|
||||
virtual ~b3GpuDynamicsWorld();
|
||||
|
||||
virtual int stepSimulation( b3Scalar timeStep,int maxSubSteps=1, b3Scalar fixedTimeStep=b3Scalar(1.)/b3Scalar(60.));
|
||||
|
||||
virtual void synchronizeMotionStates()
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
void debugDrawWorld() {}
|
||||
|
||||
void setGravity(const b3Vector3& gravity);
|
||||
|
||||
void addRigidBody(b3RigidBody* body);
|
||||
|
||||
void removeCollisionObject(b3CollisionObject* colObj);
|
||||
|
||||
|
||||
|
||||
b3AlignedObjectArray<class b3CollisionObject*>& getCollisionObjectArray();
|
||||
|
||||
const b3AlignedObjectArray<class b3CollisionObject*>& getCollisionObjectArray() const;
|
||||
|
||||
virtual void addAction(b3ActionInterface* action)
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
virtual void removeAction(b3ActionInterface* action)
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
|
||||
b3Vector3 getGravity () const
|
||||
{
|
||||
return m_gravity;
|
||||
}
|
||||
|
||||
virtual void addRigidBody(b3RigidBody* body, short group, short mask)
|
||||
{
|
||||
addRigidBody(body);
|
||||
}
|
||||
|
||||
virtual void removeRigidBody(b3RigidBody* body)
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
virtual void setConstraintSolver(b3ConstraintSolver* solver)
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
virtual b3ConstraintSolver* getConstraintSolver()
|
||||
{
|
||||
b3Assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual b3DynamicsWorldType getWorldType() const
|
||||
{
|
||||
return B3_GPU_PHYSICS_WORLD;
|
||||
}
|
||||
|
||||
virtual void clearForces()
|
||||
{
|
||||
b3Assert(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //B3_GPU_DYNAMICS_WORLD_H
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
"..",
|
||||
".",
|
||||
"../../src"
|
||||
}
|
||||
|
||||
initOpenGL()
|
||||
@@ -37,11 +36,6 @@
|
||||
"../OpenGLTrueTypeFont/fontstash.h",
|
||||
"../OpenGLTrueTypeFont/opengl_fontstashcallbacks.cpp",
|
||||
"../OpenGLTrueTypeFont/opengl_fontstashcallbacks.h",
|
||||
"../../src/Bullet3Geometry/b3ConvexHullComputer.cpp",
|
||||
"../../src/Bullet3Geometry/b3ConvexHullComputer.h",
|
||||
"../../src/Bullet3Common/b3Logging.h",
|
||||
"../../src/Bullet3Common/b3Logging.cpp",
|
||||
"../../src/Bullet3Common/b3AlignedAllocator.cpp",
|
||||
"../../btgui/Timing/b3Clock.cpp",
|
||||
"../../btgui/Timing/b3Clock.h",
|
||||
"**.cpp",
|
||||
|
||||
@@ -322,7 +322,7 @@ static GLint lines_position=0;
|
||||
static GLint lines_colour=0;
|
||||
GLuint lineVertexBufferObject=0;
|
||||
GLuint lineVertexArrayObject=0;
|
||||
|
||||
GLuint lineIndexVbo = 0;
|
||||
|
||||
|
||||
|
||||
@@ -720,17 +720,21 @@ void GLInstancingRenderer::InitShaders()
|
||||
int SCALE_BUFFER_SIZE = (m_maxNumObjectCapacity*sizeof(float)*3);
|
||||
|
||||
linesShader = gltLoadShaderPair(linesVertexShader,linesFragmentShader);
|
||||
glLinkProgram(linesShader);
|
||||
glUseProgram(linesShader);
|
||||
lines_ModelViewMatrix = glGetUniformLocation(linesShader, "ModelViewMatrix");
|
||||
lines_ProjectionMatrix = glGetUniformLocation(linesShader, "ProjectionMatrix");
|
||||
lines_colour=glGetUniformLocation(linesShader, "colour");
|
||||
lines_position=glGetAttribLocation(linesShader, "position");
|
||||
glLinkProgram(linesShader);
|
||||
glUseProgram(linesShader);
|
||||
|
||||
glGenBuffers(1, &lineVertexBufferObject);
|
||||
|
||||
glGenVertexArrays(1, &lineVertexArrayObject);
|
||||
glBindVertexArray(lineVertexArrayObject);
|
||||
|
||||
glGenBuffers(1, &lineVertexBufferObject);
|
||||
glGenBuffers(1, &lineIndexVbo);
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
//glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range);
|
||||
glGetIntegerv(GL_SMOOTH_LINE_WIDTH_RANGE, lineWidthRange);
|
||||
@@ -1315,16 +1319,85 @@ void GLInstancingRenderer::drawPoints(const float* positions, const float color[
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
|
||||
glBufferData(GL_ARRAY_BUFFER, numPoints*pointStrideInBytes, positions, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
|
||||
glEnableVertexAttribArray(0);
|
||||
int numFloats = 3;//pointStrideInBytes/sizeof(float);
|
||||
glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, pointStrideInBytes, 0);
|
||||
int numFloats = pointStrideInBytes/sizeof(float);
|
||||
glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glDrawArrays(GL_POINTS, 0, numPoints);
|
||||
glBindVertexArray(0);
|
||||
glPointSize(1);
|
||||
}
|
||||
|
||||
void GLInstancingRenderer::drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize)
|
||||
{
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
|
||||
|
||||
GLint err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D,0);
|
||||
int curOffset = 0;
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
glUseProgram(linesShader);
|
||||
glUniformMatrix4fv(lines_ProjectionMatrix, 1, false, &projectionMatrix[0]);
|
||||
glUniformMatrix4fv(lines_ModelViewMatrix, 1, false, &modelviewMatrix[0]);
|
||||
glUniform4f(lines_colour,color[0],color[1],color[2],color[3]);
|
||||
|
||||
// glPointSize(pointDrawSize);
|
||||
glBindVertexArray(lineVertexArrayObject);
|
||||
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
|
||||
glBufferData(GL_ARRAY_BUFFER, numPoints*pointStrideInBytes, positions, GL_STATIC_DRAW);
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
int numFloats = pointStrideInBytes/sizeof(float);
|
||||
glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lineIndexVbo);
|
||||
int indexBufferSizeInBytes = numIndices*sizeof(int);
|
||||
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeInBytes, NULL, GL_STATIC_DRAW);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSizeInBytes,indices);
|
||||
|
||||
glDrawElements(GL_LINES, numIndices, GL_UNSIGNED_INT,0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// for (int i=0;i<numIndices;i++)
|
||||
// printf("indicec[i]=%d]\n",indices[i]);
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
glBindVertexArray(0);
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
glPointSize(1);
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void GLInstancingRenderer::drawLine(const float from[4], const float to[4], const float color[4], float lineWidth)
|
||||
{
|
||||
GLint err = glGetError();
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
struct GLInstanceRendererInternalData* getInternalData();
|
||||
|
||||
void drawLine(const float from[4], const float to[4], const float color[4], float lineWidth=1);
|
||||
void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize);
|
||||
void drawPoints(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, float pointDrawSize);
|
||||
void drawPoint(const float* position, const float color[4], float pointSize=1);
|
||||
void updateCamera();
|
||||
|
||||
@@ -288,6 +288,8 @@ void GLPrimitiveRenderer::drawTexturedRect(float x0, float y0, float x1, float y
|
||||
|
||||
glUniform2fv(m_data->m_positionUniform, 1, (const GLfloat *)&p);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
err = glGetError();
|
||||
@@ -316,6 +318,7 @@ void GLPrimitiveRenderer::drawTexturedRect(float x0, float y0, float x1, float y
|
||||
err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
|
||||
|
||||
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
|
||||
err = glGetError();
|
||||
assert(err==GL_NO_ERROR);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "Bullet3Common/b3Logging.h"
|
||||
|
||||
|
||||
// Load the shader from the source text
|
||||
void gltLoadShaderSrc(const char *szShaderSrc, GLuint shader)
|
||||
@@ -90,8 +90,8 @@ GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg)
|
||||
&actualLen,
|
||||
infoLog);
|
||||
|
||||
b3Error("Warning/Error in GLSL shader:\n");
|
||||
b3Error("%s\n",infoLog);
|
||||
printf("Warning/Error in GLSL shader:\n");
|
||||
printf("%s\n",infoLog);
|
||||
glDeleteProgram(hReturn);
|
||||
return (GLuint)NULL;
|
||||
}
|
||||
|
||||
215
btgui/OpenGLWindow/SimpleOpenGL3App.cpp
Normal file
215
btgui/OpenGLWindow/SimpleOpenGL3App.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "SimpleOpenGL3App.h"
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "OpenGLWindow/MacOpenGLWindow.h"
|
||||
#else
|
||||
|
||||
#include "GL/glew.h"
|
||||
#ifdef _WIN32
|
||||
#include "OpenGLWindow/Win32OpenGLWindow.h"
|
||||
#else
|
||||
//let's cross the fingers it is Linux/X11
|
||||
#include "OpenGLWindow/X11OpenGLWindow.h"
|
||||
#endif //_WIN32
|
||||
#endif//__APPLE__
|
||||
|
||||
#include "OpenGLWindow/GLPrimitiveRenderer.h"
|
||||
#include "OpenGLWindow/GLInstancingRenderer.h"
|
||||
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
|
||||
#include "../btgui/OpenGLTrueTypeFont/fontstash.h"
|
||||
#include "../btgui/OpenGLWindow/TwFonts.h"
|
||||
|
||||
struct SimpleInternalData
|
||||
{
|
||||
GLuint m_fontTextureId;
|
||||
};
|
||||
|
||||
static SimpleOpenGL3App* gApp=0;
|
||||
|
||||
void SimpleResizeCallback( float width, float height)
|
||||
{
|
||||
gApp->m_instancingRenderer->resize(width,height);
|
||||
gApp->m_primRenderer->setScreenSize(width,height);
|
||||
|
||||
}
|
||||
|
||||
static GLuint BindFont(const CTexFont *_Font)
|
||||
{
|
||||
GLuint TexID = 0;
|
||||
glGenTextures(1, &TexID);
|
||||
glBindTexture(GL_TEXTURE_2D, TexID);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_RED, GL_UNSIGNED_BYTE, _Font->m_TexBytes);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return TexID;
|
||||
}
|
||||
|
||||
|
||||
SimpleOpenGL3App::SimpleOpenGL3App( const char* title, int width,int height)
|
||||
{
|
||||
gApp = this;
|
||||
m_data = new SimpleInternalData;
|
||||
m_window = new b3gDefaultOpenGLWindow();
|
||||
b3gWindowConstructionInfo ci;
|
||||
ci.m_title = title;
|
||||
ci.m_width = width;
|
||||
ci.m_height = height;
|
||||
m_window->createWindow(ci);
|
||||
|
||||
m_window->setWindowTitle(title);
|
||||
glClearColor(1,1,1,1);
|
||||
m_window->startRendering();
|
||||
#ifndef __APPLE__
|
||||
glewInit();
|
||||
#endif
|
||||
|
||||
m_primRenderer = new GLPrimitiveRenderer(width,height);
|
||||
|
||||
m_instancingRenderer = new GLInstancingRenderer(128*1024,4*1024*1024);
|
||||
m_instancingRenderer->init();
|
||||
m_instancingRenderer->resize(width,height);
|
||||
m_instancingRenderer->InitShaders();
|
||||
|
||||
m_window->setMouseMoveCallback(b3DefaultMouseMoveCallback);
|
||||
m_window->setMouseButtonCallback(b3DefaultMouseButtonCallback);
|
||||
m_window->setKeyboardCallback(b3DefaultKeyboardCallback);
|
||||
m_window->setWheelCallback(b3DefaultWheelCallback);
|
||||
m_window->setResizeCallback(SimpleResizeCallback);
|
||||
|
||||
TwGenerateDefaultFonts();
|
||||
m_data->m_fontTextureId = BindFont(g_DefaultNormalFont);
|
||||
}
|
||||
|
||||
|
||||
void SimpleOpenGL3App::drawText( const char* txt, int posX, int posY)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//printf("str = %s\n",unicodeText);
|
||||
int xpos=0;
|
||||
int ypos=0;
|
||||
float dx;
|
||||
|
||||
int measureOnly=0;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/*
|
||||
if (m_useTrueTypeFont)
|
||||
{
|
||||
|
||||
float yoffset = 0.f;
|
||||
if (m_retinaScale==2.0f)
|
||||
{
|
||||
yoffset = -12;
|
||||
}
|
||||
Translate(r);
|
||||
sth_draw_text(m_font,
|
||||
1,m_fontScaling,
|
||||
r.x,r.y+yoffset,
|
||||
unicodeText,&dx, m_screenWidth,m_screenHeight,measureOnly,m_retinaScale);
|
||||
|
||||
} else
|
||||
*/
|
||||
{
|
||||
//float width = 0.f;
|
||||
int pos=0;
|
||||
float color[]={0.2f,0.2,0.2f,1.f};
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D,m_data->m_fontTextureId);
|
||||
|
||||
//float width = r.x;
|
||||
float extraSpacing = 0.;
|
||||
|
||||
int startX = posX;
|
||||
int startY = posY;
|
||||
|
||||
|
||||
while (txt[pos])
|
||||
{
|
||||
int c = txt[pos];
|
||||
//r.h = g_DefaultNormalFont->m_CharHeight;
|
||||
//r.w = g_DefaultNormalFont->m_CharWidth[c]+extraSpacing;
|
||||
int endX = startX+g_DefaultNormalFont->m_CharWidth[c];
|
||||
int endY = startY+g_DefaultNormalFont->m_CharHeight;
|
||||
//Gwen::Rect rect = r;
|
||||
//Translate( rect );
|
||||
|
||||
|
||||
float currentColor[]={0.2f,0.2,0.2f,1.f};
|
||||
|
||||
m_primRenderer->drawTexturedRect(startX, startY, endX, endY, currentColor,g_DefaultNormalFont->m_CharU0[c],g_DefaultNormalFont->m_CharV0[c],g_DefaultNormalFont->m_CharU1[c],g_DefaultNormalFont->m_CharV1[c]);
|
||||
|
||||
//DrawTexturedRect(0,r,g_DefaultNormalFont->m_CharU0[c],g_DefaultNormalFont->m_CharV0[c],g_DefaultNormalFont->m_CharU1[c],g_DefaultNormalFont->m_CharV1[c]);
|
||||
// DrawFilledRect(r);
|
||||
|
||||
startX = endX;
|
||||
//startY = endY;
|
||||
|
||||
pos++;
|
||||
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D,0);
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void SimpleOpenGL3App::drawGrid(int gridSize)
|
||||
{
|
||||
|
||||
b3Vector3 gridColor = b3MakeVector3(0.5,0.5,0.5);
|
||||
for(int i=-gridSize;i<=gridSize;i++)
|
||||
{
|
||||
|
||||
GLint err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
m_instancingRenderer->drawLine(b3MakeVector3(float(i),0,float(-gridSize)),b3MakeVector3(float(i),0,float(gridSize)),gridColor);
|
||||
|
||||
err = glGetError();
|
||||
b3Assert(err==GL_NO_ERROR);
|
||||
|
||||
m_instancingRenderer->drawLine(b3MakeVector3(float(-gridSize),0,float(i)),b3MakeVector3(float(gridSize),0,float(i)),gridColor);
|
||||
}
|
||||
|
||||
m_instancingRenderer->drawLine(b3MakeVector3(0,0,0),b3MakeVector3(1,0,0),b3MakeVector3(1,0,0),3);
|
||||
m_instancingRenderer->drawLine(b3MakeVector3(0,0,0),b3MakeVector3(0,1,0),b3MakeVector3(0,1,0),3);
|
||||
m_instancingRenderer->drawLine(b3MakeVector3(0,0,0),b3MakeVector3(0,0,1),b3MakeVector3(0,0,1),3);
|
||||
|
||||
m_instancingRenderer->drawPoint(b3MakeVector3(1,0,0),b3MakeVector3(1,0,0),6);
|
||||
m_instancingRenderer->drawPoint(b3MakeVector3(0,1,0),b3MakeVector3(0,1,0),6);
|
||||
m_instancingRenderer->drawPoint(b3MakeVector3(0,0,1),b3MakeVector3(0,0,1),6);
|
||||
}
|
||||
|
||||
SimpleOpenGL3App::~SimpleOpenGL3App()
|
||||
{
|
||||
delete m_primRenderer ;
|
||||
|
||||
m_window->closeWindow();
|
||||
delete m_window;
|
||||
delete m_data ;
|
||||
}
|
||||
|
||||
void SimpleOpenGL3App::swapBuffer()
|
||||
{
|
||||
m_window->endRendering();
|
||||
m_window->startRendering();
|
||||
}
|
||||
25
btgui/OpenGLWindow/SimpleOpenGL3App.h
Normal file
25
btgui/OpenGLWindow/SimpleOpenGL3App.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef SIMPLE_OPENGL3_APP_H
|
||||
#define SIMPLE_OPENGL3_APP_H
|
||||
|
||||
#include "OpenGLWindow/GLInstancingRenderer.h"
|
||||
#include "OpenGLWindow/GLPrimitiveRenderer.h"
|
||||
#include "OpenGLWindow/b3gWindowInterface.h"
|
||||
|
||||
struct SimpleOpenGL3App
|
||||
{
|
||||
struct SimpleInternalData* m_data;
|
||||
|
||||
class b3gWindowInterface* m_window;
|
||||
class GLPrimitiveRenderer* m_primRenderer;
|
||||
class GLInstancingRenderer* m_instancingRenderer;
|
||||
|
||||
SimpleOpenGL3App(const char* title, int width,int height);
|
||||
virtual ~SimpleOpenGL3App();
|
||||
|
||||
void drawGrid(int gridSize=10);
|
||||
void swapBuffer();
|
||||
void drawText( const char* txt, int posX, int posY);
|
||||
|
||||
};
|
||||
|
||||
#endif //SIMPLE_OPENGL3_APP_H
|
||||
@@ -18,14 +18,14 @@ subject to the following restrictions:
|
||||
|
||||
#include "OpenGLInclude.h"
|
||||
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
//#include "Bullet3Common/b3Vector3.h"
|
||||
|
||||
#include "Win32InternalWindowData.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void printGLString(const char *name, GLenum s) {
|
||||
const char *v = (const char *) glGetString(s);
|
||||
b3Printf("GL %s = %s\n", name, v);
|
||||
printf("%s = %s\n",name, v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ subject to the following restrictions:
|
||||
#include "Win32Window.h"
|
||||
|
||||
#include "OpenGLInclude.h"
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
|
||||
#include <wchar.h>
|
||||
static InternalData2* sData = 0;
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
"GLInstancingRenderer.h",
|
||||
"GLPrimitiveRenderer.h",
|
||||
"GLPrimitiveRenderer.cpp",
|
||||
"SimpleOpenGL3App.cpp",
|
||||
"SimpleOpenGL3App.h",
|
||||
"LoadShader.cpp",
|
||||
"LoadShader.h",
|
||||
"gwenWindow.cpp",
|
||||
|
||||
@@ -101,11 +101,13 @@
|
||||
|
||||
if not _OPTIONS["ios"] then
|
||||
|
||||
-- include "../Demos3/CpuDemos"
|
||||
|
||||
include "../Demos3/GpuDemos"
|
||||
-- include "../Demos3/CpuDemos"
|
||||
|
||||
include "../Demos3/Wavefront"
|
||||
include "../btgui/MultiThreading"
|
||||
|
||||
include "../Demos3/ImplicitCloth"
|
||||
|
||||
-- include "../demo/gpudemo"
|
||||
-- include "../btgui/MidiTest"
|
||||
|
||||
Reference in New Issue
Block a user