diff --git a/Demos3/GpuDemos/ParticleDemo.cpp b/Demos3/GpuDemos/ParticleDemo.cpp index 7221d88e2..1a10d13f2 100644 --- a/Demos3/GpuDemos/ParticleDemo.cpp +++ b/Demos3/GpuDemos/ParticleDemo.cpp @@ -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(); } diff --git a/Demos3/GpuDemos/ParticleKernels.cl b/Demos3/GpuDemos/ParticleKernels.cl index 34fed45c0..c3a32d541 100644 --- a/Demos3/GpuDemos/ParticleKernels.cl +++ b/Demos3/GpuDemos/ParticleKernels.cl @@ -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)) diff --git a/Demos3/GpuDemos/main_opengl3core.cpp b/Demos3/GpuDemos/main_opengl3core.cpp index 025f388d1..c6d545deb 100644 --- a/Demos3/GpuDemos/main_opengl3core.cpp +++ b/Demos3/GpuDemos/main_opengl3core.cpp @@ -84,12 +84,13 @@ enum }; b3AlignedObjectArray 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, diff --git a/Demos3/ImplicitCloth/main.cpp b/Demos3/ImplicitCloth/main.cpp new file mode 100644 index 000000000..be95c76a2 --- /dev/null +++ b/Demos3/ImplicitCloth/main.cpp @@ -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 indices; + + for (int i=0;isprings.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; +} diff --git a/Demos3/ImplicitCloth/premake4.lua b/Demos3/ImplicitCloth/premake4.lua new file mode 100644 index 000000000..b767e95cc --- /dev/null +++ b/Demos3/ImplicitCloth/premake4.lua @@ -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 diff --git a/Demos3/ImplicitCloth/stan/Cloth.cpp b/Demos3/ImplicitCloth/stan/Cloth.cpp new file mode 100644 index 000000000..e713f8eec --- /dev/null +++ b/Demos3/ImplicitCloth/stan/Cloth.cpp @@ -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 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;iX[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;iCreateSpring(SPRING_STRUCT,i*w+j,(i+1)*w+j); // structural + if(jCreateSpring(SPRING_STRUCT,i*w+j,i*w+(j+1)); // structural + if(jCreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j+1)); // shear + if(j>0 &&iCreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j-1)); // shear + if(iCreateSpring(SPRING_BEND ,i*w+j,(i+2)*w+j); // benders + if(jCreateSpring(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;isprings.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;iSimulate((cloth->cloth_step<0)?DeltaT:cloth->cloth_step); + //if(cloth_showsprings) + // ClothDrawSprings(cloth); // debug visualization + + } +} \ No newline at end of file diff --git a/Demos3/ImplicitCloth/stan/Cloth.h b/Demos3/ImplicitCloth/stan/Cloth.h new file mode 100644 index 000000000..4a4ec9166 --- /dev/null +++ b/Demos3/ImplicitCloth/stan/Cloth.h @@ -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 diff --git a/Demos3/ImplicitCloth/stan/SpringNetwork.cpp b/Demos3/ImplicitCloth/stan/SpringNetwork.cpp new file mode 100644 index 000000000..d9b2b29c4 --- /dev/null +++ b/Demos3/ImplicitCloth/stan/SpringNetwork.cpp @@ -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 +#include + +#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; + 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 diff --git a/Demos3/ImplicitCloth/stan/array.h b/Demos3/ImplicitCloth/stan/array.h new file mode 100644 index 000000000..d55714698 --- /dev/null +++ b/Demos3/ImplicitCloth/stan/array.h @@ -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 +#include + +template class Array { + public: + Array(int s=0); + Array(Array &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=0 && i ©(const Array &array); + Array &operator=(Array &array); +}; + + +template Array::Array(int s) +{ + if(s==-1) return; + count=0; + array_size = 0; + element = NULL; + if(s) + { + allocate(s); + } +} + + +template Array::Array(Array &array) +{ + count=0; + array_size = 0; + element = NULL; + *this = array; +} + + + + +template Array &Array::copy(const Array &array) +{ + assert(array.array_size>=0); + count=0; + for(int i=0;i Array &Array::operator=( Array &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::~Array() +{ + if (element != NULL && array_size!=0) + { + delete[] element; + } + count=0;array_size=0;element=NULL; +} + +template void Array::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 void Array::SetSize(int s) +{ + if(s==0) + { + if(element) + { + delete[] element; + element = NULL; + } + array_size = s; + } + else + { + allocate(s); + } + count=s; +} + +template void Array::Pack() +{ + allocate(count); +} + +template Type& Array::Add(Type t) +{ + assert(count<=array_size); + if(count==array_size) + { + allocate((array_size)?array_size *2:16); + } + //int i; + //for(i=0;i int Array::Contains(Type t) +{ + int i; + int found=0; + for(i=0;i void Array::AddUnique(Type t) +{ + if(!Contains(t)) Add(t); +} + + +template void Array::DelIndex(int i) +{ + assert(i Type& Array::DelIndexWithLast(int i) +{ + assert(i void Array::Remove(Type t) +{ + int i; + for(i=0;i void Array::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 int Array::IndexOf(Type t) +{ + int i; + for(i=0;i + +#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_loopcountstarget && 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_loopcountstarget && 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 +//template void * vec4::operator new[](size_t n){ return _mm_malloc(n,64); } +//template void vec4::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 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 float3Nx3N &operator= (const E& expression) {expression.evalequals(*this);return *this;} + template float3Nx3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;} + template float3Nx3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;} +}; + +class float3N: public Array +{ +public: + float3N(int _count=0) + { + SetSize(_count); + } + void Zero(); + void Init(const float3 &v); // sets each subvector to v + template float3N &operator= (const E& expression) {expression.evalequals(*this);return *this;} + template float3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;} + template 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 &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 // for memcpy +#include + +float squared(float a){return a*a;} +float clamp(float a,const float minval, const float maxval) {return Min(maxval,Max(minval,a));} +int clamp(int a,const int minval, const int maxval) {return Min(maxval,Max(minval,a));} + + +float Round(float a,float precision) +{ + return floorf(0.5f+a/precision)*precision; +} + + +float Interpolate(const float &f0,const float &f1,float alpha) +{ + return f0*(1-alpha) + f1*alpha; +} + + +int argmin(const float a[],int n) +{ + int r=0; + for(int i=1;ia[r]) + { + r = i; + } + } + return r; +} + + + +//------------ float3 (3D) -------------- + + + +float3 vabs(const float3 &v) +{ + return float3(fabsf(v.x),fabsf(v.y),fabsf(v.z)); +} + + + +float3 safenormalize(const float3 &v) +{ + if(magnitude(v)<=0.0f) + { + return float3(1,0,0); + } + return normalize(v); +} + +float3 Round(const float3 &a,float precision) +{ + return float3(Round(a.x,precision),Round(a.y,precision),Round(a.z,precision)); +} + + +float3 Interpolate(const float3 &v0,const float3 &v1,float alpha) +{ + return v0*(1-alpha) + v1*alpha; +} + +float3 Orth(const float3& v) +{ + float3 absv=vabs(v); + float3 u(1,1,1); + u[argmax(&absv[0],3)] =0.0f; + return normalize(cross(u,v)); +} + +void BoxLimits(const float3 *verts,int verts_count, float3 &bmin,float3 &bmax) +{ + bmin=float3( FLT_MAX, FLT_MAX, FLT_MAX); + bmax=float3(-FLT_MAX,-FLT_MAX,-FLT_MAX); + for(int i=0;ibmaxb[j]) return 0; + if(bminb[j]>bmaxa[j]) return 0; + } + return 1; +} + +// the statement v1*v2 is ambiguous since there are 3 types +// of vector multiplication +// - componantwise (for example combining colors) +// - dot product +// - cross product +// Therefore we never declare/implement this function. +// So we will never see: float3 operator*(float3 a,float3 b) + + + + +//------------ float3x3 --------------- +float Determinant(const float3x3 &m) +{ + return m.x.x*m.y.y*m.z.z + m.y.x*m.z.y*m.x.z + m.z.x*m.x.y*m.y.z + -m.x.x*m.z.y*m.y.z - m.y.x*m.x.y*m.z.z - m.z.x*m.y.y*m.x.z ; +} + +float3x3 Inverse(const float3x3 &a) +{ + float3x3 b; + float d=Determinant(a); + assert(d!=0); + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + int j1=(j+1)%3; + int j2=(j+2)%3; + // reverse indexs i&j to take transpose + b[j][i] = (a[i1][j1]*a[i2][j2]-a[i1][j2]*a[i2][j1])/d; + } + } + // Matrix check=a*b; // Matrix 'check' should be the identity (or close to it) + return b; +} + + +float3x3 Transpose( const float3x3& m ) +{ + return float3x3( float3(m.x.x,m.y.x,m.z.x), + float3(m.x.y,m.y.y,m.z.y), + float3(m.x.z,m.y.z,m.z.z)); +} + + +float3 operator*(const float3& v , const float3x3 &m ) { + return float3((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 ) { + return float3(dot(m.x,v),dot(m.y,v),dot(m.z,v)); +} + + +float3x3 operator*( const float3x3& a, const float3x3& b ) +{ + return float3x3(a.x*b,a.y*b,a.z*b); +} + +float3x3 operator*( const float3x3& a, const float& s ) +{ + return float3x3(a.x*s, a.y*s ,a.z*s); +} +float3x3 operator/( const float3x3& a, const float& s ) +{ + float t=1/s; + return float3x3(a.x*t, a.y*t ,a.z*t); +} +float3x3 operator+( const float3x3& a, const float3x3& b ) +{ + return float3x3(a.x+b.x, a.y+b.y, a.z+b.z); +} +float3x3 operator-( const float3x3& a, const float3x3& b ) +{ + return float3x3(a.x-b.x, a.y-b.y, a.z-b.z); +} +float3x3 &operator+=( float3x3& a, const float3x3& b ) +{ + a.x+=b.x; + a.y+=b.y; + a.z+=b.z; + return a; +} +float3x3 &operator-=( float3x3& a, const float3x3& b ) +{ + a.x-=b.x; + a.y-=b.y; + a.z-=b.z; + return a; +} +float3x3 &operator*=( float3x3& a, const float& s ) +{ + a.x*=s; + a.y*=s; + a.z*=s; + return a; +} + +float3x3 outerprod(const float3& a,const float3& b) +{ + return float3x3(a.x*b,a.y*b,a.z*b); // a is a column vector b is a row vector +} + +//--------------- 4D ---------------- + +float4 operator*( const float4& v, const float4x4& m ) +{ + return v.x*m.x + v.y*m.y + v.z*m.z + v.w*m.w; // yes this actually works +} + + +// Dont implement m*v for now, since that might confuse us +// All our transforms are based on multiplying the "row" vector on the left +//float4 operator*(const float4x4& m , const float4& v ) +//{ +// return float4(dot(v,m.x),dot(v,m.y),dot(v,m.z),dot(v,m.w)); +//} + + +float4x4 operator*( const float4x4& a, const float4x4& b ) +{ + return float4x4(a.x*b,a.y*b,a.z*b,a.w*b); +} + +float4x4 MatrixTranspose(const float4x4 &m) +{ + return float4x4( + m.x.x, m.y.x, m.z.x, m.w.x, + m.x.y, m.y.y, m.z.y, m.w.y, + m.x.z, m.y.z, m.z.z, m.w.z, + m.x.w, m.y.w, m.z.w, m.w.w ); +} + +float4x4 MatrixRigidInverse(const float4x4 &m) +{ + float4x4 trans_inverse = MatrixTranslation(-m.w.xyz()); + float4x4 rot = m; + rot.w = float4(0,0,0,1); + return trans_inverse * MatrixTranspose(rot); +} + + +float4x4 MatrixPerspectiveFov(float fovy, float aspect, float zn, float zf ) +{ + float h = 1.0f/tanf(fovy/2.0f); // view space height + float w = h / aspect ; // view space width + return float4x4( + w, 0, 0 , 0, + 0, h, 0 , 0, + 0, 0, zf/(zn-zf) , -1, + 0, 0, zn*zf/(zn-zf) , 0 ); +} + + + +float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up) +{ + float4x4 m; + m.w.w = 1.0f; + m.w.xyz() = eye; + m.z.xyz() = normalize(eye-at); + m.x.xyz() = normalize(cross(up,m.z.xyz())); + m.y.xyz() = cross(m.z.xyz(),m.x.xyz()); + return MatrixRigidInverse(m); +} + + +float4x4 MatrixTranslation(const float3 &t) +{ + return float4x4( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + t.x,t.y,t.z,1 ); +} + + +float4x4 MatrixRotationZ(const float angle_radians) +{ + float s = sinf(angle_radians); + float c = cosf(angle_radians); + return float4x4( + c, s, 0, 0, + -s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 ); +} + + + +int operator==( const float4x4 &a, const float4x4 &b ) +{ + return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w); +} + + +float4x4 Inverse(const float4x4 &m) +{ + float4x4 d; + float *dst = &d.x.x; + float tmp[12]; /* temp array for pairs */ + float src[16]; /* array of transpose source matrix */ + float det; /* determinant */ + /* transpose matrix */ + for ( int i = 0; i < 4; i++) { + src[i] = m(i,0) ; + src[i + 4] = m(i,1); + src[i + 8] = m(i,2); + src[i + 12] = m(i,3); + } + /* calculate pairs for first 8 elements (cofactors) */ + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + /* calculate first 8 elements (cofactors) */ + dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; + dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; + dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; + dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; + dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; + dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; + dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; + dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; + dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; + dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; + dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; + dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; + dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; + dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; + dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; + dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; + /* calculate pairs for second 8 elements (cofactors) */ + tmp[0] = src[2]*src[7]; + tmp[1] = src[3]*src[6]; + tmp[2] = src[1]*src[7]; + tmp[3] = src[3]*src[5]; + tmp[4] = src[1]*src[6]; + tmp[5] = src[2]*src[5]; + tmp[6] = src[0]*src[7]; + tmp[7] = src[3]*src[4]; + tmp[8] = src[0]*src[6]; + tmp[9] = src[2]*src[4]; + tmp[10] = src[0]*src[5]; + tmp[11] = src[1]*src[4]; + /* calculate second 8 elements (cofactors) */ + dst[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; + dst[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; + dst[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; + dst[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; + dst[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; + dst[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; + dst[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; + dst[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; + dst[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; + dst[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; + dst[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; + dst[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; + dst[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; + dst[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; + dst[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; + dst[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; + /* calculate determinant */ + det=src[0]*dst[0]+src[1]*dst[1]+src[2]*dst[2]+src[3]*dst[3]; + /* calculate matrix inverse */ + det = 1/det; + for ( int j = 0; j < 16; j++) + dst[j] *= det; + return d; +} + + +//--------- Quaternion -------------- + +template<> void Quaternion::Normalize() +{ + float m = sqrtf(squared(w)+squared(x)+squared(y)+squared(z)); + if(m<0.000000001f) { + w=1.0f; + x=y=z=0.0f; + return; + } + (*this) *= (1.0f/m); +} + +float3 rotate( const Quaternion& q, const float3& v ) +{ + // The following is equivalent to: + //return (q.getmatrix() * v); + float qx2 = q.x*q.x; + float qy2 = q.y*q.y; + float qz2 = q.z*q.z; + + float qxqy = q.x*q.y; + float qxqz = q.x*q.z; + float qxqw = q.x*q.w; + float qyqz = q.y*q.z; + float qyqw = q.y*q.w; + float qzqw = q.z*q.w; + return float3( + (1-2*(qy2+qz2))*v.x + (2*(qxqy-qzqw))*v.y + (2*(qxqz+qyqw))*v.z , + (2*(qxqy+qzqw))*v.x + (1-2*(qx2+qz2))*v.y + (2*(qyqz-qxqw))*v.z , + (2*(qxqz-qyqw))*v.x + (2*(qyqz+qxqw))*v.y + (1-2*(qx2+qy2))*v.z ); +} + + +Quaternion slerp(const Quaternion &_a, const Quaternion& b, float interp ) +{ + Quaternion a=_a; + if(dot(a,b) <0.0) + { + a.w=-a.w; + a.x=-a.x; + a.y=-a.y; + a.z=-a.z; + } + float d = dot(a,b); + if(d>=1.0) { + return a; + } + float theta = acosf(d); + if(theta==0.0f) { return(a);} + return a*(sinf(theta-interp*theta)/sinf(theta)) + b*(sinf(interp*theta)/sinf(theta)); +} + + +Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha) { + return slerp(q0,q1,alpha); +} + + +Quaternion YawPitchRoll( float yaw, float pitch, float roll ) +{ + return QuatFromAxisAngle(float3(0.0f,0.0f,1.0f),DegToRad(yaw )) + * QuatFromAxisAngle(float3(1.0f,0.0f,0.0f),DegToRad(pitch)) + * QuatFromAxisAngle(float3(0.0f,1.0f,0.0f),DegToRad(roll )); +} + +float Yaw( const Quaternion& q ) +{ + static float3 v; + v=q.ydir(); + return (v.y==0.0&&v.x==0.0) ? 0.0f: RadToDeg(atan2f(-v.x,v.y)); +} + +float Pitch( const Quaternion& q ) +{ + static float3 v; + v=q.ydir(); + return RadToDeg(atan2f(v.z,sqrtf(squared(v.x)+squared(v.y)))); +} + +float Roll( const Quaternion &_q ) +{ + Quaternion q=_q; + q = QuatFromAxisAngle(float3(0.0f,0.0f,1.0f),-DegToRad(Yaw(q))) *q; + q = QuatFromAxisAngle(float3(1.0f,0.0f,0.0f),-DegToRad(Pitch(q))) *q; + return RadToDeg(atan2f(-q.xdir().z,q.xdir().x)); +} + +float Yaw( const float3& v ) +{ + return (v.y==0.0&&v.x==0.0) ? 0.0f: RadToDeg(atan2f(-v.x,v.y)); +} + +float Pitch( const float3& v ) +{ + return RadToDeg(atan2f(v.z,sqrtf(squared(v.x)+squared(v.y)))); +} + + + + + + +//--------- utility functions ------------- + +// RotationArc() +// Given two vectors v0 and v1 this function +// returns quaternion q where q*v0==v1. +// Routine taken from game programming gems. +Quaternion RotationArc(float3 v0,float3 v1){ + static Quaternion q; + v0 = normalize(v0); // Comment these two lines out if you know its not needed. + v1 = normalize(v1); // If vector is already unit length then why do it again? + float3 c = cross(v0,v1); + float d = dot(v0,v1); + if(d<=-1.0f) { float3 a=Orth(v0); return Quaternion(a.x,a.y,a.z,0);} // 180 about any orthogonal axis axis + float s = sqrtf((1+d)*2); + q.x = c.x / s; + q.y = c.y / s; + q.z = c.z / s; + q.w = s /2.0f; + return q; +} + + +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v) +{ + // builds a 4x4 transformation matrix based on orientation q and translation v + float qx2 = q.x*q.x; + float qy2 = q.y*q.y; + float qz2 = q.z*q.z; + + float qxqy = q.x*q.y; + float qxqz = q.x*q.z; + float qxqw = q.x*q.w; + float qyqz = q.y*q.z; + float qyqw = q.y*q.w; + float qzqw = q.z*q.w; + + return float4x4( + 1-2*(qy2+qz2), + 2*(qxqy+qzqw), + 2*(qxqz-qyqw), + 0 , + 2*(qxqy-qzqw), + 1-2*(qx2+qz2), + 2*(qyqz+qxqw), + 0 , + 2*(qxqz+qyqw), + 2*(qyqz-qxqw), + 1-2*(qx2+qy2), + 0 , + v.x , + v.y , + v.z , + 1.0f ); +} + + + +float3 PlaneLineIntersection(const float3 &normal,const float dist, const float3 &p0, const float3 &p1) +{ + // returns the point where the line p0-p1 intersects the plane n&d + float3 dif; + dif = p1-p0; + float dn= dot(normal,dif); + float t = -(dist+dot(normal,p0) )/dn; + return p0 + (dif*t); +} + +float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a) +{ + // project point a on segment [p0,p1] + float3 d= p1-p0; + float t= dot(d,(a-p0)) / dot(d,d); + return p0+ d*t; +} + + +float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a) +{ + // project point a on segment [p0,p1] + float3 d= p1-p0; + float t= dot(d,(a-p0)) / dot(d,d); + return t; +} + + + +float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2) +{ + // return the normal of the triangle + // inscribed by v0, v1, and v2 + float3 cp=cross(v1-v0,v2-v1); + float m=magnitude(cp); + if(m==0) return float3(1,0,0); + return cp*(1.0f/m); +} + + + +int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax) +{ + return (p.x >= bmin.x && p.x <=bmax.x && + p.y >= bmin.y && p.y <=bmax.y && + p.z >= bmin.z && p.z <=bmax.z ); +} + + +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax,float3 *impact) +{ + if(BoxInside(v0,bmin,bmax)) + { + *impact=v0; + return 1; + } + if(v0.x<=bmin.x && v1.x>=bmin.x) + { + float a = (bmin.x-v0.x)/(v1.x-v0.x); + //v.x = bmin.x; + float vy = (1-a) *v0.y + a*v1.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) + { + impact->x = bmin.x; + impact->y = vy; + impact->z = vz; + return 1; + } + } + else if(v0.x >= bmax.x && v1.x <= bmax.x) + { + float a = (bmax.x-v0.x)/(v1.x-v0.x); + //v.x = bmax.x; + float vy = (1-a) *v0.y + a*v1.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) + { + impact->x = bmax.x; + impact->y = vy; + impact->z = vz; + return 1; + } + } + if(v0.y<=bmin.y && v1.y>=bmin.y) + { + float a = (bmin.y-v0.y)/(v1.y-v0.y); + float vx = (1-a) *v0.x + a*v1.x; + //v.y = bmin.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) + { + impact->x = vx; + impact->y = bmin.y; + impact->z = vz; + return 1; + } + } + else if(v0.y >= bmax.y && v1.y <= bmax.y) + { + float a = (bmax.y-v0.y)/(v1.y-v0.y); + float vx = (1-a) *v0.x + a*v1.x; + // vy = bmax.y; + float vz = (1-a) *v0.z + a*v1.z; + if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) + { + impact->x = vx; + impact->y = bmax.y; + impact->z = vz; + return 1; + } + } + if(v0.z<=bmin.z && v1.z>=bmin.z) + { + float a = (bmin.z-v0.z)/(v1.z-v0.z); + float vx = (1-a) *v0.x + a*v1.x; + float vy = (1-a) *v0.y + a*v1.y; + // v.z = bmin.z; + if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) + { + impact->x = vx; + impact->y = vy; + impact->z = bmin.z; + return 1; + } + } + else if(v0.z >= bmax.z && v1.z <= bmax.z) + { + float a = (bmax.z-v0.z)/(v1.z-v0.z); + float vx = (1-a) *v0.x + a*v1.x; + float vy = (1-a) *v0.y + a*v1.y; + // v.z = bmax.z; + if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) + { + impact->x = vx; + impact->y = vy; + impact->z = bmax.z; + return 1; + } + } + return 0; +} + + +float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint, float3 *vpoint) +{ + static float3 cp; + cp = normalize(cross(udir,vdir)); + + float distu = -dot(cp,ustart); + float distv = -dot(cp,vstart); + float dist = (float)fabs(distu-distv); + if(upoint) + { + float3 normal = normalize(cross(vdir,cp)); + *upoint = PlaneLineIntersection(normal,-dot(normal,vstart),ustart,ustart+udir); + } + if(vpoint) + { + float3 normal = normalize(cross(udir,cp)); + *vpoint = PlaneLineIntersection(normal,-dot(normal,ustart),vstart,vstart+vdir); + } + return dist; +} + + +Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2) +{ + // routine taken from game programming gems. + // Implement track ball functionality to spin stuf on the screen + // cop center of projection + // cor center of rotation + // dir1 old mouse direction + // dir2 new mouse direction + // pretend there is a sphere around cor. Then find the points + // where dir1 and dir2 intersect that sphere. Find the + // rotation that takes the first point to the second. + float m; + // compute plane + float3 nrml = cor - cop; + float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop + nrml = normalize(nrml); + float dist = -dot(nrml,cor); + float3 u= PlaneLineIntersection(nrml,dist,cop,cop+dir1); + u=u-cor; + u=u*fudgefactor; + m= magnitude(u); + if(m>1) + { + u/=m; + } + else + { + u=u - (nrml * sqrtf(1-m*m)); + } + float3 v= PlaneLineIntersection(nrml,dist,cop,cop+dir2); + v=v-cor; + v=v*fudgefactor; + m= magnitude(v); + if(m>1) + { + v/=m; + } + else + { + v=v - (nrml * sqrtf(1-m*m)); + } + return RotationArc(u,v); +} + + +int countpolyhit=0; +int HitCheckPoly(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact, float3 *normal) +{ + countpolyhit++; + int i; + float3 nrml(0,0,0); + for(i=0;i0) + { + return 0; + } + + static float3 the_point; + // By using the cached plane distances d0 and d1 + // we can optimize the following: + // the_point = planelineintersection(nrml,dist,v0,v1); + float a = d0/(d0-d1); + the_point = v0*(1-a) + v1*a; + + + int inside=1; + for(int j=0;inside && j= 0.0); + } + if(inside) + { + if(normal){*normal=nrml;} + if(impact){*impact=the_point;} + } + return inside; +} + +int SolveQuadratic(float a,float b,float c,float *ta,float *tb) // if true returns roots ta,tb where ta<=tb +{ + assert(ta); + assert(tb); + float d = b*b-4.0f*a*c; // discriminant + if(d<0.0f) return 0; + float sqd = sqrtf(d); + *ta = (-b-sqd) / (2.0f * a); + *tb = (-b+sqd) / (2.0f * a); + return 1; +} + +int HitCheckRaySphere(const float3& sphereposition,float radius, const float3& _v0, const float3& _v1, float3 *impact,float3 *normal) +{ + assert(impact); + assert(normal); + float3 dv = _v1-_v0; + float3 v0 = _v0 - sphereposition; // solve in coord system of the sphere + if(radius<=0.0f || _v0==_v1) return 0; // only true if point moves from outside to inside sphere. + float a = dot(dv,dv); + float b = 2.0f * dot(dv,v0); + float c = dot(v0,v0) - radius*radius; + if(c<0.0f) return 0; // we are already inside the sphere. + + float ta, tb; + int doesIntersect = SolveQuadratic(a, b, c, &ta, &tb); + + if (!doesIntersect) return 0; + + if (ta >= 0.0f && ta <= 1.0f && (ta <= tb || tb<=0.0f)) + { + *impact = _v0 + dv * ta; + *normal = (v0 + dv*ta)/radius; + return 1; + } + if (tb >= 0.0f && tb <= 1.0f) + { + assert(tb <= ta || ta <=0.0f); // tb must be better than ta + *impact = _v0 + dv * tb; + *normal = (v0 + dv*tb)/radius; + return 1; + } + return 0; +} + +int HitCheckRayCylinder(const float3 &p0,const float3 &p1,float radius,const float3& _v0,const float3& _v1, float3 *impact,float3 *normal) +{ + assert(impact); + assert(normal); + // only concerned about hitting the sides, not the caps for now + float3x3 m=RotationArc(p1-p0,float3(0,0,1.0f)).getmatrix(); + float h = ((p1-p0)*m ).z; + float3 v0 = (_v0-p0) *m; + float3 v1 = (_v1-p0) *m; + if(v0.z <= 0.0f && v1.z <= 0.0f) return 0; // entirely below cylinder + if(v0.z >= h && v1.z >= h ) return 0; // ray is above cylinder + if(v0.z <0.0f ) v0 = PlaneLineIntersection(float3(0,0,1.0f), 0,v0,v1); // crop to cylinder range + if(v1.z <0.0f ) v1 = PlaneLineIntersection(float3(0,0,1.0f), 0,v0,v1); + if(v0.z > h ) v0 = PlaneLineIntersection(float3(0,0,1.0f),-h,v0,v1); + if(v1.z > h ) v1 = PlaneLineIntersection(float3(0,0,1.0f),-h,v0,v1); + if(v0.x==v1.x && v0.y==v1.y) return 0; + float3 dv = v1-v0; + + float a = dv.x*dv.x+dv.y*dv.y; + float b = 2.0f * (dv.x*v0.x+dv.y*v0.y); + float c = (v0.x*v0.x+v0.y*v0.y) - radius*radius; + if(c<0.0f) return 0; // we are already inside the cylinder . + + float ta, tb; + int doesIntersect = SolveQuadratic(a, b, c, &ta, &tb); + + if (!doesIntersect) return 0; + + if (ta >= 0.0f && ta <= 1.0f && (ta <= tb || tb<=0.0f)) + { + *impact = (v0 + dv * ta)*Transpose(m) + p0; + *normal = (float3(v0.x,v0.y,0.0f) + float3(dv.x,dv.y,0) * ta) /radius * Transpose(m); + return 1; + } + if (tb >= 0.0f && tb <= 1.0f) + { + assert(tb <= ta || ta <=0.0f); // tb must be better than ta + *impact = (v0 + dv * tb)*Transpose(m) + p0; // compute intersection in original space + *normal = (float3(v0.x,v0.y,0.0f) + float3(dv.x,dv.y,0) * tb) /radius * Transpose(m); + return 1; + } + return 0; +} + +int HitCheckSweptSphereTri(const float3 &p0,const float3 &p1,const float3 &p2,float radius, const float3& v0,const float3& _v1, float3 *impact,float3 *normal) +{ + float3 unused; + if(!normal) normal=&unused; + float3 v1=_v1; // so we can update v1 after each sub intersection test if necessary + int hit=0; + float3 cp = cross(p1-p0,p2-p0); + if(dot(cp,v1-v0)>=0.0f) return 0; // coming from behind and/or moving away + float3 n = normalize(cp); + float3 tv[3]; + tv[0] = p0 + n*radius; + tv[1] = p1 + n*radius; + tv[2] = p2 + n*radius; + hit += HitCheckPoly(tv,3,v0,v1,&v1,normal); + hit += HitCheckRayCylinder(p0,p1,radius,v0,v1,&v1,normal); + hit += HitCheckRayCylinder(p1,p2,radius,v0,v1,&v1,normal); + hit += HitCheckRayCylinder(p2,p0,radius,v0,v1,&v1,normal); + hit += HitCheckRaySphere(p0,radius,v0,v1,&v1,normal); + hit += HitCheckRaySphere(p1,radius,v0,v1,&v1,normal); + hit += HitCheckRaySphere(p2,radius,v0,v1,&v1,normal); + if(hit && impact) *impact = v1 + *normal * 0.001f; + return hit; +} + + +float3 PlanesIntersection(const Plane &p0,const Plane &p1, const Plane &p2) +{ + float3x3 mp =Transpose(float3x3(p0.normal(),p1.normal(),p2.normal())); + float3x3 mi = Inverse(mp); + float3 b(p0.dist(),p1.dist(),p2.dist()); + return -b * mi; +} + + +float3 PlanesIntersection(const Plane *planes,int planes_count,const float3 &seed) +{ + int i; + float3x3 A; // gets initilized to 0 matrix + float3 b(0,0,0); + for(i=0;i= count+1 + assert(verts_out); + int n=0; + int prev_status = (dot(plane_normal,verts_in[count_in-1])+plane_dist > 0) ; + for(int i=0;i 0) ; + if(status != prev_status) + { + verts_out[n++] = PlaneLineIntersection(plane_normal,plane_dist,verts_in[(i==0)?count_in-1:i-1],verts_in[i]); + } + if(status==0) // under + { + verts_out[n++] = verts_in[i]; + } + } + assert(n<=count_in+1); // remove if intention to use this routine on convex polygons + return n; +} + +int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch) +{ + // clips polys against each other. + // requires sufficiently allocated temporary memory in scratch buffer + // function returns final number of vertices in clipped polygon. + // Resulting vertices are returned in the scratch buffer. + // if the arrays are the same &verts_in==&scratch the routine should still work anyways. + // the first argument (normal) is the normal of polygon clipper. + // its generally assumed both are convex polygons. + assert(scratch); // size should be >= 2*(clipper_count+in_count) + int i; + int bsize = clipper_count+in_count; + int count = in_count; + for(i=0;iom.y&&om.x>om.z)?0: (om.y>om.z)? 1 : 2; // index of largest element of offdiag + int k1 = (k+1)%3; + int k2 = (k+2)%3; + if(offdiag[k]==0.0f) break; // diagonal already + float thet = (D[k2][k2]-D[k1][k1])/(2.0f*offdiag[k]); + float sgn = (thet>0.0f)?1.0f:-1.0f; + thet *= sgn; // make it positive + float t = sgn /(thet +((thet<1.E6f)?sqrtf(squared(thet)+1.0f):thet)) ; // sign(T)/(|T|+sqrt(T^2+1)) + float c = 1.0f/sqrtf(squared(t)+1.0f); // c= 1/(t^2+1) , t=s/c + if(c==1.0f) break; // no room for improvement - reached machine precision. + Quaternion jr(0,0,0,0); // jacobi rotation for this iteration. + jr[k] = sgn*sqrtf((1.0f-c)/2.0f); // using 1/2 angle identity sin(a/2) = sqrt((1-cos(a))/2) + jr[k] *= -1.0f; // since our quat-to-matrix convention was for v*M instead of M*v + jr.w = sqrtf(1.0f - squared(jr[k])); + if(jr.w==1.0f) break; // reached limits of floating point precision + q = q*jr; + q.Normalize(); + } + return q; +} + +float3 Diagonal(const float3x3 &M) +{ + return float3(M[0][0],M[1][1],M[2][2]); +} diff --git a/Demos3/ImplicitCloth/stan/vecmath.h b/Demos3/ImplicitCloth/stan/vecmath.h new file mode 100644 index 000000000..a83ed8cfb --- /dev/null +++ b/Demos3/ImplicitCloth/stan/vecmath.h @@ -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 +#include +#include +#include + +#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 +void Swap(T &a,T &b) +{ + T tmp = a; + a=b; + b=tmp; +} + + + +template +T Max(const T &a,const T &b) +{ + return (a>b)?a:b; +} + +template +T Min(const T &a,const T &b) +{ + return (a +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 int2; +typedef vec2 float2; + + +template inline int operator ==(const vec2 &a,const vec2 &b) {return (a.x==b.x && a.y==b.y);} +template inline vec2 operator-( const vec2& a, const vec2& b ){return vec2(a.x-b.x,a.y-b.y);} +template inline vec2 operator+( const vec2& a, const vec2& b ){return float2(a.x+b.x,a.y+b.y);} + +//--------- 3D --------- + + + +template +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 int3; +typedef vec3 short3; +typedef vec3 float3; + +// due to ambiguity there is no overloaded operators for v3*v3 use dot,cross,outerprod,cmul +template inline int operator==(const vec3 &a,const vec3 &b) {return (a.x==b.x && a.y==b.y && a.z==b.z);} +template inline int operator!=(const vec3 &a,const vec3 &b) {return !(a==b);} +template inline vec3 operator+(const vec3& a, const vec3& b ){return vec3(a.x+b.x, a.y+b.y, a.z+b.z);} +template inline vec3 operator-(const vec3& a, const vec3& b ){return vec3(a.x-b.x, a.y-b.y, a.z-b.z);} +template inline vec3 operator-(const vec3& v){return vec3(-v.x,-v.y,-v.z );} +template inline vec3 operator*(const vec3& v, const T &s ){ return vec3( v.x*s, v.y*s, v.z*s );} +template inline vec3 operator*(T s, const vec3& v ){return v*s;} +template inline vec3 operator/(const vec3& v, T s ){return vec3( v.x/s, v.y/s, v.z/s );} +template inline T dot (const vec3& a, const vec3& b){return a.x*b.x + a.y*b.y + a.z*b.z;} +template inline vec3 cmul (const vec3& a, const vec3& b){return vec3(a.x*b.x, a.y*b.y, a.z*b.z);} +template inline vec3 cross(const vec3& a, const vec3& b){return vec3(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 inline T magnitude( const vec3& v ){return squareroot(dot(v,v));} +template inline vec3 normalize( const vec3& v ){return v/magnitude(v);} +template inline vec3& operator+=(vec3& a, const vec3& b){a.x+=b.x;a.y+=b.y;a.z+=b.z;return a;} +template inline vec3& operator-=(vec3& a, const vec3& b){a.x-=b.x;a.y-=b.y;a.z-=b.z;return a;} +template inline vec3& operator*=(vec3& v, T s){v.x*=s;v.y*=s;v.z*= s;return v;} +template inline vec3& operator/=(vec3& 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 inline vec3VectorMin(const vec3 &a,const vec3 &b) {return vec3(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z));} +template inline vec3VectorMax(const vec3 &a,const vec3 &b) {return vec3(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 mat3x3 +{ + public: + vec3 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 &_x,const vec3 &_y,const vec3 &_z):x(_x),y(_y),z(_z){} + inline vec3& operator[](int i) {return (&x)[i];} + inline const vec3& 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 float3x3; + +float3x3 Transpose( const float3x3& m ); +template vec3 operator*( const vec3& v , const mat3x3& m ) +{ + return vec3((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 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 &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& xyz() const { return *((vec3*)this);} + inline vec3& xyz() { return *((vec3*)this);} +}; + + +typedef vec4 float4; +typedef vec4 int4; +typedef vec4 byte4; + + +template inline int operator==(const vec4 &a,const vec4 &b) {return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);} +template inline int operator!=(const vec4 &a,const vec4 &b) {return !(a==b);} +template inline vec4 operator+(const vec4& a, const vec4& b ){return vec4(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);} +template inline vec4 operator-(const vec4& a, const vec4& b ){return vec4(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);} +template inline vec4 operator-(const vec4& v){return vec4(-v.x,-v.y,-v.z,-v.w);} +template inline vec4 operator*(const vec4& v, const T &s ){ return vec4( v.x*s, v.y*s, v.z*s,v.w*s);} +template inline vec4 operator*(T s, const vec4& v ){return v*s;} +template inline vec4 operator/(const vec4& v, T s ){return vec4( v.x/s, v.y/s, v.z/s,v.w/s );} +template inline T dot(const vec4& a, const vec4& b ){return a.x*b.x + a.y*b.y + a.z*b.z+a.w*b.w;} +template inline vec4 cmul(const vec4 &a, const vec4 &b) {return vec4(a.x*b.x, a.y*b.y, a.z*b.z,a.w*b.w);} +template inline vec4& operator+=(vec4& a, const vec4& b ){a.x+=b.x;a.y+=b.y;a.z+=b.z;a.w+=b.w;return a;} +template inline vec4& operator-=(vec4& a, const vec4& b ){a.x-=b.x;a.y-=b.y;a.z-=b.z;a.w-=b.w;return a;} +template inline vec4& operator*=(vec4& v, T s){v.x*=s;v.y*=s;v.z*=s;v.w*=s;return v;} +template inline vec4& operator/=(vec4& v, T s){v.x/=s;v.y/=s;v.z/=s;v.w/=s;return v;} +template inline T magnitude( const vec4& v ){return squareroot(dot(v,v));} +template inline vec4 normalize( const vec4& v ){return v/magnitude(v);} + + + +struct D3DXMATRIX; + +template +class mat4x4 +{ + public: + vec4 x,y,z,w; // the 4 rows + inline mat4x4(){} + inline mat4x4(const vec4 &_x, const vec4 &_y, const vec4 &_z, const vec4 &_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& operator[](int i) {assert(i>=0&&i<4);return (&x)[i];} + inline const vec4& 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 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 quaternion : public vec4 +{ + 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 &v):vec4(v){} + T angle() const { return acosf(this->w)*2.0f; } + vec3 axis() const { vec3 a(this->x,this->y,this->z); if(fabsf(angle())<0.0000001f) return vec3(1,0,0); return a*(1/sinf(angle()/2.0f)); } + inline vec3 xdir() const { return vec3( 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 ydir() const { return vec3( 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 zdir() const { return vec3( 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 getmatrix() const { return mat3x3( xdir(), ydir(), zdir() ); } + //operator float3x3() { return getmatrix(); } + void Normalize(); +}; + +template +inline quaternion quatfrommat(const mat3x3 &m) +{ + T magw = m[0 ][ 0] + m[1 ][ 1] + m[2 ][ 2]; + T magxy; + T magzw; + vec3 pre; + vec3 prexy; + vec3 prezw; + quaternion postxy; + quaternion postzw; + quaternion post; + int wvsz = (magw > m[2][2] ) ; + magzw = (wvsz) ? magw : m[2][2]; + prezw = (wvsz) ? vec3(1.0f,1.0f,1.0f) : vec3(-1.0f,-1.0f,1.0f) ; + postzw = (wvsz) ? quaternion(0.0f,0.0f,0.0f,1.0f): quaternion(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(1.0f,-1.0f,-1.0f) : vec3(-1.0f,1.0f,-1.0f) ; + postxy = (xvsy) ? quaternion(1.0f,0.0f,0.0f,0.0f): quaternion(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 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 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 inline quaternion Conjugate(const quaternion &q){return quaternion(-q.x,-q.y,-q.z,q.w);} +template inline quaternion Inverse(const quaternion &q){return Conjugate(q);} +template inline quaternion normalize( const quaternion & a ){return quaternion (normalize((vec4&)a));} +template inline quaternion& operator*=(quaternion& a, T s ){return (quaternion&)((vec4&)a *=s);} +template inline quaternion operator*( const quaternion& a, float s ){return quaternion((vec4&)a*s);} +template inline quaternion operator+( const quaternion& a, const quaternion& b){return quaternion((vec4&)a+(vec4&)b);} +template inline quaternion operator-( const quaternion& a, const quaternion& b){return quaternion((vec4&)a-(vec4&)b);} +template inline quaternion operator-( const quaternion& b){return quaternion(-(vec4&)b);} +template inline quaternion operator*( const quaternion& a, const quaternion& b) +{ + return quaternion( + 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(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 +inline int maxdir(const T *p,int count,const T &dir) +{ + assert(count); + int m=0; + for(int i=1;idot(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 diff --git a/Demos3/donttouch/Bullet2GpuDemo.cpp b/Demos3/donttouch/Bullet2GpuDemo.cpp deleted file mode 100644 index 2851d2c53..000000000 --- a/Demos3/donttouch/Bullet2GpuDemo.cpp +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/Demos3/donttouch/Bullet2GpuDemo.h b/Demos3/donttouch/Bullet2GpuDemo.h deleted file mode 100644 index bef549c97..000000000 --- a/Demos3/donttouch/Bullet2GpuDemo.h +++ /dev/null @@ -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 - diff --git a/Demos3/donttouch/GpuDemo.cpp b/Demos3/donttouch/GpuDemo.cpp deleted file mode 100644 index 7f92ec67f..000000000 --- a/Demos3/donttouch/GpuDemo.cpp +++ /dev/null @@ -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 //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 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;kcalculateLocalInertia(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 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;kcalculateLocalInertia(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 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;kcalculateLocalInertia(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; - - 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 diff --git a/Demos3/donttouch/OpenGL3CoreRenderer.cpp b/Demos3/donttouch/OpenGL3CoreRenderer.cpp deleted file mode 100644 index fd8d2a874..000000000 --- a/Demos3/donttouch/OpenGL3CoreRenderer.cpp +++ /dev/null @@ -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* vertices = new b3AlignedObjectArray; - { - int numVertices = utilPtr->m_vertices.size(); - int numIndices = 0; - b3AlignedObjectArray* indicesPtr = new b3AlignedObjectArray; - for (int f=0;fm_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;jpush_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* vertexArray = new b3AlignedObjectArray; - b3AlignedObjectArray* indexArray = new b3AlignedObjectArray; - - - - //create a graphics shape for each child, combine them into a single graphics shape using their child transforms - for (int i=0;igetNumChildShapes();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;jm_numIndices;j++) - indexArray->push_back(childGfxShape->m_indices[j]+baseIndex); - - GraphicsVertex* orgVerts = (GraphicsVertex*)childGfxShape->m_vertices; - - for (int j=0;jm_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* vertices = new b3AlignedObjectArray; - b3AlignedObjectArray* indicesPtr = new b3AlignedObjectArray; - - const b3StridingMeshInterface* meshInterface = trimesh->getMeshInterface(); - - b3Vector3 trimeshScaling(1,1,1); - for (int partId=0;partIdgetNumSubParts();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* vertices = new b3AlignedObjectArray; - { -// int numVertices = obj->vertexCount; - // int numIndices = 0; - b3AlignedObjectArray* indicesPtr = new b3AlignedObjectArray; - /* - for (int v=0;vvertexCount;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;ffaceCount;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;igetWorldTransform().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;im_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;im_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(); -} - diff --git a/Demos3/donttouch/OpenGL3CoreRenderer.h b/Demos3/donttouch/OpenGL3CoreRenderer.h deleted file mode 100644 index 60a79e0c4..000000000 --- a/Demos3/donttouch/OpenGL3CoreRenderer.h +++ /dev/null @@ -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 - diff --git a/Demos3/donttouch/b3CpuDynamicsWorld.cpp b/Demos3/donttouch/b3CpuDynamicsWorld.cpp deleted file mode 100644 index 5b9ea666a..000000000 --- a/Demos3/donttouch/b3CpuDynamicsWorld.cpp +++ /dev/null @@ -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() -{ - -} diff --git a/Demos3/donttouch/b3CpuDynamicsWorld.h b/Demos3/donttouch/b3CpuDynamicsWorld.h deleted file mode 100644 index 8325da879..000000000 --- a/Demos3/donttouch/b3CpuDynamicsWorld.h +++ /dev/null @@ -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 diff --git a/Demos3/donttouch/b3GpuDynamicsWorld.cpp b/Demos3/donttouch/b3GpuDynamicsWorld.cpp deleted file mode 100644 index 70f90a33f..000000000 --- a/Demos3/donttouch/b3GpuDynamicsWorld.cpp +++ /dev/null @@ -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 -#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;im_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 tmpVertices; - tmpVertices.resize(numVertices); - for (int i=0;igetVertex(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 vertices; - b3AlignedObjectArray indices; - - b3Vector3 trimeshScaling(1,1,1); - for (int partId=0;partIdgetNumSubParts();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 childShapes; - - for (int i=0;igetNumChildShapes();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); -} - - diff --git a/Demos3/donttouch/b3GpuDynamicsWorld.h b/Demos3/donttouch/b3GpuDynamicsWorld.h deleted file mode 100644 index b4832b7a4..000000000 --- a/Demos3/donttouch/b3GpuDynamicsWorld.h +++ /dev/null @@ -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 m_uniqueShapes; - b3AlignedObjectArray 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& getCollisionObjectArray(); - - const b3AlignedObjectArray& 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 diff --git a/btgui/GwenOpenGLTest/premake4.lua b/btgui/GwenOpenGLTest/premake4.lua index 5c28f672c..fb39dcbfe 100644 --- a/btgui/GwenOpenGLTest/premake4.lua +++ b/btgui/GwenOpenGLTest/premake4.lua @@ -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", diff --git a/btgui/OpenGLWindow/GLInstancingRenderer.cpp b/btgui/OpenGLWindow/GLInstancingRenderer.cpp index 870abf403..bddd6dd5f 100644 --- a/btgui/OpenGLWindow/GLInstancingRenderer.cpp +++ b/btgui/OpenGLWindow/GLInstancingRenderer.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;im_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); diff --git a/btgui/OpenGLWindow/LoadShader.cpp b/btgui/OpenGLWindow/LoadShader.cpp index ad75cb689..aa2971337 100644 --- a/btgui/OpenGLWindow/LoadShader.cpp +++ b/btgui/OpenGLWindow/LoadShader.cpp @@ -3,7 +3,7 @@ #include #include #include -#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; } diff --git a/btgui/OpenGLWindow/SimpleOpenGL3App.cpp b/btgui/OpenGLWindow/SimpleOpenGL3App.cpp new file mode 100644 index 000000000..be0f3aa9d --- /dev/null +++ b/btgui/OpenGLWindow/SimpleOpenGL3App.cpp @@ -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(); +} \ No newline at end of file diff --git a/btgui/OpenGLWindow/SimpleOpenGL3App.h b/btgui/OpenGLWindow/SimpleOpenGL3App.h new file mode 100644 index 000000000..6cdb38413 --- /dev/null +++ b/btgui/OpenGLWindow/SimpleOpenGL3App.h @@ -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 diff --git a/btgui/OpenGLWindow/Win32OpenGLWindow.cpp b/btgui/OpenGLWindow/Win32OpenGLWindow.cpp index 76ef81de3..2a3928699 100644 --- a/btgui/OpenGLWindow/Win32OpenGLWindow.cpp +++ b/btgui/OpenGLWindow/Win32OpenGLWindow.cpp @@ -18,14 +18,14 @@ subject to the following restrictions: #include "OpenGLInclude.h" -#include "Bullet3Common/b3Vector3.h" +//#include "Bullet3Common/b3Vector3.h" #include "Win32InternalWindowData.h" #include 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); } diff --git a/btgui/OpenGLWindow/Win32Window.cpp b/btgui/OpenGLWindow/Win32Window.cpp index 72a588810..b4afe623c 100644 --- a/btgui/OpenGLWindow/Win32Window.cpp +++ b/btgui/OpenGLWindow/Win32Window.cpp @@ -17,7 +17,7 @@ subject to the following restrictions: #include "Win32Window.h" #include "OpenGLInclude.h" -#include "Bullet3Common/b3Vector3.h" + #include static InternalData2* sData = 0; diff --git a/btgui/OpenGLWindow/premake4.lua b/btgui/OpenGLWindow/premake4.lua index b50702eda..1854eb942 100644 --- a/btgui/OpenGLWindow/premake4.lua +++ b/btgui/OpenGLWindow/premake4.lua @@ -29,6 +29,8 @@ "GLInstancingRenderer.h", "GLPrimitiveRenderer.h", "GLPrimitiveRenderer.cpp", + "SimpleOpenGL3App.cpp", + "SimpleOpenGL3App.h", "LoadShader.cpp", "LoadShader.h", "gwenWindow.cpp", diff --git a/build3/premake4.lua b/build3/premake4.lua index 2147ee78e..1c803ec0d 100644 --- a/build3/premake4.lua +++ b/build3/premake4.lua @@ -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"