Init
This commit is contained in:
48
kaplademo/source/kaplaDemo/Fracture/Actor.cpp
Normal file
48
kaplademo/source/kaplaDemo/Fracture/Actor.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "Actor.h"
|
||||
|
||||
#include <foundation/PxMat44.h>
|
||||
#include "PxRigidBodyExt.h"
|
||||
#include "PxPhysics.h"
|
||||
#include "PxCooking.h"
|
||||
#include "PxShape.h"
|
||||
|
||||
#include "SimScene.h"
|
||||
#include "Compound.h"
|
||||
|
||||
Actor::Actor(base::SimScene* scene):
|
||||
base::Actor(scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Actor::~Actor()
|
||||
{
|
||||
|
||||
}
|
||||
52
kaplademo/source/kaplaDemo/Fracture/Actor.h
Normal file
52
kaplademo/source/kaplaDemo/Fracture/Actor.h
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef RT_ACTOR_H
|
||||
#define RT_ACTOR_H
|
||||
|
||||
//#include <PxFoundation.h>
|
||||
|
||||
#include "ActorBase.h"
|
||||
|
||||
class RegularCell3D;
|
||||
|
||||
using namespace physx;
|
||||
using namespace physx::fracture;
|
||||
|
||||
class Actor : public base::Actor
|
||||
{
|
||||
friend class SimScene;
|
||||
protected:
|
||||
Actor(base::SimScene* scene);
|
||||
public:
|
||||
virtual ~Actor();
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
97
kaplademo/source/kaplaDemo/Fracture/Compound.cpp
Normal file
97
kaplademo/source/kaplaDemo/Fracture/Compound.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
|
||||
#include "Mesh.h"
|
||||
#include "CompoundGeometry.h"
|
||||
#include "CompoundCreator.h"
|
||||
#include "PxConvexMeshGeometry.h"
|
||||
#include "PxRigidBodyExt.h"
|
||||
#include "foundation/PxMat44.h"
|
||||
#include "PxScene.h"
|
||||
#include "PxShape.h"
|
||||
|
||||
#include "SimScene.h"
|
||||
#include "Compound.h"
|
||||
#include "Convex.h"
|
||||
#include "foundation/PxMathUtils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MathUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define CREATE_DEBRIS 1
|
||||
|
||||
float Compound::getSleepingThresholdRB()
|
||||
{
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::draw(bool useShader, bool debug)
|
||||
{
|
||||
if (useShader && mShader)
|
||||
mShader->activate(mShaderMat);
|
||||
else {
|
||||
glColor3f(mShaderMat.color[0], mShaderMat.color[1], mShaderMat.color[2]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++)
|
||||
mConvexes[i]->draw(debug);
|
||||
|
||||
if (useShader && mShader)
|
||||
mShader->deactivate();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::clear()
|
||||
{
|
||||
base::Compound::clear();
|
||||
|
||||
mShader = NULL;
|
||||
mShaderMat.init();
|
||||
}
|
||||
|
||||
void Compound::copyShaders(base::Compound* m)
|
||||
{
|
||||
((Compound*)m)->mShader = mShader;
|
||||
((Compound*)m)->mShaderMat = mShaderMat;
|
||||
}
|
||||
|
||||
void Compound::convexAdded(base::Convex* c, Shader* shader)
|
||||
{
|
||||
((SimScene*)mScene)->getConvexRenderer().add(c, shader);
|
||||
}
|
||||
|
||||
void Compound::convexRemoved(base::Convex* c)
|
||||
{
|
||||
((SimScene*)mScene)->getConvexRenderer().remove(c);
|
||||
}
|
||||
86
kaplademo/source/kaplaDemo/Fracture/Compound.h
Normal file
86
kaplademo/source/kaplaDemo/Fracture/Compound.h
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef COMPOUND
|
||||
#define COMPOUND
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxPlane.h>
|
||||
#include <foundation/PxBounds3.h>
|
||||
#include <foundation/PxTransform.h>
|
||||
#include <PsArray.h>
|
||||
#include <PxRigidDynamic.h>
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
#include "CompoundBase.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class Convex;
|
||||
class Particles;
|
||||
class Mesh;
|
||||
class SimScene;
|
||||
class CompoundGeometry;
|
||||
class XMLParser;
|
||||
|
||||
class ShaderShadow;
|
||||
|
||||
using namespace physx::fracture;
|
||||
|
||||
class Compound : public base::Compound
|
||||
{
|
||||
friend class SimScene;
|
||||
protected:
|
||||
Compound(SimScene* scene, PxReal contactOffset = 0.005f, PxReal restOffset = -0.001f):
|
||||
physx::fracture::base::Compound((base::SimScene*)scene,contactOffset,restOffset) {}
|
||||
public:
|
||||
|
||||
virtual void convexAdded(base::Convex* c, Shader* shader);
|
||||
virtual void convexRemoved(base::Convex* c);
|
||||
|
||||
bool createFromXml(XMLParser *p, float scale, const PxTransform &trans, bool ignoreVisualMesh = false);
|
||||
|
||||
void setShader(Shader* shader, const ShaderMaterial &mat) { mShader = shader; mShaderMat = mat; }
|
||||
Shader* getShader() const { return mShader; }
|
||||
const ShaderMaterial& getShaderMat() { return mShaderMat; }
|
||||
|
||||
virtual void draw(bool useShader, bool debug = false);
|
||||
|
||||
virtual void clear();
|
||||
|
||||
virtual void copyShaders(base::Compound*);
|
||||
|
||||
protected:
|
||||
|
||||
virtual float getSleepingThresholdRB();
|
||||
|
||||
Shader *mShader;
|
||||
ShaderMaterial mShaderMat;
|
||||
};
|
||||
|
||||
#endif
|
||||
65
kaplademo/source/kaplaDemo/Fracture/CompoundCreator.cpp
Normal file
65
kaplademo/source/kaplaDemo/Fracture/CompoundCreator.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "CompoundCreator.h"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include "CompoundGeometry.h"
|
||||
|
||||
#define DEBUG_DRAW 1
|
||||
|
||||
#if DEBUG_DRAW
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::debugDraw()
|
||||
{
|
||||
#if DEBUG_DRAW
|
||||
|
||||
const bool drawEdges = false;
|
||||
|
||||
if (drawEdges) {
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < (int)mTetEdges.size(); i++) {
|
||||
TetEdge &e = mTetEdges[i];
|
||||
if (e.onSurface)
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
else
|
||||
glColor3f(1.0f, 1.0f, 0.0f);
|
||||
|
||||
PxVec3 &p0 = mTetVertices[e.i0];
|
||||
PxVec3 &p1 = mTetVertices[e.i1];
|
||||
glVertex3f(p0.x, p0.y, p0.z);
|
||||
glVertex3f(p1.x, p1.y, p1.z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
48
kaplademo/source/kaplaDemo/Fracture/CompoundCreator.h
Normal file
48
kaplademo/source/kaplaDemo/Fracture/CompoundCreator.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef COMPOUND_CREATOR_H
|
||||
#define COMPOUND_CREATOR_H
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxTransform.h>
|
||||
#include <PsArray.h>
|
||||
|
||||
#include "CompoundCreatorBase.h"
|
||||
|
||||
using namespace physx::fracture;
|
||||
|
||||
class CompoundCreator : public base::CompoundCreator
|
||||
{
|
||||
friend class SimScene;
|
||||
public:
|
||||
virtual void debugDraw();
|
||||
protected:
|
||||
CompoundCreator(SimScene* scene): base::CompoundCreator((base::SimScene*)scene) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
102
kaplademo/source/kaplaDemo/Fracture/CompoundGeometry.cpp
Normal file
102
kaplademo/source/kaplaDemo/Fracture/CompoundGeometry.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "CompoundGeometry.h"
|
||||
|
||||
#define DEBUG_DRAW 1
|
||||
|
||||
#if DEBUG_DRAW
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
void CompoundGeometry::debugDraw(int maxConvexes) const
|
||||
{
|
||||
#if DEBUG_DRAW
|
||||
const bool drawConvexes = true;
|
||||
const bool drawWireframe = true;
|
||||
const bool drawClipped = false;
|
||||
const float clipMaxX = 0.0f;
|
||||
|
||||
if (drawConvexes) {
|
||||
float s = drawClipped ? 1.0f : 0.95f;
|
||||
|
||||
if (drawWireframe)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
PxVec3 n;
|
||||
int num = convexes.size();
|
||||
if (maxConvexes > 0 && maxConvexes < num)
|
||||
num = maxConvexes;
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
|
||||
switch (i%7) {
|
||||
case 0 : glColor3f(1.0f, 0.0f, 0.0f); break;
|
||||
case 1 : glColor3f(0.0f, 1.0f, 0.0f); break;
|
||||
case 2 : glColor3f(1.0f, 0.0f, 1.0f); break;
|
||||
case 3 : glColor3f(0.0f, 1.0f, 1.0f); break;
|
||||
case 4 : glColor3f(1.0f, 0.0f, 1.0f); break;
|
||||
case 5 : glColor3f(1.0f, 1.0f, 0.0f); break;
|
||||
case 6 : glColor3f(1.0f, 1.0f, 1.0f); break;
|
||||
};
|
||||
|
||||
const Convex &c = convexes[i];
|
||||
const PxVec3 *verts = &vertices[c.firstVert];
|
||||
PxVec3 center;
|
||||
center = PxVec3(0.0f, 0.0f, 0.0f);
|
||||
for (int j = 0; j < c.numVerts; j++)
|
||||
center += verts[j];
|
||||
center /= (float)c.numVerts;
|
||||
if (drawClipped && center.x > clipMaxX)
|
||||
continue;
|
||||
|
||||
const int *ids = &indices[c.firstIndex];
|
||||
for (int j = 0; j < c.numFaces; j++) {
|
||||
int numVerts = *ids++;
|
||||
int flags = *ids++;
|
||||
|
||||
n = (verts[ids[1]] - verts[ids[0]]).cross(verts[ids[2]] - verts[ids[0]]);
|
||||
n.normalize();
|
||||
glNormal3f(n.x, n.y, n.z);
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
for (int k = 0; k < numVerts; k++) {
|
||||
PxVec3 p = verts[ids[k]];
|
||||
p = center + (p - center) * s;
|
||||
glVertex3f(p.x, p.y, p.z);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
ids += numVerts;
|
||||
}
|
||||
}
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
45
kaplademo/source/kaplaDemo/Fracture/CompoundGeometry.h
Normal file
45
kaplademo/source/kaplaDemo/Fracture/CompoundGeometry.h
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef COMPOUND_GEOMETRY
|
||||
#define COMPOUND_GEOMETRY
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxPlane.h>
|
||||
#include <PsArray.h>
|
||||
|
||||
#include "CompoundGeometryBase.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class CompoundGeometry : public physx::fracture::base::CompoundGeometry
|
||||
{
|
||||
public:
|
||||
virtual void debugDraw(int maxConvexes = 0) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
276
kaplademo/source/kaplaDemo/Fracture/Convex.cpp
Normal file
276
kaplademo/source/kaplaDemo/Fracture/Convex.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "PxPhysics.h"
|
||||
#include "PxCooking.h"
|
||||
#include "PxDefaultStreams.h"
|
||||
#include "PxShape.h"
|
||||
#include "foundation/PxMath.h"
|
||||
#include "PxRigidDynamic.h"
|
||||
#include "PxConvexMesh.h"
|
||||
#include "foundation/PxMat44.h"
|
||||
#include "foundation/PxMathUtils.h"
|
||||
|
||||
#include "CompoundGeometry.h"
|
||||
#include "Shader.h"
|
||||
#include "PolygonTriangulator.h"
|
||||
|
||||
#include "Convex.h"
|
||||
|
||||
#include "PhysXMacros.h"
|
||||
|
||||
class physx::PxPhysics;
|
||||
class physx::PxCooking;
|
||||
class physx::PxActor;
|
||||
class physx::PxScene;
|
||||
class physx::PxConvexMesh;
|
||||
|
||||
#define COOK_TRIANGLES 0
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Convex::draw(bool debug)
|
||||
{
|
||||
//if (!mIsGhostConvex)
|
||||
// return; // foo
|
||||
|
||||
bool drawConvex = true;
|
||||
bool drawVisMesh = true;
|
||||
bool wireframe = false;
|
||||
bool drawWorldBounds = false;
|
||||
bool drawInsideTest = false;
|
||||
bool drawVisPolys = true;
|
||||
bool drawTangents = false;
|
||||
bool drawNewFlag = false;
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.0f, 1.0f);
|
||||
|
||||
if (!debug) {
|
||||
drawConvex = false;
|
||||
drawVisMesh = true;
|
||||
wireframe = false;
|
||||
drawWorldBounds = false;
|
||||
drawInsideTest = false;
|
||||
drawVisPolys = false;
|
||||
drawTangents = false;
|
||||
}
|
||||
|
||||
if (drawConvex) {
|
||||
if (mHasExplicitVisMesh)
|
||||
glColor3f(0.0f, 0.0f, 1.0f);
|
||||
else if (mIsGhostConvex)
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
else
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_LIGHTING);
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
PxMat44 mat(getGlobalPose());
|
||||
glMultMatrixf((GLfloat*)mat.front());
|
||||
}
|
||||
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < (int)mFaces.size(); i++) {
|
||||
Face &f = mFaces[i];
|
||||
for (int j = 0; j < f.numIndices; j++) {
|
||||
PxVec3 &p0 = mVertices[mIndices[f.firstIndex + j]];
|
||||
PxVec3 &p1 = mVertices[mIndices[f.firstIndex + (j+1)%f.numIndices]];
|
||||
glVertex3f(p0.x, p0.y, p0.z);
|
||||
glVertex3f(p1.x, p1.y, p1.z);
|
||||
}
|
||||
|
||||
if (drawNewFlag && (f.flags & CompoundGeometry::FF_NEW) && f.numIndices > 0) {
|
||||
float r = 0.01f;
|
||||
|
||||
PxVec3 c(0.0f, 0.0f, 0.0f);
|
||||
for (int j = 0; j < f.numIndices; j++)
|
||||
c += mVertices[mIndices[f.firstIndex + j]];
|
||||
c /= (float)f.numIndices;
|
||||
glVertex3f(c.x - r, c.y, c.z); glVertex3f(c.x + r, c.y, c.z);
|
||||
glVertex3f(c.x, c.y - r, c.z); glVertex3f(c.x, c.y + r, c.z);
|
||||
glVertex3f(c.x, c.y, c.z - r); glVertex3f(c.x, c.y, c.z + r);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
if (mVisVertices.empty())
|
||||
return;
|
||||
|
||||
if (drawVisPolys) {
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
PxMat44 mat(getGlobalPose());
|
||||
glMultMatrixf((GLfloat*)mat.front());
|
||||
}
|
||||
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
glDisable(GL_LIGHTING);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < (int)mVisPolyStarts.size()-1; i++) {
|
||||
int first = mVisPolyStarts[i];
|
||||
int num = mVisPolyStarts[i+1] - first;
|
||||
|
||||
for (int j = 0; j < num; j++) {
|
||||
PxVec3 &p0 = mVisVertices[mVisPolyIndices[first + j]];
|
||||
PxVec3 &p1 = mVisVertices[mVisPolyIndices[first + (j+1)%num]];
|
||||
glVertex3f(p0.x, p0.y, p0.z);
|
||||
glVertex3f(p1.x, p1.y, p1.z);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
if (drawTangents) {
|
||||
const float r = 0.1f;
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
PxMat44 mat(getGlobalPose());
|
||||
glMultMatrixf((GLfloat*)mat.front());
|
||||
}
|
||||
|
||||
glColor3f(1.0f, 1.0f, 0.0f);
|
||||
glDisable(GL_LIGHTING);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < (int)mVisVertices.size()-1; i++) {
|
||||
PxVec3 p0 = mVisVertices[i];
|
||||
PxVec3 p1 = p0 + r * mVisTangents[i];
|
||||
glVertex3f(p0.x, p0.y, p0.z);
|
||||
glVertex3f(p1.x, p1.y, p1.z);
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
if (drawVisMesh && mVisTriIndices.size() > 0) {
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
PxMat44 mat(getGlobalPose());
|
||||
glMultMatrixf((GLfloat*)mat.front());
|
||||
}
|
||||
|
||||
if (wireframe) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, &mVisVertices[0]);
|
||||
glNormalPointer(GL_FLOAT, sizeof(PxVec3), &mVisNormals[0]);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, mVisTriIndices.size(), GL_UNSIGNED_INT, &mVisTriIndices[0]);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
if (mPxActor != NULL) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
if (wireframe) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (drawWorldBounds) {
|
||||
static const int corners[12 * 2][3] = {
|
||||
{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}, {0,1,1}, {1,1,1}, {0,0,1}, {1,0,1},
|
||||
{0,0,0}, {0,1,0}, {1,0,0}, {1,1,0}, {1,0,1}, {1,1,1}, {0,0,1}, {0,1,1},
|
||||
{0,0,0}, {0,0,1}, {1,0,0}, {1,0,1}, {1,1,0}, {1,1,1}, {0,1,0}, {0,1,1}};
|
||||
PxBounds3 b;
|
||||
getWorldBounds(b);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < 24; i++) {
|
||||
glVertex3f(
|
||||
corners[i][0] ? b.minimum.x : b.maximum.x,
|
||||
corners[i][1] ? b.minimum.y : b.maximum.y,
|
||||
corners[i][2] ? b.minimum.z : b.maximum.z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
if (drawInsideTest) {
|
||||
PxBounds3 bounds;
|
||||
bounds.setEmpty();
|
||||
for (int i = 0; i < (int)mVertices.size(); i++)
|
||||
bounds.include(mVertices[i]);
|
||||
|
||||
int num = 20;
|
||||
float r = 0.05f * bounds.getDimensions().magnitude() / (float)num;
|
||||
PxVec3 p;
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
glBegin(GL_LINES);
|
||||
for (int xi = 0; xi < num; xi++) {
|
||||
for (int yi = 0; yi < num; yi++) {
|
||||
for (int zi = 0; zi < num; zi++) {
|
||||
p.x = bounds.minimum.x + xi * (bounds.maximum.x - bounds.minimum.x)/num;
|
||||
p.y = bounds.minimum.y + yi * (bounds.maximum.y - bounds.minimum.y)/num;
|
||||
p.z = bounds.minimum.z + zi * (bounds.maximum.z - bounds.minimum.z)/num;
|
||||
if (insideVisualMesh(p)) {
|
||||
glVertex3f(p.x - r, p.y, p.z); glVertex3f(p.x + r, p.y, p.z);
|
||||
glVertex3f(p.x, p.y - r, p.z); glVertex3f(p.x, p.y + r, p.z);
|
||||
glVertex3f(p.x, p.y, p.z - r); glVertex3f(p.x, p.y, p.z + r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
65
kaplademo/source/kaplaDemo/Fracture/Convex.h
Normal file
65
kaplademo/source/kaplaDemo/Fracture/Convex.h
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef CONVEX
|
||||
#define CONVEX
|
||||
|
||||
#include <PxPhysics.h>
|
||||
#include <PxCooking.h>
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxPlane.h>
|
||||
#include <foundation/PxBounds3.h>
|
||||
#include <foundation/PxTransform.h>
|
||||
#include <PsArray.h>
|
||||
|
||||
#include "ConvexBase.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class physx::PxShape;
|
||||
class physx::PxActor;
|
||||
class physx::PxScene;
|
||||
class physx::PxConvexMesh;
|
||||
|
||||
class Compound;
|
||||
class CompoundGeometry;
|
||||
|
||||
|
||||
using namespace physx::fracture;
|
||||
|
||||
class Convex : public base::Convex
|
||||
{
|
||||
friend class SimScene;
|
||||
protected:
|
||||
Convex(base::SimScene* scene): base::Convex(scene) {}
|
||||
public:
|
||||
|
||||
virtual void draw(bool debug = false);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
403
kaplademo/source/kaplaDemo/Fracture/ConvexRenderer.cpp
Normal file
403
kaplademo/source/kaplaDemo/Fracture/ConvexRenderer.cpp
Normal file
@ -0,0 +1,403 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "Shader.h"
|
||||
#include "ConvexRenderer.h"
|
||||
#include "Compound.h"
|
||||
#include <foundation/PxMat44.h>
|
||||
|
||||
//--------------------------------------------------------
|
||||
ConvexRenderer::ConvexRenderer()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
ConvexRenderer::~ConvexRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
void ConvexRenderer::init()
|
||||
{
|
||||
mShader = NULL;
|
||||
mShaderMat.init();
|
||||
|
||||
mBumpTextureUVScale = 0.1f;
|
||||
mExtraNoiseScale = 2.0f;
|
||||
mRoughnessScale = 0.2f;
|
||||
|
||||
mDiffuseTexArray = 0;
|
||||
mBumpTexArray = 0;
|
||||
mSpecularTexArray = 0;
|
||||
mEmissiveReflectSpecPowerTexArray = 0;
|
||||
|
||||
mActive = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
void ConvexRenderer::add(const base::Convex* convex, Shader* shader)
|
||||
{
|
||||
if (!mActive)
|
||||
return;
|
||||
|
||||
ConvexGroup *g;
|
||||
|
||||
// int gnr = 0; // to search all groups
|
||||
int gnr = 0;// !mGroups.empty() ? mGroups.size() - 1 : 0; // to search only last
|
||||
int numNewVerts = convex->getVisVertices().size();
|
||||
|
||||
while (gnr < (int)mGroups.size() && (mGroups[gnr]->numVertices + numNewVerts >= maxVertsPerGroup || mGroups[gnr]->mShader != shader))
|
||||
gnr++;
|
||||
|
||||
if (gnr == (int)mGroups.size()) { // create new group
|
||||
g = new ConvexGroup();
|
||||
g->init();
|
||||
g->mShader = shader;
|
||||
gnr = mGroups.size();
|
||||
mGroups.push_back(g);
|
||||
}
|
||||
g = mGroups[gnr];
|
||||
convex->setConvexRendererInfo(gnr, g->convexes.size());
|
||||
g->convexes.push_back((Convex*)convex);
|
||||
g->numIndices += convex->getVisTriIndices().size();
|
||||
g->numVertices += convex->getVisVertices().size();
|
||||
g->dirty = true;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
void ConvexRenderer::remove(const base::Convex* convex)
|
||||
{
|
||||
if (!mActive)
|
||||
return;
|
||||
|
||||
int gnr = convex->getConvexRendererGroupNr();
|
||||
int pos = convex->getConvexRendererGroupPos();
|
||||
if (gnr < 0 || gnr >= (int)mGroups.size())
|
||||
return;
|
||||
|
||||
ConvexGroup *g = mGroups[gnr];
|
||||
if (pos < 0 || pos > (int)g->convexes.size())
|
||||
return;
|
||||
|
||||
if (g->convexes[pos] != convex)
|
||||
return;
|
||||
|
||||
g->numIndices -= convex->getVisTriIndices().size();
|
||||
g->numVertices -= convex->getVisVertices().size();
|
||||
|
||||
g->convexes[pos] = g->convexes[g->convexes.size()-1];
|
||||
g->convexes[pos]->setConvexRendererInfo(gnr, pos);
|
||||
g->convexes.pop_back();
|
||||
g->dirty = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
void ConvexRenderer::updateRenderBuffers()
|
||||
{
|
||||
/*
|
||||
static int maxNumV = 0;
|
||||
static int maxNumI = 0;
|
||||
static int maxNumC = 0;
|
||||
static int maxNumG = 0;
|
||||
if (mGroups.size() > maxNumG) maxNumG = mGroups.size();
|
||||
*/
|
||||
|
||||
for (int i = 0; i < (int)mGroups.size(); i++) {
|
||||
|
||||
|
||||
ConvexGroup *g = mGroups[i];
|
||||
if (!g->dirty)
|
||||
continue;
|
||||
|
||||
if (g->numIndices == 0 || g->numVertices == 0)
|
||||
continue;
|
||||
|
||||
if (!g->VBO) {
|
||||
glGenBuffersARB(1, &g->VBO);
|
||||
}
|
||||
if (!g->IBO) {
|
||||
glGenBuffersARB(1, &g->IBO);
|
||||
}
|
||||
if (!g->matTex) {
|
||||
glGenTextures(1, &g->matTex);
|
||||
glBindTexture(GL_TEXTURE_2D, g->matTex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
}
|
||||
if (g->numVertices == 0 || g->numIndices == 0)
|
||||
return;
|
||||
|
||||
// recalculate in case they have changed
|
||||
g->numVertices = 0;
|
||||
g->numIndices = 0;
|
||||
for (int i = 0; i < (int)g->convexes.size(); i++) {
|
||||
g->numVertices += g->convexes[i]->getVisVertices().size();
|
||||
g->numIndices += g->convexes[i]->getVisTriIndices().size();
|
||||
}
|
||||
|
||||
g->vertices.resize(g->numVertices*12);
|
||||
g->indices.resize(g->numIndices);
|
||||
float* vp = &g->vertices[0];
|
||||
unsigned int* ip = &g->indices[0];
|
||||
|
||||
int sumV = 0;
|
||||
// Make cpu copy of VBO and IBO
|
||||
|
||||
int convexNr = 0;
|
||||
for (int j = 0; j < (int)g->convexes.size(); j++, convexNr++) {
|
||||
const Convex* c = g->convexes[j];
|
||||
// PxVec3 matOff = c->getMaterialOffset();
|
||||
|
||||
int nv = c->getVisVertices().size();
|
||||
int ni = c->getVisTriIndices().size();
|
||||
|
||||
if (nv > 0) {
|
||||
float* cvp = (float*)&c->getVisVertices()[0]; // float3
|
||||
float* cnp = (float*)&c->getVisNormals()[0]; // float3
|
||||
// float* c3dtp = (float*)&c->getVisVertices()[0]; // float3
|
||||
float* c2dtp = (float*)&c->getVisTexCoords()[0]; // float2
|
||||
float* ctanp = (float*)&c->getVisTangents()[0]; // float3
|
||||
|
||||
int* cip = (int*)&c->getVisTriIndices()[0];
|
||||
for (int k = 0; k < nv; k++) {
|
||||
*(vp++) = *(cvp++);
|
||||
*(vp++) = *(cvp++);
|
||||
*(vp++) = *(cvp++);
|
||||
|
||||
*(vp++) = *(cnp++);
|
||||
*(vp++) = *(cnp++);
|
||||
*(vp++) = *(cnp++);
|
||||
|
||||
*(vp++) = *(ctanp++);
|
||||
*(vp++) = *(ctanp++);
|
||||
*(vp++) = *(ctanp++);
|
||||
*(vp++) = (float)convexNr;
|
||||
|
||||
*(vp++) = *(c2dtp++);
|
||||
*(vp++) = *(c2dtp++);
|
||||
|
||||
}
|
||||
for (int k = 0; k < ni; k++) {
|
||||
*(ip++) = *(cip++) + sumV;
|
||||
}
|
||||
}
|
||||
//memcpy(ip, cip, sizeof(int)*ni);
|
||||
//ip += 3*ni;
|
||||
|
||||
//std::vector<PxVec3> mTriVertices;
|
||||
//std::vector<PxVec3> mTriNormals;
|
||||
//std::vector<int> mTriIndices;
|
||||
//std::vector<float> mTriTexCoords; // 3d + obj nr
|
||||
sumV += nv;
|
||||
}
|
||||
/*
|
||||
if (g->vertices.size() > maxNumV) maxNumV = g->vertices.size();
|
||||
if (g->indices.size() > maxNumI) maxNumI = g->indices.size();
|
||||
if (g->convexes.size() > maxNumC) maxNumC = g->convexes.size();
|
||||
*/
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, g->VBO);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, g->vertices.size()*sizeof(float), &g->vertices[0], GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, g->IBO);
|
||||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, g->indices.size()*sizeof(unsigned int), &g->indices[0], GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
int oldTexSize = g->texSize;
|
||||
if (g->texSize == 0) {
|
||||
// First time
|
||||
oldTexSize = 1;
|
||||
g->texSize = 32;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int convexesPerRow = g->texSize / 4;
|
||||
if (convexesPerRow * g->texSize >= (int)g->convexes.size()) {
|
||||
break;
|
||||
} else {
|
||||
g->texSize *= 2;
|
||||
}
|
||||
}
|
||||
if (g->texSize != oldTexSize) {
|
||||
g->texCoords.resize(g->texSize*g->texSize*4);
|
||||
// Let's allocate texture
|
||||
glBindTexture(GL_TEXTURE_2D, g->matTex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, g->texSize, g->texSize, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
g->dirty = false;
|
||||
}
|
||||
|
||||
// printf("maxV = %d, maxI = %d, maxC = %d, maxG = %d\n", maxNumV, maxNumI, maxNumC, maxNumG);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
void ConvexRenderer::updateTransformations()
|
||||
{
|
||||
for (int i = 0; i < (int)mGroups.size(); i++) {
|
||||
ConvexGroup *g = mGroups[i];
|
||||
if (g->texCoords.empty())
|
||||
continue;
|
||||
|
||||
float* tt = &g->texCoords[0];
|
||||
|
||||
for (int j = 0; j < (int)g->convexes.size(); j++) {
|
||||
const Convex* c = g->convexes[j];
|
||||
|
||||
PxMat44 pose(c->getGlobalPose());
|
||||
float* mp = (float*)pose.front();
|
||||
|
||||
float* ta = tt;
|
||||
for (int k = 0; k < 16; k++) {
|
||||
*(tt++) = *(mp++);
|
||||
}
|
||||
PxVec3 matOff = c->getMaterialOffset();
|
||||
ta[3] = matOff.x;
|
||||
ta[7] = matOff.y;
|
||||
ta[11] = matOff.z;
|
||||
|
||||
int idFor2DTex = c->getSurfaceMaterialId();
|
||||
int idFor3DTex = c->getMaterialId();
|
||||
const int MAX_3D_TEX = 8;
|
||||
ta[15] = (float)(idFor2DTex*MAX_3D_TEX + idFor3DTex);
|
||||
|
||||
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, g->matTex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g->texSize, g->texSize,
|
||||
GL_RGBA, GL_FLOAT, &g->texCoords[0]);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
void ConvexRenderer::render()
|
||||
{
|
||||
if (!mActive)
|
||||
return;
|
||||
|
||||
updateRenderBuffers();
|
||||
|
||||
updateTransformations();
|
||||
|
||||
for (int i = 0; i < (int)mGroups.size(); i++) {
|
||||
|
||||
ConvexGroup *g = mGroups[i];
|
||||
|
||||
Shader* shader = mShader;
|
||||
if (g->mShader != NULL)
|
||||
shader = g->mShader;
|
||||
|
||||
shader->activate(mShaderMat);
|
||||
// Assume convex all use the same shader
|
||||
|
||||
glActiveTexture(GL_TEXTURE7);
|
||||
glBindTexture(GL_TEXTURE_3D, volTex);
|
||||
|
||||
glActiveTexture(GL_TEXTURE8);
|
||||
glBindTexture(GL_TEXTURE_2D, g->matTex);
|
||||
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mDiffuseTexArray);
|
||||
glActiveTexture(GL_TEXTURE11);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mBumpTexArray);
|
||||
glActiveTexture(GL_TEXTURE12);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mSpecularTexArray);
|
||||
glActiveTexture(GL_TEXTURE13);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, mEmissiveReflectSpecPowerTexArray);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float itt = 1.0f/g->texSize;
|
||||
|
||||
shader->setUniform("diffuseTexArray", 10);
|
||||
shader->setUniform("bumpTexArray", 11);
|
||||
shader->setUniform("specularTexArray", 12);
|
||||
shader->setUniform("emissiveReflectSpecPowerTexArray", 13);
|
||||
|
||||
shader->setUniform("ttt3D", 7);
|
||||
shader->setUniform("transTex", 8);
|
||||
shader->setUniform("transTexSize", g->texSize);
|
||||
shader->setUniform("iTransTexSize", itt);
|
||||
shader->setUniform("bumpTextureUVScale", mBumpTextureUVScale);
|
||||
shader->setUniform("extraNoiseScale", mExtraNoiseScale);
|
||||
shader->setUniform("roughnessScale", mRoughnessScale);
|
||||
|
||||
if (mShaderMat.color[3] < 1.0f) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glColor4f(mShaderMat.color[0], mShaderMat.color[1], mShaderMat.color[2], mShaderMat.color[3]);
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, g->VBO);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, g->IBO);
|
||||
|
||||
int stride = 12*sizeof(float);
|
||||
glVertexPointer(3, GL_FLOAT, stride, 0);
|
||||
|
||||
glNormalPointer(GL_FLOAT, stride, (void*)(3*sizeof(float)));
|
||||
|
||||
glTexCoordPointer(4, GL_FLOAT, stride, (void*)(6*sizeof(float)));
|
||||
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, (void*)(10*sizeof(float)));
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, g->numIndices, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
if (mShaderMat.color[3] < 1.0f) {
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
shader->deactivate();
|
||||
}
|
||||
}
|
||||
104
kaplademo/source/kaplaDemo/Fracture/ConvexRenderer.h
Normal file
104
kaplademo/source/kaplaDemo/Fracture/ConvexRenderer.h
Normal file
@ -0,0 +1,104 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef CONVEX_RENDERER
|
||||
#define CONVEX_RENDERER
|
||||
|
||||
#include "Convex.h"
|
||||
#include <vector>
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class Shader;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
class ConvexRenderer
|
||||
{
|
||||
public:
|
||||
ConvexRenderer();
|
||||
~ConvexRenderer();
|
||||
|
||||
void init();
|
||||
|
||||
const static int maxVertsPerGroup = 100000;
|
||||
|
||||
void setActive(bool active) { mActive = active; };
|
||||
|
||||
void add(const base::Convex* convex, Shader* shader);
|
||||
void remove(const base::Convex* convex);
|
||||
|
||||
void render();
|
||||
void setShaderMaterial(Shader* shader, const ShaderMaterial& mat) {this->mShader = shader; this->mShaderMat = mat;}
|
||||
void setTexArrays(unsigned int diffuse, unsigned int bump, unsigned int specular, unsigned int specPower) {
|
||||
mDiffuseTexArray = diffuse; mBumpTexArray = bump;
|
||||
mSpecularTexArray = specular; mEmissiveReflectSpecPowerTexArray = specPower; }
|
||||
void setVolTex(unsigned int volTexi) { volTex = volTexi;}
|
||||
private:
|
||||
void updateRenderBuffers();
|
||||
void updateTransformations();
|
||||
|
||||
Shader* mShader;
|
||||
ShaderMaterial mShaderMat;
|
||||
|
||||
struct ConvexGroup {
|
||||
void init() {
|
||||
numVertices = 0; numIndices = 0;
|
||||
VBO = 0; IBO = 0; matTex = 0;
|
||||
texSize = 0;
|
||||
}
|
||||
bool dirty;
|
||||
std::vector<const Convex*> convexes;
|
||||
|
||||
std::vector<float> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<float> texCoords;
|
||||
|
||||
int numVertices, numIndices;
|
||||
unsigned int VBO;
|
||||
unsigned int IBO;
|
||||
unsigned int matTex;
|
||||
int texSize;
|
||||
|
||||
Shader* mShader;
|
||||
};
|
||||
|
||||
std::vector<ConvexGroup*> mGroups;
|
||||
|
||||
bool mActive;
|
||||
|
||||
float mBumpTextureUVScale;
|
||||
float mExtraNoiseScale;
|
||||
float mRoughnessScale;
|
||||
|
||||
unsigned int mDiffuseTexArray;
|
||||
unsigned int mBumpTexArray;
|
||||
unsigned int mSpecularTexArray;
|
||||
unsigned int mEmissiveReflectSpecPowerTexArray;
|
||||
unsigned int volTex;
|
||||
};
|
||||
|
||||
#endif
|
||||
166
kaplademo/source/kaplaDemo/Fracture/Core/ActorBase.cpp
Normal file
166
kaplademo/source/kaplaDemo/Fracture/Core/ActorBase.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include "ActorBase.h"
|
||||
|
||||
#include <foundation/PxMat44.h>
|
||||
#include "PxRigidBodyExt.h"
|
||||
|
||||
#include "PxScene.h"
|
||||
#include "SimSceneBase.h"
|
||||
#include "CompoundBase.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
Actor::Actor(SimScene* scene):
|
||||
mScene(scene),
|
||||
mMinConvexSize(scene->mMinConvexSize),
|
||||
mDepthLimit(100),
|
||||
mDestroyIfAtDepthLimit(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Actor::~Actor()
|
||||
{
|
||||
mScene->getScene()->lockWrite();
|
||||
clear();
|
||||
mScene->getScene()->unlockWrite();
|
||||
mScene->removeActor(this);
|
||||
}
|
||||
|
||||
void Actor::clear()
|
||||
{
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
PX_DELETE(mCompounds[i]);
|
||||
}
|
||||
mCompounds.clear();
|
||||
}
|
||||
|
||||
void Actor::addCompound(Compound *c)
|
||||
{
|
||||
mCompounds.pushBack(c);
|
||||
PxRigidDynamic *a = c->getPxActor();
|
||||
#if 1
|
||||
if (a) {
|
||||
// a->setContactReportFlags(Px_NOTIFY_ON_TOUCH_FORCE_THRESHOLD | Px_NOTIFY_ON_START_TOUCH_FORCE_THRESHOLD);
|
||||
a->setContactReportThreshold(mScene->mFractureForceThreshold);
|
||||
}
|
||||
#endif
|
||||
c->mActor = this;
|
||||
++(mScene->mSceneVersion);
|
||||
}
|
||||
|
||||
void Actor::removeCompound(Compound *c)
|
||||
{
|
||||
int num = 0;
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
if (mCompounds[i] != c) {
|
||||
mCompounds[num] = mCompounds[i];
|
||||
num++;
|
||||
}
|
||||
}
|
||||
if (mScene->mPickActor == c->getPxActor())
|
||||
mScene->mPickActor = NULL;
|
||||
|
||||
c->clear();
|
||||
//delCompoundList.push_back(c);
|
||||
//delete c;
|
||||
mScene->delCompoundList.pushBack(c);
|
||||
mCompounds.resize(num);
|
||||
++mScene->mSceneVersion;
|
||||
}
|
||||
|
||||
void Actor::preSim(float dt)
|
||||
{
|
||||
int num = 0;
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
mCompounds[i]->step(dt);
|
||||
if (mCompounds[i]->getLifeFrames() == 0) {
|
||||
mCompounds[i]->clear();
|
||||
//delCompoundList.push_back(mCompounds[i]);
|
||||
//delete mCompounds[i];
|
||||
mScene->delCompoundList.pushBack(mCompounds[i]);
|
||||
}
|
||||
else {
|
||||
mCompounds[num] = mCompounds[i];
|
||||
num++;
|
||||
}
|
||||
}
|
||||
mCompounds.resize(num);
|
||||
}
|
||||
|
||||
void Actor::postSim(float /*dt*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool Actor::rayCast(const PxVec3 &orig, const PxVec3 &dir, float &dist, int &compoundNr, int &convexNr, PxVec3 &normal) const
|
||||
{
|
||||
dist = PX_MAX_F32;
|
||||
compoundNr = -1;
|
||||
convexNr = -1;
|
||||
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
float d;
|
||||
int cNr;
|
||||
PxVec3 n;
|
||||
if (mCompounds[i]->rayCast(orig, dir, d, cNr, n)) {
|
||||
if (d < dist) {
|
||||
dist = d;
|
||||
compoundNr = i;
|
||||
convexNr = cNr;
|
||||
normal = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
return compoundNr >= 0;
|
||||
}
|
||||
|
||||
bool Actor::findCompound(const Compound* c, int& compoundNr)
|
||||
{
|
||||
for(int i = 0; i < (int)mCompounds.size(); i++)
|
||||
{
|
||||
if(mCompounds[i] == c)
|
||||
{
|
||||
compoundNr = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
81
kaplademo/source/kaplaDemo/Fracture/Core/ActorBase.h
Normal file
81
kaplademo/source/kaplaDemo/Fracture/Core/ActorBase.h
Normal file
@ -0,0 +1,81 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef ACTOR_BASE_H
|
||||
#define ACTOR_BASE_H
|
||||
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
class Compound;
|
||||
|
||||
class Actor : public ::physx::shdfnd::UserAllocated
|
||||
{
|
||||
friend class SimScene;
|
||||
friend class Compound;
|
||||
protected:
|
||||
Actor(SimScene* scene);
|
||||
public:
|
||||
virtual ~Actor();
|
||||
|
||||
void clear();
|
||||
void addCompound(Compound *m);
|
||||
void removeCompound(Compound *m);
|
||||
|
||||
bool findCompound(const Compound* c, int& compoundNr);
|
||||
|
||||
void preSim(float dt);
|
||||
void postSim(float dt);
|
||||
|
||||
bool rayCast(const PxVec3 &orig, const PxVec3 &dir, float &dist, int &compoundNr, int &convexNr, PxVec3 &normal) const;
|
||||
|
||||
shdfnd::Array<Compound*> getCompounds() { return mCompounds; }
|
||||
|
||||
protected:
|
||||
SimScene* mScene;
|
||||
shdfnd::Array<Compound*> mCompounds;
|
||||
|
||||
PxF32 mMinConvexSize;
|
||||
PxU32 mDepthLimit;
|
||||
bool mDestroyIfAtDepthLimit;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
563
kaplademo/source/kaplaDemo/Fracture/Core/CompoundBase.cpp
Normal file
563
kaplademo/source/kaplaDemo/Fracture/Core/CompoundBase.cpp
Normal file
@ -0,0 +1,563 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include "MeshBase.h"
|
||||
#include "CompoundGeometryBase.h"
|
||||
#include "CompoundCreatorBase.h"
|
||||
#include "PxConvexMeshGeometry.h"
|
||||
#include "PxRigidBodyExt.h"
|
||||
#include "foundation/PxMat44.h"
|
||||
#include "PxScene.h"
|
||||
#include "PxShape.h"
|
||||
|
||||
#include "SimSceneBase.h"
|
||||
#include "CompoundBase.h"
|
||||
#include "ActorBase.h"
|
||||
#include "ConvexBase.h"
|
||||
#include "foundation/PxMathUtils.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MathUtils.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
//vector<PxVec3> tmpPoints;
|
||||
void Compound::appendUniformSamplesOfConvexPolygon(PxVec3* vertices, int numV, float area, shdfnd::Array<PxVec3>& samples, shdfnd::Array<PxVec3>* normals) {
|
||||
PxVec3& p0 = vertices[0];
|
||||
PxVec3 normal;
|
||||
if (numV < 3) {
|
||||
normal = PxVec3(0.0f,1.0f,0.0f);
|
||||
} else {
|
||||
normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
|
||||
normal.normalize();
|
||||
}
|
||||
for (int i = 1; i < numV-1; i++) {
|
||||
PxVec3& p1 = vertices[i];
|
||||
PxVec3& p2 = vertices[i+1];
|
||||
float tarea = 0.5f*((p1-p0).cross(p2-p0)).magnitude();
|
||||
float aa = tarea / area;
|
||||
int np = (int)floor(aa);
|
||||
|
||||
if (randRange(0.0f,1.0f) <= aa-np) np++;
|
||||
|
||||
for (int j = 0; j < np; j++) {
|
||||
float r1 = randRange(0.0f,1.0f);
|
||||
float sr1 = physx::PxSqrt(r1);
|
||||
float r2 = randRange(0.0f, 1.0f);
|
||||
|
||||
PxVec3 p = (1 - sr1) * p0 + (sr1 * (1 - r2)) * p1 + (sr1 * r2) * p2;
|
||||
samples.pushBack(p);
|
||||
if (normals) normals->pushBack(normal);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Compound::Compound(SimScene *scene, PxReal contactOffset, PxReal restOffset)
|
||||
{
|
||||
mScene = scene;
|
||||
mActor = NULL;
|
||||
mPxActor = NULL;
|
||||
mContactOffset = contactOffset;
|
||||
mRestOffset = restOffset;
|
||||
mLifeFrames = -1; // live forever
|
||||
mDepth = 0;
|
||||
clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Compound::~Compound()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#define SHAPE_BUFFER_SIZE 100
|
||||
|
||||
void Compound::clear()
|
||||
{
|
||||
if (mPxActor != NULL) {
|
||||
// Unmap all shapes for this actor
|
||||
const physx::PxU32 shapeCount = mPxActor->getNbShapes();
|
||||
physx::PxShape* shapeBuffer[SHAPE_BUFFER_SIZE];
|
||||
for (physx::PxU32 shapeStartIndex = 0; shapeStartIndex < shapeCount; shapeStartIndex += SHAPE_BUFFER_SIZE)
|
||||
{
|
||||
physx::PxU32 shapesRead = mPxActor->getShapes(shapeBuffer, SHAPE_BUFFER_SIZE, shapeStartIndex);
|
||||
for (physx::PxU32 shapeBufferIndex = 0; shapeBufferIndex < shapesRead; ++shapeBufferIndex)
|
||||
{
|
||||
mScene->unmapShape(*shapeBuffer[shapeBufferIndex]);
|
||||
}
|
||||
}
|
||||
// release the actor
|
||||
mPxActor->release();
|
||||
mPxActor = NULL;
|
||||
}
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++) {
|
||||
if (mConvexes[i]->decreaseRefCounter() <= 0) {
|
||||
convexRemoved(mConvexes[i]); //mScene->getConvexRenderer().remove(mConvexes[i]);
|
||||
PX_DELETE(mConvexes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
mConvexes.clear();
|
||||
mEdges.clear();
|
||||
|
||||
//mShader = NULL;
|
||||
//mShaderMat.init();
|
||||
|
||||
mKinematicVel = PxVec3(0.0f, 0.0f, 0.0f);
|
||||
mAttachmentBounds.clear();
|
||||
|
||||
mAdditionalImpactNormalImpulse = 0.0f;
|
||||
mAdditionalImpactRadialImpulse = 0.0f;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::setKinematic(const PxVec3 &vel)
|
||||
{
|
||||
if (mPxActor == NULL)
|
||||
return;
|
||||
|
||||
mPxActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
mKinematicVel = vel;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::step(float dt)
|
||||
{
|
||||
//if (mPxActor == NULL)
|
||||
// return;
|
||||
|
||||
if (!mKinematicVel.isZero()) {
|
||||
PxTransform pose = mPxActor->getGlobalPose();
|
||||
pose.p += mKinematicVel * dt;
|
||||
mPxActor->setKinematicTarget(pose);
|
||||
}
|
||||
|
||||
if (mLifeFrames > 0)
|
||||
mLifeFrames--;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Compound::createFromConvex(Convex* convex, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, bool copyConvexes, int matID, int surfMatID)
|
||||
{
|
||||
return createFromConvexes(&convex, 1, pose, vel, omega, copyConvexes, matID, surfMatID);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Compound::createFromConvexes(Convex** convexes, int numConvexes, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, bool copyConvexes, int matID, int surfMatID)
|
||||
{
|
||||
if (numConvexes == 0)
|
||||
return false;
|
||||
|
||||
clear();
|
||||
PxVec3 center(0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < numConvexes; i++)
|
||||
center += convexes[i]->getCenter();
|
||||
center /= (float)numConvexes;
|
||||
|
||||
shdfnd::Array<PxShape*> shapes;
|
||||
|
||||
for (int i = 0; i < numConvexes; i++) {
|
||||
Convex *c;
|
||||
if (copyConvexes) {
|
||||
c = mScene->createConvex();
|
||||
c->createFromConvex(convexes[i], 0, matID, surfMatID);
|
||||
}
|
||||
else
|
||||
c = convexes[i];
|
||||
|
||||
c->increaseRefCounter();
|
||||
mConvexes.pushBack(c);
|
||||
|
||||
PxVec3 off = c->centerAtZero();
|
||||
c->setMaterialOffset(c->getMaterialOffset() + off);
|
||||
c->setLocalPose(PxTransform(off - center));
|
||||
|
||||
if (convexes[i]->isGhostConvex())
|
||||
continue;
|
||||
|
||||
bool reused = c->getPxConvexMesh() != NULL;
|
||||
|
||||
mScene->profileBegin("cook convex meshes"); //Profiler::getInstance()->begin("cook convex meshes");
|
||||
PxConvexMesh* mesh = c->createPxConvexMesh(this, mScene->getPxPhysics(), mScene->getPxCooking());
|
||||
mScene->profileEnd("cook convex meshes"); //Profiler::getInstance()->end("cook convex meshes");
|
||||
|
||||
if (mesh == NULL) {
|
||||
if (c->decreaseRefCounter() <= 0)
|
||||
PX_DELETE(c);
|
||||
mConvexes.popBack();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!c->hasExplicitVisMesh())
|
||||
c->createVisMeshFromConvex();
|
||||
|
||||
if (!reused)
|
||||
convexAdded(c); //mScene->getConvexRenderer().add(c);
|
||||
|
||||
PxShape *shape = mScene->getPxPhysics()->createShape(
|
||||
PxConvexMeshGeometry(mesh),
|
||||
*mScene->getPxDefaultMaterial(),
|
||||
true
|
||||
);
|
||||
shape->setLocalPose(c->getLocalPose());
|
||||
|
||||
//shape->setContactOffset(mContactOffset);
|
||||
//shape->setRestOffset(mRestOffset);
|
||||
|
||||
if (mContactOffset < mRestOffset || mContactOffset < 0.0f)
|
||||
{
|
||||
printf("WRONG\n");
|
||||
}
|
||||
|
||||
mScene->mapShapeToConvex(*shape, *c);
|
||||
|
||||
shapes.pushBack(shape);
|
||||
}
|
||||
|
||||
if (shapes.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
createPxActor(shapes, pose, vel, omega);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
bool Compound::createFromGeometry(const CompoundGeometry &geom, PxRigidDynamic* body, Shader* myShader, int matID, int surfMatID)
|
||||
{
|
||||
clear();
|
||||
|
||||
shdfnd::Array<PxShape*> shapes(body->getNbShapes());
|
||||
|
||||
body->getShapes(shapes.begin(), body->getNbShapes());
|
||||
|
||||
PX_ASSERT(geom.convexes.size() == body->getNbShapes());
|
||||
|
||||
for (int i = 0; i < (int)geom.convexes.size(); i++) {
|
||||
Convex *c = mScene->createConvex();
|
||||
c->createFromGeometry(geom, i, 0, matID, surfMatID);
|
||||
c->increaseRefCounter();
|
||||
mConvexes.pushBack(c);
|
||||
|
||||
PxVec3 off = c->centerAtZero();
|
||||
c->setMaterialOffset(c->getMaterialOffset() + off);
|
||||
c->createVisMeshFromConvex();
|
||||
c->setLocalPose(PxTransform(off));
|
||||
|
||||
bool reused = c->getPxConvexMesh() != NULL;
|
||||
|
||||
if (!reused)
|
||||
convexAdded(c, myShader); //mScene->getConvexRenderer().add(c);
|
||||
|
||||
mScene->mapShapeToConvex(*shapes[i], *c);
|
||||
|
||||
}
|
||||
|
||||
if (shapes.empty())
|
||||
return false;
|
||||
|
||||
mPxActor = body;
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++)
|
||||
mConvexes[i]->setPxActor(mPxActor);
|
||||
|
||||
//createPxActor(shapes, pose, vel, omega);
|
||||
return true;
|
||||
|
||||
}
|
||||
bool Compound::createFromGeometry(const CompoundGeometry &geom, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, Shader* myShader, int matID, int surfMatID)
|
||||
{
|
||||
clear();
|
||||
|
||||
shdfnd::Array<PxShape*> shapes;
|
||||
|
||||
for (int i = 0; i < (int)geom.convexes.size(); i++) {
|
||||
Convex *c = mScene->createConvex();
|
||||
c->createFromGeometry(geom, i, 0, matID, surfMatID);
|
||||
c->increaseRefCounter();
|
||||
mConvexes.pushBack(c);
|
||||
|
||||
PxVec3 off = c->centerAtZero();
|
||||
c->setMaterialOffset(c->getMaterialOffset() + off);
|
||||
c->createVisMeshFromConvex();
|
||||
c->setLocalPose(PxTransform(off));
|
||||
|
||||
bool reused = c->getPxConvexMesh() != NULL;
|
||||
|
||||
PxConvexMesh* mesh = c->createPxConvexMesh(this, mScene->getPxPhysics(), mScene->getPxCooking());
|
||||
if (mesh == NULL) {
|
||||
if (c->decreaseRefCounter() <= 0)
|
||||
PX_DELETE(c);
|
||||
mConvexes.popBack();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!reused)
|
||||
convexAdded(c, myShader); //mScene->getConvexRenderer().add(c);
|
||||
|
||||
PxShape *shape;
|
||||
if (geom.convexes[i].isSphere)
|
||||
{
|
||||
shape = mScene->getPxPhysics()->createShape(
|
||||
PxSphereGeometry(geom.convexes[i].radius),
|
||||
*mScene->getPxDefaultMaterial(),
|
||||
true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
shape = mScene->getPxPhysics()->createShape(
|
||||
PxConvexMeshGeometry(mesh),
|
||||
*mScene->getPxDefaultMaterial(),
|
||||
true
|
||||
);
|
||||
}
|
||||
shape->setLocalPose(c->getLocalPose());
|
||||
|
||||
//shape->setContactOffset(mContactOffset);
|
||||
//shape->setRestOffset(mRestOffset);
|
||||
|
||||
mScene->mapShapeToConvex(*shape, *c);
|
||||
|
||||
shapes.pushBack(shape);
|
||||
}
|
||||
|
||||
if (shapes.empty())
|
||||
return false;
|
||||
|
||||
createPxActor(shapes, pose, vel, omega);
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::createFromMesh(const Mesh *mesh, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, int submeshNr, const PxVec3& scale, int matID, int surfMatID)
|
||||
{
|
||||
const shdfnd::Array<PxVec3> &verts = mesh->getVertices();
|
||||
const shdfnd::Array<PxVec3> &normals = mesh->getNormals();
|
||||
const shdfnd::Array<PxVec2> &texcoords = mesh->getTexCoords();
|
||||
const shdfnd::Array<PxU32> &indices = mesh->getIndices();
|
||||
|
||||
if (verts.empty() || indices.empty())
|
||||
return;
|
||||
|
||||
if (submeshNr >= 0 && submeshNr >= (int)mesh->getSubMeshes().size())
|
||||
return;
|
||||
|
||||
PxBounds3 bounds;
|
||||
mesh->getBounds(bounds, submeshNr);
|
||||
PxMat33 scaleMat(PxMat33::createDiagonal(scale));
|
||||
bounds = PxBounds3::transformSafe(scaleMat, bounds);
|
||||
|
||||
PxVec3 dims = bounds.getDimensions() * 1.01f;
|
||||
PxVec3 center = bounds.getCenter();
|
||||
|
||||
mScene->getCompoundCreator()->createBox(dims);
|
||||
createFromGeometry(mScene->getCompoundCreator()->getGeometry(), pose, vel, omega, NULL, matID, surfMatID);
|
||||
PxTransform trans(-center);
|
||||
|
||||
if (submeshNr < 0)
|
||||
mConvexes[0]->setExplicitVisMeshFromTriangles(verts.size(), &verts[0], &normals[0], &texcoords[0], indices.size(), &indices[0], &trans, &scale);
|
||||
else {
|
||||
const Mesh::SubMesh &sm = mesh->getSubMeshes()[submeshNr];
|
||||
mConvexes[0]->setExplicitVisMeshFromTriangles(verts.size(), &verts[0], &normals[0], &texcoords[0], sm.numIndices, &indices[sm.firstIndex], &trans, &scale);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Compound::createPxActor(shdfnd::Array<PxShape*> &shapes, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega)
|
||||
{
|
||||
if (shapes.empty())
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < (int)shapes.size(); i++)
|
||||
{
|
||||
applyShapeTemplate(shapes[i]);
|
||||
}
|
||||
|
||||
PxRigidDynamic* body = mScene->getPxPhysics()->createRigidDynamic(pose);
|
||||
if (body == NULL)
|
||||
return false;
|
||||
|
||||
//body->setSleepThreshold(getSleepingThresholdRB());
|
||||
#if 0
|
||||
body->setWakeCounter(100000000000.f);
|
||||
#endif
|
||||
|
||||
mScene->getScene()->addActor(*body);
|
||||
|
||||
for (int i = 0; i < (int)shapes.size(); i++)
|
||||
body->attachShape(*shapes[i]);
|
||||
|
||||
|
||||
|
||||
//KS - we clamp the mass in the range [minMass, maxMass]. This helps to improve stability
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 1.0f);
|
||||
|
||||
/*const PxReal maxMass = 50.f;
|
||||
const PxReal minMass = 1.f;
|
||||
|
||||
PxReal mass = PxMax(PxMin(maxMass, body->getMass()), minMass);
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*body, mass);*/
|
||||
|
||||
|
||||
|
||||
body->setLinearVelocity(vel);
|
||||
body->setAngularVelocity(omega);
|
||||
|
||||
/*if (vel.isZero() && omega.isZero())
|
||||
{
|
||||
body->putToSleep();
|
||||
}*/
|
||||
|
||||
mPxActor = body;
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++)
|
||||
mConvexes[i]->setPxActor(mPxActor);
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Compound::rayCast(const PxVec3 &orig, const PxVec3 &dir, float &dist, int &convexNr, PxVec3 &normal)
|
||||
{
|
||||
dist = PX_MAX_F32;
|
||||
convexNr = -1;
|
||||
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++) {
|
||||
float d;
|
||||
PxVec3 n;
|
||||
if (mConvexes[i]->rayCast(orig, dir, d, n)) {
|
||||
if (d < dist) {
|
||||
dist = d;
|
||||
convexNr = i;
|
||||
normal = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
return convexNr >= 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::getRestBounds(PxBounds3 &bounds) const
|
||||
{
|
||||
bounds.setEmpty();
|
||||
PxBounds3 bi;
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++) {
|
||||
Convex *c = mConvexes[i];
|
||||
PxBounds3 bi = c->getBounds();
|
||||
bi = PxBounds3::transformSafe(c->getLocalPose(), bi);
|
||||
bounds.include(bi);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::getWorldBounds(PxBounds3 &bounds) const
|
||||
{
|
||||
bounds.setEmpty();
|
||||
PxBounds3 bi;
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++) {
|
||||
mConvexes[i]->getWorldBounds(bi);
|
||||
bounds.include(bi);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::getLocalBounds(PxBounds3 &bounds) const
|
||||
{
|
||||
bounds.setEmpty();
|
||||
PxBounds3 bi;
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++) {
|
||||
mConvexes[i]->getLocalBounds(bi);
|
||||
bounds.include(bi);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool Compound::isAttached()
|
||||
{
|
||||
if (mAttachmentBounds.empty())
|
||||
return false;
|
||||
|
||||
PxBounds3 b;
|
||||
for (int i = 0; i < (int)mConvexes.size(); i++) {
|
||||
Convex *c = mConvexes[i];
|
||||
b = c->getBounds();
|
||||
b.minimum += c->getMaterialOffset();
|
||||
b.maximum += c->getMaterialOffset();
|
||||
for (int j = 0; j < (int)mAttachmentBounds.size(); j++) {
|
||||
if (b.intersects(mAttachmentBounds[j]))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::attach(const shdfnd::Array<PxBounds3> &bounds)
|
||||
{
|
||||
mAttachmentBounds.resize(bounds.size());
|
||||
|
||||
PxTransform t = getPxActor()->getGlobalPose().getInverse();
|
||||
for (int i = 0; i < (int)bounds.size(); i++) {
|
||||
PxVec3 a = t.transform(bounds[i].minimum);
|
||||
PxVec3 b = t.transform(bounds[i].maximum);
|
||||
mAttachmentBounds[i].minimum = PxVec3(PxMin(a.x,b.x),PxMin(a.y,b.y),PxMin(a.z,b.z));
|
||||
mAttachmentBounds[i].maximum = PxVec3(PxMax(a.x,b.x),PxMax(a.y,b.y),PxMax(a.z,b.z));
|
||||
}
|
||||
|
||||
if (isAttached())
|
||||
mPxActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void Compound::attachLocal(const shdfnd::Array<PxBounds3> &bounds)
|
||||
{
|
||||
mAttachmentBounds.resize(bounds.size());
|
||||
|
||||
for (int i = 0; i < (int)bounds.size(); i++) {
|
||||
mAttachmentBounds[i] = bounds[i];
|
||||
}
|
||||
|
||||
if (isAttached())
|
||||
mPxActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
162
kaplademo/source/kaplaDemo/Fracture/Core/CompoundBase.h
Normal file
162
kaplademo/source/kaplaDemo/Fracture/Core/CompoundBase.h
Normal file
@ -0,0 +1,162 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef COMPOUNDBASE
|
||||
#define COMPOUNDBASE
|
||||
|
||||
#define TECHNICAL_MODE 1
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxPlane.h>
|
||||
#include <foundation/PxBounds3.h>
|
||||
#include <foundation/PxTransform.h>
|
||||
#include <PsArray.h>
|
||||
#include <PxRigidDynamic.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
|
||||
class Shader;
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
class Convex;
|
||||
class Mesh;
|
||||
class SimScene;
|
||||
class CompoundGeometry;
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
class Compound : public ::physx::shdfnd::UserAllocated
|
||||
{
|
||||
friend class SimScene;
|
||||
friend class Actor;
|
||||
protected:
|
||||
Compound(SimScene* scene, PxReal contactOffset = 0.005f, PxReal restOffset = -0.001f);
|
||||
public:
|
||||
virtual ~Compound();
|
||||
|
||||
virtual bool createFromConvexes(Convex** convexes, int numConvexes, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, bool copyConvexes = true, int matID = 0, int surfMatID = 0);
|
||||
bool createFromConvex(Convex* convex, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, bool copyConvexes = true, int matID = 0, int surfMatID = 0);
|
||||
bool createFromGeometry(const CompoundGeometry &geom, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, Shader* myShader, int matID = 0, int surfMatID = 0);
|
||||
bool createFromGeometry(const CompoundGeometry &geom, PxRigidDynamic* body, Shader* myShader, int matID = 0, int surfMatID = 0);
|
||||
void createFromMesh(const Mesh *mesh, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega, int submeshNr = -1, const PxVec3& scale = PxVec3(1.f), int matID = 0, int surfMatID = 0);
|
||||
|
||||
virtual void applyShapeTemplate(PxShape* /*shape*/) {}
|
||||
|
||||
bool rayCast(const PxVec3 &orig, const PxVec3 &dir, float &dist, int &convexNr, PxVec3 &normal);
|
||||
void setLifeFrames(int frames) { mLifeFrames = frames == 0 ? 1 : frames; }
|
||||
int getLifeFrames() { return mLifeFrames; }
|
||||
|
||||
|
||||
virtual void convexAdded(Convex* /*c*/, Shader* shader = NULL) {}
|
||||
virtual void convexRemoved(Convex* /*c*/) {}
|
||||
|
||||
void attach(const shdfnd::Array<PxBounds3> &bounds);
|
||||
void attachLocal(const shdfnd::Array<PxBounds3> &bounds);
|
||||
|
||||
const shdfnd::Array<Convex*>& getConvexes() const { return mConvexes; }
|
||||
const shdfnd::Array<PxBounds3>& getAttachmentBounds() const { return mAttachmentBounds; }
|
||||
|
||||
PxRigidDynamic* getPxActor() { return mPxActor; }
|
||||
void getWorldBounds(PxBounds3 &bounds) const;
|
||||
void getLocalBounds(PxBounds3 &bounds) const;
|
||||
void getRestBounds(PxBounds3 &bounds) const;
|
||||
|
||||
//void setShader(Shader* shader, const ShaderMaterial &mat) { mShader = shader; mShaderMat = mat; }
|
||||
//Shader* getShader() const { return mShader; }
|
||||
//const ShaderMaterial& getShaderMat() { return mShaderMat; }
|
||||
|
||||
void setKinematic(const PxVec3 &vel);
|
||||
void step(float dt);
|
||||
|
||||
virtual void draw(bool /*useShader*/, bool /*debug*/ = false) {}
|
||||
|
||||
virtual void clear();
|
||||
|
||||
void setAdditionalImpactImpulse(float radial, float normal) {
|
||||
mAdditionalImpactRadialImpulse = radial; mAdditionalImpactNormalImpulse = normal;
|
||||
}
|
||||
float getAdditionalImpactRadialImpulse() const { return mAdditionalImpactRadialImpulse; }
|
||||
float getAdditionalImpactNormalImpulse() const { return mAdditionalImpactNormalImpulse; }
|
||||
|
||||
virtual void copyShaders(Compound*) {}
|
||||
|
||||
protected:
|
||||
|
||||
bool isAttached();
|
||||
|
||||
bool createPxActor(shdfnd::Array<PxShape*> &shapes, const PxTransform &pose, const PxVec3 &vel, const PxVec3 &omega);
|
||||
|
||||
static void appendUniformSamplesOfConvexPolygon(PxVec3* vertices, int numV, float area, shdfnd::Array<PxVec3>& samples, shdfnd::Array<PxVec3>* normals = NULL);
|
||||
|
||||
virtual float getSleepingThresholdRB() {return 0.1f;}
|
||||
|
||||
struct Edge {
|
||||
void init(int c0, int c1) {
|
||||
this->c0 = c0; this->c1 = c1;
|
||||
restLen = 0.0f;
|
||||
deleted = false;
|
||||
}
|
||||
int c0, c1;
|
||||
float restLen;
|
||||
bool deleted;
|
||||
};
|
||||
|
||||
shdfnd::Array<Convex*> mConvexes;
|
||||
shdfnd::Array<Edge> mEdges;
|
||||
|
||||
SimScene *mScene;
|
||||
Actor *mActor;
|
||||
PxRigidDynamic *mPxActor;
|
||||
PxVec3 mKinematicVel;
|
||||
shdfnd::Array<PxBounds3> mAttachmentBounds;
|
||||
|
||||
//Shader *mShader;
|
||||
//ShaderMaterial mShaderMat;
|
||||
|
||||
PxReal mContactOffset;
|
||||
PxReal mRestOffset;
|
||||
|
||||
int mLifeFrames;
|
||||
|
||||
float mAdditionalImpactNormalImpulse;
|
||||
float mAdditionalImpactRadialImpulse;
|
||||
|
||||
PxU32 mDepth; // fracture depth
|
||||
PxVec3 mNormal; // normal use with mSheetFracture
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
871
kaplademo/source/kaplaDemo/Fracture/Core/CompoundCreatorBase.cpp
Normal file
871
kaplademo/source/kaplaDemo/Fracture/Core/CompoundCreatorBase.cpp
Normal file
@ -0,0 +1,871 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include "CompoundCreatorBase.h"
|
||||
#include <algorithm>
|
||||
#include <foundation/PxAssert.h>
|
||||
|
||||
#include "PhysXMacros.h"
|
||||
#include "PxConvexMeshGeometry.h"
|
||||
#include "PxConvexMesh.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
int CompoundCreator::tetFaceIds[4][3] = {{0,1,3},{1,2,3},{2,0,3},{0,2,1}};
|
||||
int CompoundCreator::tetEdgeVerts[6][2] = {{0,1},{1,2},{2,0},{0,3},{1,3},{2,3}};
|
||||
int CompoundCreator::tetFaceEdges[4][3] = {{0,4,3},{1,5,4},{2,3,5},{0,2,1}};
|
||||
|
||||
#define CONVEX_THRESHOLD (PxPi + 0.05f)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::createTorus(float r0, float r1, int numSegs0, int numSegs1, const PxTransform *trans)
|
||||
{
|
||||
mGeom.clear();
|
||||
CompoundGeometry::Convex c;
|
||||
PxVec3 nr0,nr1,nz;
|
||||
nz = PxVec3(0.0f, 0.0f, 1.0f);
|
||||
PxVec3 p,n;
|
||||
PxTransform t = PX_TRANSFORM_ID;
|
||||
if (trans)
|
||||
t = *trans;
|
||||
|
||||
shdfnd::Array<PxVec3> normals;
|
||||
|
||||
float dphi0 = PxTwoPi / (float)numSegs0;
|
||||
float dphi1 = PxTwoPi / (float)numSegs1;
|
||||
for (int i = 0; i < numSegs0; i++) {
|
||||
nr0 = PxVec3(PxCos(i*dphi0), PxSin(i*dphi0), 0.0f);
|
||||
nr1 = PxVec3(PxCos((i+1)*dphi0), PxSin((i+1)*dphi0), 0.0f);
|
||||
mGeom.initConvex(c);
|
||||
c.numVerts = 2*numSegs1;
|
||||
normals.clear();
|
||||
for (int j = 0; j < numSegs1; j++) {
|
||||
p = nr0 * (r0 + r1 * PxCos(j*dphi1)) + nz * r1 * PxSin(j*dphi1);
|
||||
mGeom.vertices.pushBack(t.transform(p));
|
||||
n = nr0 * (PxCos(j*dphi1)) + nz * PxSin(j*dphi1);
|
||||
normals.pushBack(t.rotate(n));
|
||||
|
||||
p = nr1 * (r0 + r1 * PxCos(j*dphi1)) + nz * r1 * PxSin(j*dphi1);
|
||||
mGeom.vertices.pushBack(t.transform(p));
|
||||
n = nr1 * (PxCos(j*dphi1)) + nz * PxSin(j*dphi1);
|
||||
normals.pushBack(t.rotate(n));
|
||||
}
|
||||
|
||||
c.numFaces = 2 + numSegs1;
|
||||
mGeom.indices.pushBack(numSegs1); // face size
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_INVISIBLE); // face flags
|
||||
for (int j = 0; j < numSegs1; j++)
|
||||
mGeom.indices.pushBack(2*j);
|
||||
mGeom.indices.pushBack(numSegs1); // face size
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_INVISIBLE); // face flags
|
||||
for (int j = 0; j < numSegs1; j++) {
|
||||
mGeom.indices.pushBack(2*(numSegs1-1-j) + 1);
|
||||
}
|
||||
for (int j = 0; j < numSegs1; j++) {
|
||||
int k = (j+1)%numSegs1;
|
||||
mGeom.indices.pushBack(4); // face size
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_OBJECT_SURFACE | CompoundGeometry::FF_HAS_NORMALS);
|
||||
int i0 = 2*j;
|
||||
int i1 = 2*j+1;
|
||||
int i2 = 2*k+1;
|
||||
int i3 = 2*k;
|
||||
mGeom.indices.pushBack(i0);
|
||||
mGeom.indices.pushBack(i1);
|
||||
mGeom.indices.pushBack(i2);
|
||||
mGeom.indices.pushBack(i3);
|
||||
mGeom.normals.pushBack(normals[i0]);
|
||||
mGeom.normals.pushBack(normals[i1]);
|
||||
mGeom.normals.pushBack(normals[i2]);
|
||||
mGeom.normals.pushBack(normals[i3]);
|
||||
}
|
||||
c.numNeighbors = 2;
|
||||
mGeom.neighbors.pushBack((i + (numSegs0-1)) % numSegs0);
|
||||
mGeom.neighbors.pushBack((i + 1) % numSegs0);
|
||||
mGeom.convexes.pushBack(c);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::createCylinder(float r, float h, int numSegs, const PxTransform *trans)
|
||||
{
|
||||
PxTransform t = PX_TRANSFORM_ID;
|
||||
if (trans)
|
||||
t = *trans;
|
||||
|
||||
mGeom.clear();
|
||||
CompoundGeometry::Convex c;
|
||||
mGeom.initConvex(c);
|
||||
|
||||
float dphi = PxTwoPi / (float)numSegs;
|
||||
c.numVerts = 2*numSegs;
|
||||
mGeom.vertices.resize(c.numVerts);
|
||||
|
||||
for (int i = 0; i < numSegs; i++) {
|
||||
PxVec3 p0(r * PxCos(i*dphi), r * PxSin(i*dphi), -0.5f * h);
|
||||
PxVec3 p1(r * PxCos(i*dphi), r * PxSin(i*dphi), 0.5f * h);
|
||||
mGeom.vertices[2*i] = t.transform(p0);
|
||||
mGeom.vertices[2*i+1] = t.transform(p1);
|
||||
}
|
||||
|
||||
c.numFaces = 2 + numSegs;
|
||||
|
||||
mGeom.indices.pushBack(numSegs);
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_OBJECT_SURFACE);
|
||||
for (int i = 0; i < numSegs; i++)
|
||||
mGeom.indices.pushBack(2*(numSegs-1-i));
|
||||
mGeom.indices.pushBack(numSegs);
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_OBJECT_SURFACE);
|
||||
for (int i = 0; i < numSegs; i++)
|
||||
mGeom.indices.pushBack(2*i+1);
|
||||
|
||||
for (int i = 0; i < numSegs; i++) {
|
||||
int j = (i+1) % numSegs;
|
||||
|
||||
PxVec3 n0(PxCos(i*dphi),PxSin(i*dphi),0.0f);
|
||||
PxVec3 n1(PxCos(j*dphi),PxSin(j*dphi),0.0f);
|
||||
|
||||
n0 = t.rotate(n0);
|
||||
n1 = t.rotate(n1);
|
||||
//n0*=-1;
|
||||
//n1*=-1;
|
||||
mGeom.indices.pushBack(4);
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_OBJECT_SURFACE | CompoundGeometry::FF_HAS_NORMALS);
|
||||
mGeom.indices.pushBack(2*i);
|
||||
mGeom.indices.pushBack(2*j);
|
||||
mGeom.indices.pushBack(2*j+1);
|
||||
mGeom.indices.pushBack(2*i+1);
|
||||
mGeom.normals.pushBack(n0);
|
||||
mGeom.normals.pushBack(n1);
|
||||
mGeom.normals.pushBack(n1);
|
||||
mGeom.normals.pushBack(n0);
|
||||
}
|
||||
mGeom.convexes.pushBack(c);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::createBox(const PxVec3 &dims, const PxTransform *trans, bool clear)
|
||||
{
|
||||
PxTransform t = PX_TRANSFORM_ID;
|
||||
if (trans)
|
||||
t = *trans;
|
||||
|
||||
if (clear)
|
||||
mGeom.clear();
|
||||
CompoundGeometry::Convex c;
|
||||
mGeom.initConvex(c);
|
||||
|
||||
c.numVerts = 8;
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3(-0.5f * dims.x, -0.5f * dims.y, -0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3( 0.5f * dims.x, -0.5f * dims.y, -0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3( 0.5f * dims.x, 0.5f * dims.y, -0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3(-0.5f * dims.x, 0.5f * dims.y, -0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3(-0.5f * dims.x, -0.5f * dims.y, 0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3( 0.5f * dims.x, -0.5f * dims.y, 0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3( 0.5f * dims.x, 0.5f * dims.y, 0.5f * dims.z)));
|
||||
mGeom.vertices.pushBack(t.transform(PxVec3(-0.5f * dims.x, 0.5f * dims.y, 0.5f * dims.z)));
|
||||
|
||||
static int faceIds[6][4] = {{0,1,5,4},{1,2,6,5},{2,3,7,6},{3,0,4,7},{0,3,2,1},{4,5,6,7}};
|
||||
|
||||
c.numFaces = 6;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
mGeom.indices.pushBack(4);
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_OBJECT_SURFACE);
|
||||
for (int j = 0; j < 4; j++)
|
||||
mGeom.indices.pushBack(faceIds[i][j]);
|
||||
}
|
||||
mGeom.convexes.pushBack(c);
|
||||
}
|
||||
|
||||
void CompoundCreator::createFromConvexMesh(const PxConvexMeshGeometry& convexGeom, PxTransform offset, bool clear)
|
||||
{
|
||||
|
||||
if (clear)
|
||||
{
|
||||
mGeom.clear();
|
||||
}
|
||||
CompoundGeometry::Convex c;
|
||||
mGeom.initConvex(c);
|
||||
|
||||
PxConvexMesh* convexMesh = convexGeom.convexMesh;
|
||||
c.numVerts = convexMesh->getNbVertices();
|
||||
c.numFaces = convexMesh->getNbPolygons();
|
||||
|
||||
const PxVec3* verts = convexMesh->getVertices();
|
||||
const PxU8* indexBuff = convexMesh->getIndexBuffer();
|
||||
|
||||
|
||||
for (PxU32 a = 0; a < c.numVerts; ++a)
|
||||
{
|
||||
mGeom.vertices.pushBack(offset.transform(verts[a]));
|
||||
}
|
||||
|
||||
|
||||
for (PxU32 a = 0; a < c.numFaces; ++a)
|
||||
{
|
||||
PxHullPolygon data;
|
||||
convexMesh->getPolygonData(a, data);
|
||||
|
||||
mGeom.indices.pushBack(data.mNbVerts);
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_OBJECT_SURFACE);
|
||||
const PxU32 indexBase = data.mIndexBase;
|
||||
for (PxU32 b = 0; b < data.mNbVerts; ++b)
|
||||
{
|
||||
PxU32 ind = indexBuff[indexBase + b];
|
||||
mGeom.indices.pushBack(ind);
|
||||
}
|
||||
}
|
||||
|
||||
mGeom.convexes.pushBack(c);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::createSphere(const PxVec3 &dims, int resolution, const PxTransform *trans)
|
||||
{
|
||||
PxTransform t = PX_TRANSFORM_ID;
|
||||
if (trans)
|
||||
t = *trans;
|
||||
|
||||
if (resolution < 2) resolution = 2;
|
||||
int numSegs0 = 2*resolution;
|
||||
int numSegs1 = resolution;
|
||||
|
||||
float rx = 0.5f * dims.x;
|
||||
float ry = 0.5f * dims.y;
|
||||
float rz = 0.5f * dims.z;
|
||||
|
||||
mGeom.clear();
|
||||
CompoundGeometry::Convex c;
|
||||
mGeom.initConvex(c);
|
||||
|
||||
if (rx == ry && rx == rz)
|
||||
{
|
||||
c.isSphere = true;
|
||||
c.radius = rx;
|
||||
}
|
||||
|
||||
float dphi = PxTwoPi / (float)numSegs0;
|
||||
float dteta = PxPi / (float)numSegs1;
|
||||
PxVec3 p, n;
|
||||
|
||||
for (int i = 1; i < numSegs1; i++) {
|
||||
for (int j = 0; j < numSegs0; j++) {
|
||||
float phi = j * dphi;
|
||||
float teta = -PxHalfPi + i * dteta;
|
||||
p = PxVec3(PxCos(phi)*PxCos(teta), PxSin(phi)*PxCos(teta), PxSin(teta));
|
||||
mGeom.vertices.pushBack(PxVec3(p.x * rx, p.y * ry, p.z * rz));
|
||||
}
|
||||
}
|
||||
int bottomNr = mGeom.vertices.size();
|
||||
mGeom.vertices.pushBack(PxVec3(0.0f, 0.0f, -rz));
|
||||
int topNr = mGeom.vertices.size();
|
||||
mGeom.vertices.pushBack(PxVec3(0.0f, 0.0f, +rz));
|
||||
|
||||
c.numVerts = mGeom.vertices.size();
|
||||
|
||||
for (int i = 0; i < numSegs1-2; i++) {
|
||||
for (int j = 0; j < numSegs0; j++) {
|
||||
mGeom.indices.pushBack(4); // face size
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_HAS_NORMALS | CompoundGeometry::FF_OBJECT_SURFACE);
|
||||
int i0 = i*numSegs0 + j;
|
||||
int i1 = i*numSegs0 + (j+1)%numSegs0;
|
||||
int i2 = (i+1)*numSegs0 + (j+1)%numSegs0;
|
||||
int i3 = (i+1)*numSegs0 + j;
|
||||
mGeom.indices.pushBack(i0);
|
||||
mGeom.indices.pushBack(i1);
|
||||
mGeom.indices.pushBack(i2);
|
||||
mGeom.indices.pushBack(i3);
|
||||
n = mGeom.vertices[i0]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
n = mGeom.vertices[i1]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
n = mGeom.vertices[i2]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
n = mGeom.vertices[i3]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
c.numFaces++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < numSegs0; j++) {
|
||||
mGeom.indices.pushBack(3); // face size
|
||||
mGeom.indices.pushBack(CompoundGeometry::FF_HAS_NORMALS | CompoundGeometry::FF_OBJECT_SURFACE);
|
||||
int i0,i1,i2;
|
||||
if (i == 0) {
|
||||
i0 = j;
|
||||
i1 = bottomNr;
|
||||
i2 = (j+1)%numSegs0;
|
||||
}
|
||||
else {
|
||||
i0 = (numSegs1-2)*numSegs0 + j;
|
||||
i1 = (numSegs1-2)*numSegs0 + (j+1)%numSegs0;
|
||||
i2 = topNr;
|
||||
}
|
||||
mGeom.indices.pushBack(i0);
|
||||
mGeom.indices.pushBack(i1);
|
||||
mGeom.indices.pushBack(i2);
|
||||
n = mGeom.vertices[i0]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
n = mGeom.vertices[i1]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
n = mGeom.vertices[i2]; n.normalize(); mGeom.normals.pushBack(n);
|
||||
c.numFaces++;
|
||||
}
|
||||
}
|
||||
mGeom.convexes.pushBack(c);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::fromTetraMesh(const shdfnd::Array<PxVec3> &tetVerts, const shdfnd::Array<int> &tetIndices)
|
||||
{
|
||||
mTetVertices = tetVerts;
|
||||
mTetIndices = tetIndices;
|
||||
deleteColors();
|
||||
|
||||
computeTetNeighbors();
|
||||
computeTetEdges();
|
||||
colorTets();
|
||||
colorsToConvexes();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::computeTetNeighbors()
|
||||
{
|
||||
int numTets = mTetIndices.size() / 4;
|
||||
|
||||
struct TetFace {
|
||||
void init(int i0, int i1, int i2, int faceNr, int tetNr) {
|
||||
if (i0 > i1) { int i = i0; i0 = i1; i1 = i; }
|
||||
if (i1 > i2) { int i = i1; i1 = i2; i2 = i; }
|
||||
if (i0 > i1) { int i = i0; i0 = i1; i1 = i; }
|
||||
this->i0 = i0; this->i1 = i1; this->i2 = i2;
|
||||
this->faceNr = faceNr; this->tetNr = tetNr;
|
||||
}
|
||||
bool operator < (const TetFace &f) const {
|
||||
if (i0 < f.i0) return true;
|
||||
if (i0 > f.i0) return false;
|
||||
if (i1 < f.i1) return true;
|
||||
if (i1 > f.i1) return false;
|
||||
return i2 < f.i2;
|
||||
}
|
||||
bool operator == (const TetFace &f) const {
|
||||
return i0 == f.i0 && i1 == f.i1 && i2 == f.i2;
|
||||
}
|
||||
int i0,i1,i2;
|
||||
int faceNr, tetNr;
|
||||
};
|
||||
shdfnd::Array<TetFace> faces(numTets * 4);
|
||||
|
||||
for (int i = 0; i < numTets; i++) {
|
||||
int ids[4];
|
||||
ids[0] = mTetIndices[4*i];
|
||||
ids[1] = mTetIndices[4*i+1];
|
||||
ids[2] = mTetIndices[4*i+2];
|
||||
ids[3] = mTetIndices[4*i+3];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int i0 = ids[tetFaceIds[j][0]];
|
||||
int i1 = ids[tetFaceIds[j][1]];
|
||||
int i2 = ids[tetFaceIds[j][2]];
|
||||
faces[4*i+j].init(i0,i1,i2, j, i);
|
||||
}
|
||||
}
|
||||
std::sort(faces.begin(), faces.end());
|
||||
|
||||
mTetNeighbors.clear();
|
||||
mTetNeighbors.resize(numTets * 4, -1);
|
||||
int i = 0;
|
||||
while (i < (int)faces.size()) {
|
||||
TetFace &f0 = faces[i];
|
||||
i++;
|
||||
if (i < (int)faces.size() && faces[i] == f0) {
|
||||
TetFace &f1 = faces[i];
|
||||
mTetNeighbors[4*f0.tetNr + f0.faceNr] = f1.tetNr;
|
||||
mTetNeighbors[4*f1.tetNr + f1.faceNr] = f0.tetNr;
|
||||
while (i < (int)faces.size() && faces[i] == f0)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::computeTetEdges()
|
||||
{
|
||||
int numTets = mTetIndices.size() / 4;
|
||||
|
||||
struct SortEdge {
|
||||
void init(int i0, int i1, int edgeNr, int tetNr) {
|
||||
if (i0 < i1) { this->i0 = i0; this->i1 = i1; }
|
||||
else { this->i0 = i1; this->i1 = i0; }
|
||||
this->edgeNr = edgeNr; this->tetNr = tetNr;
|
||||
}
|
||||
bool operator < (const SortEdge &e) const {
|
||||
if (i0 < e.i0) return true;
|
||||
if (i0 > e.i0) return false;
|
||||
return i1 < e.i1;
|
||||
}
|
||||
bool operator == (const SortEdge &e) const {
|
||||
return i0 == e.i0 && i1 == e.i1;
|
||||
}
|
||||
int i0,i1;
|
||||
int edgeNr, tetNr;
|
||||
};
|
||||
shdfnd::Array<SortEdge> edges(numTets * 6);
|
||||
|
||||
for (int i = 0; i < numTets; i++) {
|
||||
int ids[4];
|
||||
ids[0] = mTetIndices[4*i];
|
||||
ids[1] = mTetIndices[4*i+1];
|
||||
ids[2] = mTetIndices[4*i+2];
|
||||
ids[3] = mTetIndices[4*i+3];
|
||||
for (int j = 0; j < 6; j++) {
|
||||
int i0 = ids[tetEdgeVerts[j][0]];
|
||||
int i1 = ids[tetEdgeVerts[j][1]];
|
||||
edges[6*i + j].init(i0,i1, j, i);
|
||||
}
|
||||
}
|
||||
std::sort(edges.begin(), edges.end());
|
||||
|
||||
mTetEdgeNrs.clear();
|
||||
mTetEdgeNrs.resize(numTets * 6, -1);
|
||||
mTetEdges.clear();
|
||||
mEdgeTetNrs.clear();
|
||||
mEdgeTetAngles.clear();
|
||||
TetEdge te;
|
||||
|
||||
struct ChainVert {
|
||||
int adjVert0;
|
||||
int adjVert1;
|
||||
int tet0;
|
||||
int tet1;
|
||||
float dihed0;
|
||||
float dihed1;
|
||||
int mark;
|
||||
};
|
||||
ChainVert cv;
|
||||
cv.mark = 0;
|
||||
shdfnd::Array<ChainVert> chainVerts(mTetVertices.size(), cv);
|
||||
shdfnd::Array<int> chainVertNrs;
|
||||
|
||||
int mark = 1;
|
||||
|
||||
int i = 0;
|
||||
while (i < (int)edges.size()) {
|
||||
SortEdge &e0 = edges[i];
|
||||
int edgeNr = mTetEdges.size();
|
||||
te.init(e0.i0, e0.i1);
|
||||
te.firstTet = mEdgeTetNrs.size();
|
||||
te.numTets = 0;
|
||||
mark++;
|
||||
chainVertNrs.clear();
|
||||
do {
|
||||
SortEdge &e = edges[i];
|
||||
mTetEdgeNrs[6 * e.tetNr + e.edgeNr] = edgeNr;
|
||||
int i2 = -1;
|
||||
int i3 = -1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int id = mTetIndices[4 * e.tetNr + j];
|
||||
if (id != e0.i0 && id != e0.i1) {
|
||||
if (i2 < 0) i2 = id;
|
||||
else i3 = id;
|
||||
}
|
||||
}
|
||||
PX_ASSERT(i2 >= 0 && i3 >= 0);
|
||||
|
||||
// dihedral angle at edge
|
||||
PxVec3 &p0 = mTetVertices[e0.i0];
|
||||
PxVec3 &p1 = mTetVertices[e0.i1];
|
||||
PxVec3 &p2 = mTetVertices[i2];
|
||||
PxVec3 &p3 = mTetVertices[i3];
|
||||
PxVec3 n2 = (p1-p0).cross(p2-p0); n2.normalize();
|
||||
if ((p3-p0).dot(n2) > 0.0f) n2 = -n2;
|
||||
PxVec3 n3 = (p1-p0).cross(p3-p0); n3.normalize();
|
||||
if ((p2-p0).dot(n3) > 0.0f) n3 = -n3;
|
||||
float dot = n2.dot(n3);
|
||||
float dihed = PxPi - PxAcos(dot);
|
||||
|
||||
// chain for ordering tets of edge correctly
|
||||
ChainVert &cv2 = chainVerts[i2];
|
||||
ChainVert &cv3 = chainVerts[i3];
|
||||
if (cv2.mark != mark) { cv2.adjVert0 = -1; cv2.adjVert1 = -1; cv2.mark = mark; }
|
||||
if (cv3.mark != mark) { cv3.adjVert0 = -1; cv3.adjVert1 = -1; cv3.mark = mark; }
|
||||
|
||||
if (cv2.adjVert0 < 0) { cv2.adjVert0 = i3; cv2.tet0 = e.tetNr; cv2.dihed0 = dihed; }
|
||||
else { cv2.adjVert1 = i3; cv2.tet1 = e.tetNr; cv2.dihed1 = dihed; }
|
||||
if (cv3.adjVert0 < 0) { cv3.adjVert0 = i2; cv3.tet0 = e.tetNr; cv3.dihed0 = dihed; }
|
||||
else { cv3.adjVert1 = i2; cv3.tet1 = e.tetNr; cv3.dihed1 = dihed; }
|
||||
|
||||
chainVertNrs.pushBack(i2);
|
||||
chainVertNrs.pushBack(i3);
|
||||
i++;
|
||||
}
|
||||
while (i < (int)edges.size() && edges[i] == e0);
|
||||
|
||||
te.numTets = chainVertNrs.size() / 2;
|
||||
// find chain start;
|
||||
int startVertNr = -1;
|
||||
for (int j = 0; j < (int)chainVertNrs.size(); j++) {
|
||||
ChainVert &cv = chainVerts[chainVertNrs[j]];
|
||||
if (cv.adjVert0 < 0 || cv.adjVert1 < 0) {
|
||||
startVertNr = chainVertNrs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
te.onSurface = startVertNr >= 0;
|
||||
mTetEdges.pushBack(te);
|
||||
|
||||
int curr = startVertNr;
|
||||
if (curr < 0) curr = chainVertNrs[0];
|
||||
int prev = -1;
|
||||
|
||||
// collect adjacent tetrahedra
|
||||
for (int j = 0; j < te.numTets; j++) {
|
||||
ChainVert &cv = chainVerts[curr];
|
||||
int next;
|
||||
if (cv.adjVert0 == prev) {
|
||||
next = cv.adjVert1;
|
||||
mEdgeTetNrs.pushBack(cv.tet1);
|
||||
mEdgeTetAngles.pushBack(cv.dihed1);
|
||||
}
|
||||
else {
|
||||
next = cv.adjVert0;
|
||||
mEdgeTetNrs.pushBack(cv.tet0);
|
||||
mEdgeTetAngles.pushBack(cv.dihed0);
|
||||
}
|
||||
prev = curr;
|
||||
curr = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool CompoundCreator::tetHasColor(int tetNr, int color)
|
||||
{
|
||||
int nr = mTetFirstColor[tetNr];
|
||||
while (nr >= 0) {
|
||||
if (mTetColors[nr].color == color)
|
||||
return true;
|
||||
nr = mTetColors[nr].next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool CompoundCreator::tetAddColor(int tetNr, int color)
|
||||
{
|
||||
if (tetHasColor(tetNr, color))
|
||||
return false;
|
||||
Color c;
|
||||
c.color = color;
|
||||
c.next = mTetFirstColor[tetNr];
|
||||
|
||||
if (mTetColorsFirstEmpty <= 0) { // new entry
|
||||
mTetFirstColor[tetNr] = mTetColors.size();
|
||||
mTetColors.pushBack(c);
|
||||
}
|
||||
else { // take from empty list
|
||||
int newNr = mTetColorsFirstEmpty;
|
||||
mTetFirstColor[tetNr] = newNr;
|
||||
mTetColorsFirstEmpty = mTetColors[newNr].next;
|
||||
mTetColors[newNr] = c;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool CompoundCreator::tetRemoveColor(int tetNr, int color)
|
||||
{
|
||||
int nr = mTetFirstColor[tetNr];
|
||||
int prev = -1;
|
||||
while (nr >= 0) {
|
||||
if (mTetColors[nr].color == color) {
|
||||
if (prev < 0)
|
||||
mTetFirstColor[tetNr] = mTetColors[nr].next;
|
||||
else
|
||||
mTetColors[prev].next = mTetColors[nr].next;
|
||||
|
||||
// add to empty list
|
||||
mTetColors[nr].next = mTetColorsFirstEmpty;
|
||||
mTetColorsFirstEmpty = nr;
|
||||
return true;
|
||||
}
|
||||
prev = nr;
|
||||
nr = mTetColors[nr].next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
int CompoundCreator::tetNumColors(int tetNr)
|
||||
{
|
||||
int num = 0;
|
||||
int nr = mTetFirstColor[tetNr];
|
||||
while (nr >= 0) {
|
||||
num++;
|
||||
nr = mTetColors[nr].next;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::deleteColors()
|
||||
{
|
||||
mTetFirstColor.resize(mTetIndices.size()/4, -1);
|
||||
mTetColors.clear();
|
||||
mTetColorsFirstEmpty = -1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool CompoundCreator::tryTet(int tetNr, int color)
|
||||
{
|
||||
if (tetNr < 0)
|
||||
return false;
|
||||
|
||||
//if (mTetColors[tetNr] >= 0)
|
||||
// return false;
|
||||
|
||||
if (tetHasColor(tetNr, color))
|
||||
return false;
|
||||
|
||||
mTestEdges.clear();
|
||||
mAddedTets.clear();
|
||||
|
||||
tetAddColor(tetNr, color);
|
||||
mAddedTets.pushBack(tetNr);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
mTestEdges.pushBack(mTetEdgeNrs[6*tetNr+i]);
|
||||
|
||||
bool failed = false;
|
||||
|
||||
while (mTestEdges.size() > 0) {
|
||||
int edgeNr = mTestEdges[mTestEdges.size()-1];
|
||||
mTestEdges.popBack();
|
||||
|
||||
TetEdge &e = mTetEdges[edgeNr];
|
||||
bool anyOtherCol = false;
|
||||
float sumAng = 0.0f;
|
||||
for (int i = 0; i < e.numTets; i++) {
|
||||
int edgeTetNr = mEdgeTetNrs[e.firstTet + i];
|
||||
if (tetHasColor(edgeTetNr, color))
|
||||
sumAng += mEdgeTetAngles[e.firstTet + i];
|
||||
else if (tetNumColors(edgeTetNr) > 0)
|
||||
anyOtherCol = true;
|
||||
}
|
||||
if (sumAng < CONVEX_THRESHOLD)
|
||||
continue;
|
||||
|
||||
// if (e.onSurface || anyOtherCol) {
|
||||
if (e.onSurface) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < e.numTets; i++) {
|
||||
int edgeTetNr = mEdgeTetNrs[e.firstTet + i];
|
||||
if (!tetHasColor(edgeTetNr, color)) {
|
||||
tetAddColor(edgeTetNr, color);
|
||||
mAddedTets.pushBack(edgeTetNr);
|
||||
for (int j = 0; j < 6; j++)
|
||||
mTestEdges.pushBack(mTetEdgeNrs[6*edgeTetNr+j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failed) {
|
||||
for (int i = 0; i < (int)mAddedTets.size(); i++)
|
||||
tetRemoveColor(mAddedTets[i], color);
|
||||
mAddedTets.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::colorTets()
|
||||
{
|
||||
int numTets = mTetIndices.size() / 4;
|
||||
deleteColors();
|
||||
|
||||
int color = 0;
|
||||
shdfnd::Array<int> edges;
|
||||
shdfnd::Array<int> faces;
|
||||
|
||||
for (int i = 0; i < numTets; i++) {
|
||||
if (tetNumColors(i) > 0)
|
||||
continue;
|
||||
|
||||
tetAddColor(i, color);
|
||||
faces.clear();
|
||||
faces.pushBack(4*i);
|
||||
faces.pushBack(4*i+1);
|
||||
faces.pushBack(4*i+2);
|
||||
faces.pushBack(4*i+3);
|
||||
|
||||
while (faces.size() > 0) {
|
||||
int faceNr = faces[faces.size()-1];
|
||||
faces.popBack();
|
||||
|
||||
int adjTetNr = mTetNeighbors[faceNr];
|
||||
|
||||
if (adjTetNr < 0)
|
||||
continue;
|
||||
|
||||
//if (tetNumColors(adjTetNr) > 0)
|
||||
// continue;
|
||||
|
||||
if (!tryTet(adjTetNr, color))
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < (int)mAddedTets.size(); j++) {
|
||||
int addedTet = mAddedTets[j];
|
||||
for (int k = 0; k < 4; k++) {
|
||||
int adj = mTetNeighbors[4*addedTet+k];
|
||||
if (adj >= 0 && !tetHasColor(adj, color))
|
||||
faces.pushBack(4*addedTet+k);
|
||||
}
|
||||
}
|
||||
}
|
||||
color++;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void CompoundCreator::colorsToConvexes()
|
||||
{
|
||||
mGeom.clear();
|
||||
|
||||
int numTets = mTetIndices.size() / 4;
|
||||
int numColors = 0;
|
||||
for (int i = 0; i < (int)mTetColors.size(); i++) {
|
||||
int color = mTetColors[i].color;
|
||||
if (color >= numColors)
|
||||
numColors = color+1;
|
||||
}
|
||||
|
||||
shdfnd::Array<bool> colorVisited(numColors, false);
|
||||
shdfnd::Array<int> queue;
|
||||
shdfnd::Array<int> globalToLocal(mTetVertices.size(), -1);
|
||||
|
||||
shdfnd::Array<int> tetMarks(numTets, 0);
|
||||
shdfnd::Array<int> vertMarks(mTetVertices.size(), 0);
|
||||
int mark = 1;
|
||||
|
||||
shdfnd::Array<int> colorToConvexNr;
|
||||
|
||||
CompoundGeometry::Convex c;
|
||||
|
||||
for (int i = 0; i < numTets; i++) {
|
||||
int nr = mTetFirstColor[i];
|
||||
while (nr >= 0) {
|
||||
int color = mTetColors[nr].color;
|
||||
nr = mTetColors[nr].next;
|
||||
|
||||
if (colorVisited[color])
|
||||
continue;
|
||||
colorVisited[color] = true;
|
||||
|
||||
if ((int)colorToConvexNr.size() <= color)
|
||||
colorToConvexNr.resize(color+1, -1);
|
||||
colorToConvexNr[color] = mGeom.convexes.size();
|
||||
|
||||
queue.clear();
|
||||
queue.pushBack(i);
|
||||
|
||||
mGeom.initConvex(c);
|
||||
mark++;
|
||||
c.numVerts = 0;
|
||||
|
||||
// flood fill
|
||||
while (!queue.empty()) {
|
||||
int tetNr = queue[queue.size()-1];
|
||||
queue.popBack();
|
||||
if (tetMarks[tetNr] == mark)
|
||||
continue;
|
||||
tetMarks[tetNr] = mark;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int adjNr = mTetNeighbors[4*tetNr + j];
|
||||
if (adjNr < 0 || !tetHasColor(adjNr, color)) {
|
||||
// create new face
|
||||
mGeom.indices.pushBack(3); // face size
|
||||
int flags = 0;
|
||||
if (adjNr < 0) flags |= CompoundGeometry::FF_OBJECT_SURFACE;
|
||||
mGeom.indices.pushBack(flags);
|
||||
|
||||
for (int k = 0; k < 3; k++) {
|
||||
int id = mTetIndices[4*tetNr + tetFaceIds[j][k]];
|
||||
if (vertMarks[id] != mark) {
|
||||
vertMarks[id] = mark;
|
||||
globalToLocal[id] = c.numVerts;
|
||||
c.numVerts++;
|
||||
mGeom.vertices.pushBack(mTetVertices[id]);
|
||||
}
|
||||
mGeom.indices.pushBack(globalToLocal[id]);
|
||||
}
|
||||
c.numFaces++;
|
||||
}
|
||||
if (adjNr >= 0) {
|
||||
// add neighbors
|
||||
int colNr = mTetFirstColor[adjNr];
|
||||
while (colNr >= 0) {
|
||||
int adjColor = mTetColors[colNr].color;
|
||||
colNr = mTetColors[colNr].next;
|
||||
if (adjColor != color) {
|
||||
bool isNew = true;
|
||||
for (int k = 0; k < c.numNeighbors; k++) {
|
||||
if (mGeom.neighbors[c.firstNeighbor+k] == adjColor) {
|
||||
isNew = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isNew) {
|
||||
mGeom.neighbors.pushBack(adjColor);
|
||||
c.numNeighbors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adjNr < 0 || !tetHasColor(adjNr, color) || tetMarks[adjNr] == mark)
|
||||
continue;
|
||||
queue.pushBack(adjNr);
|
||||
}
|
||||
}
|
||||
mGeom.convexes.pushBack(c);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)mGeom.neighbors.size(); i++) {
|
||||
if (mGeom.neighbors[i] >= 0)
|
||||
mGeom.neighbors[i] = colorToConvexNr[mGeom.neighbors[i]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
130
kaplademo/source/kaplaDemo/Fracture/Core/CompoundCreatorBase.h
Normal file
130
kaplademo/source/kaplaDemo/Fracture/Core/CompoundCreatorBase.h
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef COMPOUND_CREATOR_BASE_H
|
||||
#define COMPOUND_CREATOR_BASE_H
|
||||
|
||||
// Matthias Mueller-Fischer
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxTransform.h>
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
#include "CompoundGeometryBase.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxConvexMeshGeometry;
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
class SimScene;
|
||||
// ---------------------------------------------------------------------------------------
|
||||
class CompoundCreator : public ::physx::shdfnd::UserAllocated {
|
||||
friend class SimScene;
|
||||
public:
|
||||
// direct
|
||||
void createTorus(float r0, float r1, int numSegs0, int numSegs1, const PxTransform *trans = NULL);
|
||||
void createCylinder(float r, float h, int numSegs, const PxTransform *trans = NULL);
|
||||
void createBox(const PxVec3 &dims, const PxTransform *trans = NULL, bool clearShape = true);
|
||||
void createSphere(const PxVec3 &dims, int resolution = 5, const PxTransform *trans = NULL);
|
||||
void fromTetraMesh(const shdfnd::Array<PxVec3> &tetVerts, const shdfnd::Array<int> &tetIndices);
|
||||
|
||||
void createFromConvexMesh(const PxConvexMeshGeometry& convexGeom, PxTransform offset = PxTransform(PxIdentity), bool clear = true);
|
||||
|
||||
|
||||
const CompoundGeometry &getGeometry() { return mGeom; }
|
||||
|
||||
virtual void debugDraw() {}
|
||||
|
||||
protected:
|
||||
CompoundCreator(SimScene* scene): mScene(scene) {}
|
||||
virtual ~CompoundCreator() {}
|
||||
|
||||
SimScene* mScene;
|
||||
|
||||
static int tetFaceIds[4][3];
|
||||
static int tetEdgeVerts[6][2];
|
||||
static int tetFaceEdges[4][3];
|
||||
|
||||
void computeTetNeighbors();
|
||||
void computeTetEdges();
|
||||
void colorTets();
|
||||
void colorsToConvexes();
|
||||
|
||||
bool tetHasColor(int tetNr, int color);
|
||||
bool tetAddColor(int tetNr, int color);
|
||||
bool tetRemoveColor(int tetNr, int color);
|
||||
int tetNumColors(int tetNr);
|
||||
void deleteColors();
|
||||
|
||||
bool tryTet(int tetNr, int color);
|
||||
|
||||
// from tet mesh
|
||||
shdfnd::Array<PxVec3> mTetVertices;
|
||||
shdfnd::Array<int> mTetIndices;
|
||||
shdfnd::Array<int> mTetNeighbors;
|
||||
|
||||
shdfnd::Array<int> mTetFirstColor;
|
||||
struct Color {
|
||||
int color;
|
||||
int next;
|
||||
};
|
||||
int mTetColorsFirstEmpty;
|
||||
shdfnd::Array<Color> mTetColors;
|
||||
|
||||
struct TetEdge {
|
||||
void init(int i0, int i1) { this->i0 = i0; this->i1 = i1; firstTet = 0; numTets = 0; onSurface = false; }
|
||||
int i0, i1;
|
||||
int firstTet, numTets;
|
||||
bool onSurface;
|
||||
};
|
||||
shdfnd::Array<TetEdge> mTetEdges;
|
||||
shdfnd::Array<int> mTetEdgeNrs;
|
||||
shdfnd::Array<int> mEdgeTetNrs;
|
||||
shdfnd::Array<float> mEdgeTetAngles;
|
||||
|
||||
shdfnd::Array<int> mAddedTets;
|
||||
shdfnd::Array<int> mTestEdges;
|
||||
|
||||
// input
|
||||
shdfnd::Array<PxVec3> mVertices;
|
||||
shdfnd::Array<int> mIndices;
|
||||
|
||||
// output
|
||||
CompoundGeometry mGeom;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,113 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include "CompoundGeometryBase.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
void CompoundGeometry::clear()
|
||||
{
|
||||
convexes.clear();
|
||||
vertices.clear();;
|
||||
normals.clear();
|
||||
indices.clear();
|
||||
neighbors.clear();
|
||||
planes.clear();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
bool CompoundGeometry::loadFromFile(const char * /*filename*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
bool CompoundGeometry::saveFromFile(const char * /*filename*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
void CompoundGeometry::initConvex(Convex &c)
|
||||
{
|
||||
c.firstVert = vertices.size();
|
||||
c.numVerts = 0;
|
||||
c.firstNormal = normals.size();
|
||||
c.firstIndex = indices.size();
|
||||
c.numFaces = 0;
|
||||
c.firstPlane = 0;
|
||||
c.firstNeighbor = neighbors.size();
|
||||
c.numNeighbors = 0;
|
||||
c.radius = 0.f;
|
||||
c.isSphere = false;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
void CompoundGeometry::derivePlanes()
|
||||
{
|
||||
planes.clear();
|
||||
PxPlane p;
|
||||
|
||||
for (int i = 0; i < (int)convexes.size(); i++) {
|
||||
Convex &c = convexes[i];
|
||||
c.firstPlane = planes.size();
|
||||
int *ids = &indices[c.firstIndex];
|
||||
PxVec3 *verts = &vertices[c.firstVert];
|
||||
for (int j = 0; j < c.numFaces; j++) {
|
||||
int num = *ids++;
|
||||
*ids++; //int flags = *ids++;
|
||||
if (num < 3)
|
||||
p = PxPlane(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
else {
|
||||
p.n = PxVec3(0.0f, 0.0f, 0.0f);
|
||||
for (int k = 1; k < num-1; k++) {
|
||||
const PxVec3 &p0 = verts[ids[0]];
|
||||
const PxVec3 &p1 = verts[ids[k]];
|
||||
const PxVec3 &p2 = verts[ids[k+1]];
|
||||
p.n += (p1-p0).cross(p2-p1);
|
||||
}
|
||||
p.n.normalize();
|
||||
p.d = p.n.dot(verts[ids[0]]);
|
||||
}
|
||||
planes.pushBack(p);
|
||||
ids += num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,95 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef COMPOUND_GEOMETRY_BASE
|
||||
#define COMPOUND_GEOMETRY_BASE
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxPlane.h>
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
class CompoundGeometry : public ::physx::shdfnd::UserAllocated
|
||||
{
|
||||
public:
|
||||
CompoundGeometry() {}
|
||||
virtual ~CompoundGeometry() {}
|
||||
bool loadFromFile(const char *filename);
|
||||
bool saveFromFile(const char *filename);
|
||||
void clear();
|
||||
void derivePlanes();
|
||||
|
||||
virtual void debugDraw(int /*maxConvexes*/ = 0) const {}
|
||||
|
||||
struct Convex { // init using CompoundGeometry::initConvex()
|
||||
int firstVert;
|
||||
int numVerts;
|
||||
int firstNormal; // one per face index! If not provided (see face flags) face normal is used
|
||||
int firstIndex;
|
||||
int numFaces;
|
||||
int firstPlane;
|
||||
int firstNeighbor;
|
||||
int numNeighbors;
|
||||
float radius;
|
||||
bool isSphere;
|
||||
};
|
||||
|
||||
void initConvex(Convex &c);
|
||||
|
||||
shdfnd::Array<Convex> convexes;
|
||||
shdfnd::Array<PxVec3> vertices;
|
||||
shdfnd::Array<PxVec3> normals; // one per face and vertex!
|
||||
// face size, face flags, id, id, .., face size, face flags, id ..
|
||||
shdfnd::Array<int> indices;
|
||||
shdfnd::Array<int> neighbors;
|
||||
|
||||
shdfnd::Array<PxPlane> planes; // derived for faster cuts
|
||||
|
||||
enum FaceFlags {
|
||||
FF_OBJECT_SURFACE = 1,
|
||||
FF_HAS_NORMALS = 2,
|
||||
FF_INVISIBLE = 4,
|
||||
FF_NEW = 8,
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
1343
kaplademo/source/kaplaDemo/Fracture/Core/ConvexBase.cpp
Normal file
1343
kaplademo/source/kaplaDemo/Fracture/Core/ConvexBase.cpp
Normal file
File diff suppressed because it is too large
Load Diff
239
kaplademo/source/kaplaDemo/Fracture/Core/ConvexBase.h
Normal file
239
kaplademo/source/kaplaDemo/Fracture/Core/ConvexBase.h
Normal file
@ -0,0 +1,239 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef CONVEX_BASE
|
||||
#define CONVEX_BASE
|
||||
|
||||
#include <PxPhysics.h>
|
||||
#include <PxCooking.h>
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxPlane.h>
|
||||
#include <foundation/PxBounds3.h>
|
||||
#include <foundation/PxTransform.h>
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
class physx::PxShape;
|
||||
class physx::PxActor;
|
||||
class physx::PxScene;
|
||||
class physx::PxConvexMesh;
|
||||
|
||||
class Compound;
|
||||
class CompoundGeometry;
|
||||
class SimScene;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
class Convex : public ::physx::shdfnd::UserAllocated
|
||||
{
|
||||
friend class SimScene;
|
||||
protected:
|
||||
Convex(SimScene* scene);
|
||||
public:
|
||||
virtual ~Convex();
|
||||
|
||||
void createFromConvex(const Convex *convex, const PxTransform *trans = NULL, int matID = 0, int surfMatID = 0);
|
||||
void createFromGeometry(const CompoundGeometry &geom, int convexNr, const PxMat44 *trans = NULL, int matID = 0, int surfMatID = 0);
|
||||
|
||||
void transform(const PxMat44 &trans);
|
||||
PxVec3 centerAtZero();
|
||||
PxVec3 getCenter() const;
|
||||
void setTexScale(float texScale) { mTexScale = texScale; }
|
||||
void increaseRefCounter() { mRefCounter++; }
|
||||
int decreaseRefCounter() { mRefCounter--; return mRefCounter; }
|
||||
|
||||
bool rayCast(const PxVec3 &ray, const PxVec3 &dir, float &dist, PxVec3 &normal) const;
|
||||
bool collide(const PxVec3 &pos, float r, float &penetration, PxVec3 &surfaceNormal, PxVec3 &surfaceVel) const;
|
||||
|
||||
void intersectWithConvex(const PxPlane *planes, int numPlanes, const PxMat44 &trans, bool &empty);
|
||||
|
||||
virtual void draw(bool /*debug*/ = false) {}
|
||||
|
||||
PxConvexMesh* createPxConvexMesh(Compound *parent, PxPhysics *pxPhysics, PxCooking *pxCooking);
|
||||
void setPxActor(PxRigidActor *actor);
|
||||
void setLocalPose(const PxTransform &pose);
|
||||
|
||||
// accessors
|
||||
Compound *getParent() { return mParent; }
|
||||
const Compound *getParent() const { return mParent; }
|
||||
const PxConvexMesh *getPxConvexMesh() const { return mPxConvexMesh; }
|
||||
PxConvexMesh *getPxConvexMesh() { return mPxConvexMesh; }
|
||||
|
||||
const shdfnd::Array<PxPlane> &getPlanes() const { return mPlanes; };
|
||||
const PxBounds3 &getBounds() const { return mBounds; }
|
||||
void getWorldBounds(PxBounds3 &bounds) const;
|
||||
void getLocalBounds(PxBounds3 &bounds) const;
|
||||
float getVolume() const;
|
||||
void removeInvisibleFacesFlags();
|
||||
void updateFaceVisibility(const float *faceCoverage);
|
||||
void clearFraceFlags(unsigned int flag);
|
||||
|
||||
struct Face {
|
||||
void init() {
|
||||
firstIndex = 0; numIndices = 0; flags = 0; firstNormal = 0;
|
||||
}
|
||||
int firstIndex;
|
||||
int numIndices;
|
||||
int flags;
|
||||
int firstNormal;
|
||||
|
||||
|
||||
};
|
||||
|
||||
const shdfnd::Array<Face> &getFaces() const { return mFaces; }
|
||||
const shdfnd::Array<int> &getIndices() const { return mIndices; }
|
||||
const shdfnd::Array<PxVec3> &getVertices() const { return mVertices; }
|
||||
|
||||
const shdfnd::Array<PxVec3> &getVisVertices() const { return mVisVertices; }
|
||||
const shdfnd::Array<PxVec3> &getVisNormals() const { return mVisNormals; }
|
||||
const shdfnd::Array<PxVec3> &getVisTangents() const { return mVisTangents; }
|
||||
const shdfnd::Array<float> &getVisTexCoords() const { return mVisTexCoords; }
|
||||
const shdfnd::Array<int> &getVisTriIndices() const { return mVisTriIndices; }
|
||||
|
||||
const shdfnd::Array<int> &getVisPolyStarts() const { return mVisPolyStarts; }
|
||||
const shdfnd::Array<int> &getVisPolyIndices() const { return mVisPolyIndices; }
|
||||
const shdfnd::Array<int> &getVisPolyNeighbors() const { return mVisPolyNeighbors; }
|
||||
|
||||
PxVec3 getMaterialOffset() const { return mMaterialOffset; }
|
||||
void setMaterialOffset(const PxVec3 &offset);
|
||||
PxTransform getGlobalPose() const;
|
||||
PxTransform getLocalPose() const;
|
||||
|
||||
bool isGhostConvex() const { return mIsGhostConvex; }
|
||||
|
||||
// explicit visual mesh
|
||||
bool hasExplicitVisMesh() const { return mHasExplicitVisMesh; }
|
||||
bool setExplicitVisMeshFromTriangles(int numVertices, const PxVec3 *vertices, const PxVec3 *normals, const PxVec2 *texcoords,
|
||||
int numIndices, const PxU32 *indices, PxTransform *trans = NULL, const PxVec3* scale = NULL);
|
||||
bool setExplicitVisMeshFromPolygons(int numVertices, const PxVec3 *vertices, const PxVec3 *normals,
|
||||
const PxVec3 *tangents, const float *texCoords,
|
||||
int numPolygons, const int *polyStarts, // numPolygons+1 entries
|
||||
int numIndices, const int *indices, PxTransform *trans = NULL, const PxVec3* scale = NULL);
|
||||
void createVisTrisFromPolys();
|
||||
void createVisMeshFromConvex();
|
||||
void transformVisualMesh(const PxTransform &trans);
|
||||
bool insideVisualMesh(const PxVec3 &pos) const;
|
||||
|
||||
void fitToVisualMesh(bool &cutEmpty, int numFitDirections = 3);
|
||||
|
||||
bool isOnConvexSurface(const PxVec3 pts) const;
|
||||
bool check();
|
||||
|
||||
PxActor* getActor();
|
||||
bool insideFattened(const PxVec3 &pos, float r) const;
|
||||
|
||||
bool use2dTexture() const { return mUse2dTexture; }
|
||||
bool isIndestructible() const { return mIndestructible; }
|
||||
int getMaterialId() const { return mMaterialId; }
|
||||
int getSurfaceMaterialId() const { return mSurfaceMaterialId; }
|
||||
void setSurfaceMaterialId(int id) { mSurfaceMaterialId = id; }
|
||||
|
||||
void setModelIslandNr(int nr) { mModelIslandNr = nr; }
|
||||
int getModelIslandNr() const { return mModelIslandNr; }
|
||||
|
||||
void setConvexRendererInfo(int groupNr, int groupPos) const { mConvexRendererGroupNr = groupNr; mConvexRendererGroupPos = groupPos; }
|
||||
int getConvexRendererGroupNr() const { return mConvexRendererGroupNr; }
|
||||
int getConvexRendererGroupPos() const { return mConvexRendererGroupPos; }
|
||||
|
||||
void setIsFarConvex(bool v) { mIsFarConvex = v; }
|
||||
bool getIsFarConvex() { return mIsFarConvex; }
|
||||
|
||||
protected:
|
||||
void clear();
|
||||
void finalize();
|
||||
void updateBounds();
|
||||
void updatePlanes();
|
||||
|
||||
bool computeVisMeshNeighbors();
|
||||
void computeVisTangentsFromPoly();
|
||||
bool cutVisMesh(const PxVec3 &localPlaneN, float localPlaneD, bool &cutEmpty);
|
||||
bool cut(const PxVec3 &localPlaneN, float localPlaneD, bool &cutEmpty, bool setNewFaceFlag = true);
|
||||
|
||||
bool rayCastConvex(const PxVec3 &orig, const PxVec3 &dir, float &dist, PxVec3 &normal) const;
|
||||
bool rayCastVisMesh(const PxVec3 &orig, const PxVec3 &dir, float &dist, PxVec3 &normal) const;
|
||||
|
||||
SimScene* mScene;
|
||||
|
||||
shdfnd::Array<Face> mFaces;
|
||||
shdfnd::Array<int> mIndices;
|
||||
shdfnd::Array<PxVec3> mVertices;
|
||||
shdfnd::Array<PxVec3> mNormals;
|
||||
shdfnd::Array<PxPlane> mPlanes;
|
||||
|
||||
shdfnd::Array<PxVec3> mVisVertices;
|
||||
shdfnd::Array<PxVec3> mVisNormals;
|
||||
shdfnd::Array<PxVec3> mVisTangents;
|
||||
shdfnd::Array<float> mVisTexCoords;
|
||||
shdfnd::Array<int> mVisTriIndices;
|
||||
|
||||
int mRefCounter;
|
||||
bool mHasExplicitVisMesh;
|
||||
bool mIsGhostConvex;
|
||||
shdfnd::Array<int> mVisPolyStarts; // for explicit mesh only
|
||||
shdfnd::Array<int> mVisPolyIndices;
|
||||
shdfnd::Array<int> mVisPolyNeighbors;
|
||||
|
||||
Convex *mNewConvex; // temporary buffer for cut operations
|
||||
|
||||
Compound *mParent;
|
||||
PxRigidActor *mPxActor;
|
||||
PxTransform mLocalPose;
|
||||
PxConvexMesh *mPxConvexMesh;
|
||||
|
||||
PxBounds3 mBounds;
|
||||
mutable float mVolume;
|
||||
mutable bool mVolumeDirty;
|
||||
PxVec3 mMaterialOffset;
|
||||
float mTexScale;
|
||||
int mModelIslandNr;
|
||||
|
||||
// material
|
||||
bool mUse2dTexture;
|
||||
bool mIndestructible;
|
||||
int mMaterialId;
|
||||
int mSurfaceMaterialId;
|
||||
|
||||
bool mIsFarConvex;
|
||||
|
||||
mutable int mConvexRendererGroupNr;
|
||||
mutable int mConvexRendererGroupPos;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
239
kaplademo/source/kaplaDemo/Fracture/Core/MeshBase.cpp
Normal file
239
kaplademo/source/kaplaDemo/Fracture/Core/MeshBase.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include <foundation/PxBounds3.h>
|
||||
|
||||
#include "MeshBase.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
void Mesh::updateNormals()
|
||||
{
|
||||
if (mVertices.empty())
|
||||
return;
|
||||
|
||||
PxVec3 zero(0.0f, 0.0f, 0.0f);
|
||||
|
||||
mNormals.resize(mVertices.size());
|
||||
for (int i = 0; i < (int)mNormals.size(); i++)
|
||||
mNormals[i] = zero;
|
||||
PxVec3 n;
|
||||
|
||||
PxU32 *idx = &mIndices[0];
|
||||
int numTriangles = mIndices.size() / 3;
|
||||
for (int i = 0; i < numTriangles; i++) {
|
||||
PxU32 i0 = *idx++;
|
||||
PxU32 i1 = *idx++;
|
||||
PxU32 i2 = *idx++;
|
||||
n = (mVertices[i1] - mVertices[i0]).cross(mVertices[i2] - mVertices[i0]);
|
||||
mNormals[i0] += n;
|
||||
mNormals[i1] += n;
|
||||
mNormals[i2] += n;
|
||||
}
|
||||
for (int i = 0; i < (int)mNormals.size(); i++) {
|
||||
if (!mNormals[i].isZero())
|
||||
mNormals[i].normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
void Mesh::getBounds(PxBounds3 &bounds, int subMeshNr) const
|
||||
{
|
||||
bounds.setEmpty();
|
||||
if (subMeshNr < 0 || subMeshNr >= (int)mSubMeshes.size()) {
|
||||
for (int i = 0; i < (int)mVertices.size(); i++)
|
||||
bounds.include(mVertices[i]);
|
||||
}
|
||||
else {
|
||||
const SubMesh &sm = mSubMeshes[subMeshNr];
|
||||
for (int i = 0; i < sm.numIndices; i++) {
|
||||
bounds.include(mVertices[mIndices[sm.firstIndex + i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
void Mesh::normalize(const PxVec3 ¢er, float diagonal)
|
||||
{
|
||||
if (mVertices.size() < 3)
|
||||
return;
|
||||
|
||||
PxBounds3 bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
float s = diagonal / bounds.getDimensions().magnitude();
|
||||
PxVec3 c = 0.5f * (bounds.minimum + bounds.maximum);
|
||||
|
||||
for (int i = 0; i < (int)mVertices.size(); i++)
|
||||
mVertices[i] = center + (mVertices[i] - c) * s;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
void Mesh::scale(float diagonal)
|
||||
{
|
||||
if (mVertices.size() < 3)
|
||||
return;
|
||||
|
||||
PxBounds3 bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
float s = diagonal / bounds.getDimensions().magnitude();
|
||||
for (int i = 0; i < (int)mVertices.size(); i++)
|
||||
mVertices[i] *= s;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
struct IdEdge {
|
||||
void set(PxU32 &i0, PxU32 &i1, int faceNr, int edgeNr) {
|
||||
if (i0 < i1) { this->i0 = i0; this->i1 = i1; }
|
||||
else { this->i0 = i1; this->i1 = i0; }
|
||||
this->faceNr = faceNr; this->edgeNr = edgeNr;
|
||||
}
|
||||
bool operator < (const IdEdge &e) const {
|
||||
if (i0 < e.i0) return true;
|
||||
if (i0 == e.i0 && i1 < e.i1) return true;
|
||||
return false;
|
||||
}
|
||||
bool operator == (const IdEdge &e) const { return i0 == e.i0 && i1 == e.i1; }
|
||||
PxU32 i0,i1;
|
||||
int faceNr, edgeNr;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
bool Mesh::computeNeighbors()
|
||||
{
|
||||
int numTris = mIndices.size() / 3;
|
||||
|
||||
shdfnd::Array<IdEdge> edges(3*numTris);
|
||||
|
||||
for (int i = 0; i < numTris; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
edges[3*i+j].set(mIndices[3*i+j], mIndices[3*i + (j+1)%3], i, j);
|
||||
}
|
||||
std::sort(edges.begin(), edges.end());
|
||||
|
||||
mNeighbors.clear();
|
||||
mNeighbors.resize(mIndices.size(), -1);
|
||||
bool manifold = true;
|
||||
int i = 0;
|
||||
while (i < (int)edges.size()) {
|
||||
IdEdge &e0 = edges[i];
|
||||
i++;
|
||||
if (i < (int)edges.size() && edges[i] == e0) {
|
||||
IdEdge &e1 = edges[i];
|
||||
mNeighbors[3* e0.faceNr + e0.edgeNr] = e1.faceNr;
|
||||
mNeighbors[3* e1.faceNr + e1.edgeNr] = e0.faceNr;
|
||||
i++;
|
||||
}
|
||||
while (i < (int)edges.size() && edges[i] == e0) {
|
||||
manifold = false;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return manifold;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
struct PosEdge {
|
||||
// not using indices for edge match but positions
|
||||
// so duplicated vertices are handled as one vertex
|
||||
static bool smaller(const PxVec3 &v0, const PxVec3 &v1) {
|
||||
if (v0.x < v1.x) return true;
|
||||
if (v0.x > v1.x) return false;
|
||||
if (v0.y < v1.y) return true;
|
||||
if (v0.y > v1.y) return false;
|
||||
return (v0.z < v1.z);
|
||||
}
|
||||
void set(const PxVec3 &v0, const PxVec3 &v1, int faceNr, int edgeNr) {
|
||||
if (smaller(v0,v1)) { this->v0 = v0; this->v1 = v1; }
|
||||
else { this->v0 = v1; this->v1 = v0; }
|
||||
this->faceNr = faceNr; this->edgeNr = edgeNr;
|
||||
}
|
||||
bool operator < (const PosEdge &e) const {
|
||||
if (smaller(v0, e.v0)) return true;
|
||||
if (v0 == e.v0 && smaller(v1, e.v1)) return true;
|
||||
return false;
|
||||
}
|
||||
bool operator == (const PosEdge &e) const { return v0 == e.v0 && v1 == e.v1; }
|
||||
PxVec3 v0,v1;
|
||||
int faceNr, edgeNr;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
bool Mesh::computeWeldedNeighbors()
|
||||
{
|
||||
int numTris = mIndices.size() / 3;
|
||||
shdfnd::Array<PosEdge> edges(3*numTris);
|
||||
|
||||
for (int i = 0; i < numTris; i++) {
|
||||
for (int j = 0; j < 3; j++)
|
||||
edges[3*i+j].set(mVertices[mIndices[3*i+j]], mVertices[mIndices[3*i + (j+1)%3]], i, j);
|
||||
}
|
||||
std::sort(edges.begin(), edges.end());
|
||||
|
||||
mNeighbors.clear();
|
||||
mNeighbors.resize(mIndices.size(), -1);
|
||||
bool manifold = true;
|
||||
int i = 0;
|
||||
while (i < (int)edges.size()) {
|
||||
PosEdge &e0 = edges[i];
|
||||
i++;
|
||||
if (i < (int)edges.size() && edges[i] == e0) {
|
||||
PosEdge &e1 = edges[i];
|
||||
mNeighbors[3* e0.faceNr + e0.edgeNr] = e1.faceNr;
|
||||
mNeighbors[3* e1.faceNr + e1.edgeNr] = e0.faceNr;
|
||||
i++;
|
||||
}
|
||||
while (i < (int)edges.size() && edges[i] == e0) {
|
||||
manifold = false;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return manifold;
|
||||
}
|
||||
|
||||
void Mesh::flipV()
|
||||
{
|
||||
for(PxU32 i = 0; i < mTexCoords.size(); i++)
|
||||
{
|
||||
mTexCoords[i].y = 1.0f - mTexCoords[i].y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
94
kaplademo/source/kaplaDemo/Fracture/Core/MeshBase.h
Normal file
94
kaplademo/source/kaplaDemo/Fracture/Core/MeshBase.h
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef MESH_BASE
|
||||
#define MESH_BASE
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxVec2.h>
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
class Mesh : public ::physx::shdfnd::UserAllocated
|
||||
{
|
||||
public:
|
||||
Mesh() {};
|
||||
virtual ~Mesh() {};
|
||||
|
||||
const shdfnd::Array<PxVec3> &getVertices() const { return mVertices; }
|
||||
const shdfnd::Array<PxVec3> &getNormals() const { return mNormals; }
|
||||
const shdfnd::Array<PxVec2> &getTexCoords() const { return mTexCoords; }
|
||||
const shdfnd::Array<PxU32> &getIndices() const { return mIndices; }
|
||||
const shdfnd::Array<int> &getNeighbors() const { return mNeighbors; }
|
||||
|
||||
struct SubMesh {
|
||||
void init() { /*name = "";*/ firstIndex = -1; numIndices = 0; }
|
||||
//std::string name;
|
||||
int firstIndex;
|
||||
int numIndices;
|
||||
};
|
||||
|
||||
const shdfnd::Array<SubMesh> &getSubMeshes() const { return mSubMeshes; }
|
||||
|
||||
void normalize(const PxVec3 ¢er, float diagonal);
|
||||
void scale(float diagonal);
|
||||
void getBounds(PxBounds3 &bounds, int subMeshNr = -1) const;
|
||||
|
||||
void flipV(); // flips v values to hand coordinate system change (Assumes normalized coordinates)
|
||||
|
||||
bool computeNeighbors();
|
||||
bool computeWeldedNeighbors();
|
||||
|
||||
protected:
|
||||
void clear();
|
||||
void updateNormals();
|
||||
|
||||
shdfnd::Array<PxVec3> mVertices;
|
||||
shdfnd::Array<PxVec3> mNormals;
|
||||
shdfnd::Array<PxVec2> mTexCoords;
|
||||
|
||||
shdfnd::Array<SubMesh> mSubMeshes;
|
||||
shdfnd::Array<PxU32> mIndices;
|
||||
shdfnd::Array<int> mNeighbors;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,299 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include "PolygonTriangulatorBase.h"
|
||||
#include <foundation/PxAssert.h>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
// ------ singleton pattern -----------------------------------------------------------
|
||||
|
||||
//static PolygonTriangulator *gPolygonTriangulator = NULL;
|
||||
//
|
||||
//PolygonTriangulator* PolygonTriangulator::getInstance()
|
||||
//{
|
||||
// if (gPolygonTriangulator == NULL) {
|
||||
// gPolygonTriangulator = PX_NEW(PolygonTriangulator)();
|
||||
// }
|
||||
// return gPolygonTriangulator;
|
||||
//}
|
||||
//
|
||||
//void PolygonTriangulator::destroyInstance()
|
||||
//{
|
||||
// if (gPolygonTriangulator != NULL) {
|
||||
// PX_DELETE(gPolygonTriangulator);
|
||||
// }
|
||||
// gPolygonTriangulator = NULL;
|
||||
//}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
PolygonTriangulator::PolygonTriangulator(SimScene* scene):
|
||||
mScene(scene)
|
||||
{
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
PolygonTriangulator::~PolygonTriangulator()
|
||||
{
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
float PolygonTriangulator::cross(const PxVec3 &p0, const PxVec3 &p1)
|
||||
{
|
||||
return p0.x * p1.y - p0.y * p1.x;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
bool PolygonTriangulator::inTriangle(const PxVec3 &p, const PxVec3 &p0, const PxVec3 &p1, const PxVec3 &p2)
|
||||
{
|
||||
float d0 = cross(p1 - p0, p - p0);
|
||||
float d1 = cross(p2 - p1, p - p1);
|
||||
float d2 = cross(p0 - p2, p - p2);
|
||||
return (d0 >= 0.0f && d1 >= 0.0f && d2 >= 0.0f) ||
|
||||
(d0 <= 0.0f && d1 <= 0.0f && d2 <= 0.0f);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
void PolygonTriangulator::triangulate(const PxVec3 *points, int numPoints, const int *indices, PxVec3 *planeNormal)
|
||||
{
|
||||
mIndices.clear();
|
||||
|
||||
if (numPoints < 3)
|
||||
return;
|
||||
if (numPoints == 3) {
|
||||
if (indices == NULL) {
|
||||
mIndices.pushBack(0);
|
||||
mIndices.pushBack(1);
|
||||
mIndices.pushBack(2);
|
||||
}
|
||||
else {
|
||||
mIndices.pushBack(indices[0]);
|
||||
mIndices.pushBack(indices[1]);
|
||||
mIndices.pushBack(indices[2]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool isConvex;
|
||||
importPoints(points, numPoints, indices, planeNormal, isConvex);
|
||||
|
||||
if (isConvex) { // fast path
|
||||
mIndices.resize(3*(numPoints-2));
|
||||
for (int i = 0; i < numPoints-2; i++) {
|
||||
mIndices[3*i] = 0;
|
||||
mIndices[3*i+1] = i+1;
|
||||
mIndices[3*i+2] = i+2;
|
||||
}
|
||||
}
|
||||
else
|
||||
clipEars();
|
||||
|
||||
if (indices != NULL) {
|
||||
for (int i = 0; i < (int)mIndices.size(); i++) {
|
||||
mIndices[i] = indices[mIndices[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
void PolygonTriangulator::importPoints(const PxVec3 *points, int numPoints, const int *indices, PxVec3 *planeNormal, bool &isConvex)
|
||||
{
|
||||
// find projection 3d -> 2d;
|
||||
PxVec3 n;
|
||||
|
||||
isConvex = true;
|
||||
|
||||
if (planeNormal)
|
||||
n = *planeNormal;
|
||||
else {
|
||||
PX_ASSERT(numPoints >= 3);
|
||||
n = PxVec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (int i = 1; i < numPoints-1; i++) {
|
||||
int i0 = 0;
|
||||
int i1 = i;
|
||||
int i2 = i+1;
|
||||
if (indices) {
|
||||
i0 = indices[i0];
|
||||
i1 = indices[i1];
|
||||
i2 = indices[i2];
|
||||
}
|
||||
const PxVec3 &p0 = points[i0];
|
||||
const PxVec3 &p1 = points[i1];
|
||||
const PxVec3 &p2 = points[i2];
|
||||
PxVec3 ni = (p1-p0).cross(p2-p0);
|
||||
if (i > 1 && ni.dot(n) < 0.0f)
|
||||
isConvex = false;
|
||||
n += ni;
|
||||
}
|
||||
}
|
||||
|
||||
n.normalize();
|
||||
PxVec3 t0,t1;
|
||||
|
||||
if (fabs(n.x) < fabs(n.y) && fabs(n.x) < fabs(n.z))
|
||||
t0 = PxVec3(1.0f, 0.0f, 0.0f);
|
||||
else if (fabs(n.y) < fabs(n.z))
|
||||
t0 = PxVec3(0.0f, 1.0f, 0.0f);
|
||||
else
|
||||
t0 = PxVec3(0.0f, 0.0f, 1.0f);
|
||||
t1 = n.cross(t0);
|
||||
t1.normalize();
|
||||
t0 = t1.cross(n);
|
||||
|
||||
mPoints.resize(numPoints);
|
||||
if (indices == NULL) {
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
mPoints[i] = PxVec3(points[i].dot(t0), points[i].dot(t1), 0.0f);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
const PxVec3 &p = points[indices[i]];
|
||||
mPoints[i] = PxVec3(p.dot(t0), p.dot(t1), 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
void PolygonTriangulator::clipEars()
|
||||
{
|
||||
// init
|
||||
int num = mPoints.size();
|
||||
|
||||
mCorners.resize(num);
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
Corner &c = mCorners[i];
|
||||
c.prev = (i > 0) ? i-1 : num-1;
|
||||
c.next = (i < num-1) ? i + 1 : 0;
|
||||
c.isEar = false;
|
||||
c.angle = 0.0f;
|
||||
PxVec3 &p0 = mPoints[c.prev];
|
||||
PxVec3 &p1 = mPoints[i];
|
||||
PxVec3 &p2 = mPoints[c.next];
|
||||
PxVec3 n1 = p1-p0;
|
||||
PxVec3 n2 = p2-p1;
|
||||
if (cross(n1, n2) > 0.0f) {
|
||||
n1.normalize();
|
||||
n2.normalize();
|
||||
c.angle = n1.dot(n2);
|
||||
|
||||
c.isEar = true;
|
||||
int nr = (i+2) % num;
|
||||
for (int j = 0; j < num-3; j++) {
|
||||
if (inTriangle(mPoints[nr], p0,p1,p2)) {
|
||||
c.isEar = false;
|
||||
break;
|
||||
}
|
||||
nr = (nr+1) % num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int firstCorner = 0;
|
||||
int numCorners = num;
|
||||
|
||||
while (numCorners > 3) {
|
||||
|
||||
// find best ear
|
||||
float minAng = FLT_MAX;
|
||||
int minNr = -1;
|
||||
|
||||
int nr = firstCorner;
|
||||
for (int i = 0; i < numCorners; i++) {
|
||||
Corner &c = mCorners[nr];
|
||||
if (c.isEar && c.angle < minAng) {
|
||||
minAng = c.angle;
|
||||
minNr = nr;
|
||||
}
|
||||
nr = c.next;
|
||||
}
|
||||
|
||||
// cut ear
|
||||
// assert(minNr >= 0);
|
||||
if (minNr < 0)
|
||||
break;
|
||||
Corner &cmin = mCorners[minNr];
|
||||
mIndices.pushBack(cmin.prev);
|
||||
mIndices.pushBack(minNr);
|
||||
mIndices.pushBack(cmin.next);
|
||||
mCorners[cmin.prev].next = cmin.next;
|
||||
mCorners[cmin.next].prev = cmin.prev;
|
||||
|
||||
if (firstCorner == minNr)
|
||||
firstCorner = cmin.next;
|
||||
numCorners--;
|
||||
if (numCorners == 3)
|
||||
break;
|
||||
|
||||
// new ears?
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int i1 = (i == 0) ? cmin.prev : cmin.next;
|
||||
int i0 = mCorners[i1].prev;
|
||||
int i2 = mCorners[i1].next;
|
||||
|
||||
PxVec3 &p0 = mPoints[i0];
|
||||
PxVec3 &p1 = mPoints[i1];
|
||||
PxVec3 &p2 = mPoints[i2];
|
||||
PxVec3 n1 = p1-p0;
|
||||
PxVec3 n2 = p2-p1;
|
||||
if (cross(n1, n2) > 0.0f) {
|
||||
n1.normalize();
|
||||
n2.normalize();
|
||||
mCorners[i1].angle = n1.dot(n2);
|
||||
|
||||
mCorners[i1].isEar = true;
|
||||
int nr = mCorners[i2].next;
|
||||
for (int j = 0; j < numCorners-3; j++) {
|
||||
if (inTriangle(mPoints[nr], p0,p1,p2)) {
|
||||
mCorners[i1].isEar = false;
|
||||
break;
|
||||
}
|
||||
nr = mCorners[nr].next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int id = firstCorner;
|
||||
mIndices.pushBack(id);
|
||||
id = mCorners[id].next;
|
||||
mIndices.pushBack(id);
|
||||
id = mCorners[id].next;
|
||||
mIndices.pushBack(id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,86 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef POLYGON_TRIANGULATOR_BASE_H
|
||||
#define POLYGON_TRIANGULATOR_BASE_H
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <foundation/PxMath.h>
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
class PolygonTriangulator : public ::physx::shdfnd::UserAllocated {
|
||||
friend class SimScene;
|
||||
public:
|
||||
// singleton pattern
|
||||
//static PolygonTriangulator* getInstance();
|
||||
//static void destroyInstance();
|
||||
|
||||
void triangulate(const PxVec3 *points, int numPoints, const int *indices = NULL, PxVec3 *planeNormal = NULL);
|
||||
const shdfnd::Array<int> &getIndices() const { return mIndices; }
|
||||
|
||||
protected:
|
||||
void importPoints(const PxVec3 *points, int numPoints, const int *indices, PxVec3 *planeNormal, bool &isConvex);
|
||||
void clipEars();
|
||||
|
||||
inline float cross(const PxVec3 &p0, const PxVec3 &p1);
|
||||
bool inTriangle(const PxVec3 &p, const PxVec3 &p0, const PxVec3 &p1, const PxVec3 &p2);
|
||||
|
||||
PolygonTriangulator(SimScene* scene);
|
||||
virtual ~PolygonTriangulator();
|
||||
|
||||
SimScene* mScene;
|
||||
|
||||
shdfnd::Array<PxVec3> mPoints;
|
||||
shdfnd::Array<int> mIndices;
|
||||
|
||||
struct Corner {
|
||||
int prev;
|
||||
int next;
|
||||
bool isEar;
|
||||
float angle;
|
||||
};
|
||||
shdfnd::Array<Corner> mCorners;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
364
kaplademo/source/kaplaDemo/Fracture/Core/SimSceneBase.cpp
Normal file
364
kaplademo/source/kaplaDemo/Fracture/Core/SimSceneBase.cpp
Normal file
@ -0,0 +1,364 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#include "PsHashMap.h"
|
||||
#include "SimSceneBase.h"
|
||||
#include <foundation/PxMat44.h>
|
||||
#include "PxRigidBodyExt.h"
|
||||
#include "PxPhysics.h"
|
||||
#include "PxCooking.h"
|
||||
#include "PxShape.h"
|
||||
|
||||
#include "ActorBase.h"
|
||||
#include "CompoundBase.h"
|
||||
#include "ConvexBase.h"
|
||||
#include "CompoundCreatorBase.h"
|
||||
#include "PolygonTriangulatorBase.h"
|
||||
|
||||
#include "RTdef.h"
|
||||
|
||||
#include "PhysXMacros.h"
|
||||
#include "PxScene.h"
|
||||
#include "PxD6Joint.h"
|
||||
|
||||
#define USE_CONVEX_RENDERER 1
|
||||
#define NUM_NO_SOUND_FRAMES 1
|
||||
|
||||
#define REL_VEL_FRACTURE_THRESHOLD 5.0f
|
||||
//#define REL_VEL_FRACTURE_THRESHOLD 0.1f
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
SimScene* SimScene::createSimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath)
|
||||
{
|
||||
SimScene* s = PX_NEW(SimScene)(pxPhysics,pxCooking, isGrbScene,minConvexSize,defaultMat,resourcePath);
|
||||
s->createSingletons();
|
||||
return s;
|
||||
}
|
||||
|
||||
void SimScene::createSingletons()
|
||||
{
|
||||
mCompoundCreator = PX_NEW(CompoundCreator)(this);
|
||||
mPolygonTriangulator = PX_NEW(PolygonTriangulator)(this);
|
||||
addActor(createActor()); // make default actor
|
||||
}
|
||||
|
||||
Convex* SimScene::createConvex()
|
||||
{
|
||||
return PX_NEW(Convex)(this);
|
||||
}
|
||||
|
||||
Compound* SimScene::createCompound(const FracturePattern *pattern, const FracturePattern *secondaryPattern, PxReal contactOffset, PxReal restOffset)
|
||||
{
|
||||
return PX_NEW(Compound)(this,contactOffset,restOffset);
|
||||
}
|
||||
|
||||
Actor* SimScene::createActor()
|
||||
{
|
||||
return PX_NEW(Actor)(this);
|
||||
}
|
||||
|
||||
shdfnd::Array<Compound*> SimScene::getCompounds()
|
||||
{
|
||||
return mActors[0]->getCompounds();
|
||||
}
|
||||
|
||||
///*extern*/ std::vector<Compound*> delCompoundList;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SimScene::SimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath)
|
||||
{
|
||||
mPxPhysics = pxPhysics; // used for cooking
|
||||
mPxCooking = pxCooking;
|
||||
mPxDefaultMaterial = defaultMat;
|
||||
mResourcePath = resourcePath;
|
||||
|
||||
clear();
|
||||
mRenderBuffers.init();
|
||||
mSceneVersion = 1;
|
||||
mRenderBufferVersion = 0;
|
||||
mOptixBufferVersion = 0;
|
||||
|
||||
//create3dTexture();
|
||||
|
||||
mFractureForceThreshold = 500.0f;
|
||||
mContactImpactRadius = 0.5f;
|
||||
|
||||
mNoFractureFrames = 0;
|
||||
mNoSoundFrames = 0;
|
||||
mFrameNr = 0;
|
||||
mDebugDraw = false;
|
||||
// mDebugDraw = true; // foo
|
||||
|
||||
mPickDepth = 0.0f;
|
||||
mPickActor = NULL;
|
||||
mPickJoint = NULL;
|
||||
mPickPos = mPickLocalPos = PxVec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
mMinConvexSize = minConvexSize;
|
||||
mNumNoFractureFrames = 2;
|
||||
|
||||
bumpTextureUVScale = 0.1f;
|
||||
roughnessScale = 0.2f;
|
||||
extraNoiseScale = 2.0f;
|
||||
|
||||
particleBumpTextureUVScale = 0.2f;
|
||||
particleRoughnessScale = 0.8f;
|
||||
particleExtraNoiseScale = 2.0f;
|
||||
|
||||
|
||||
mPlaySounds = false;
|
||||
mRenderDebris = true;
|
||||
|
||||
mCompoundCreator = NULL;
|
||||
mPolygonTriangulator = NULL;
|
||||
|
||||
mAppNotify = NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SimScene::~SimScene()
|
||||
{
|
||||
clear();
|
||||
|
||||
// Delete actors if not already deleted
|
||||
for(int i = ((int)mActors.size() - 1) ; i >= 0; i--)
|
||||
{
|
||||
PX_DELETE(mActors[i]);
|
||||
}
|
||||
|
||||
PX_DELETE(mCompoundCreator);
|
||||
PX_DELETE(mPolygonTriangulator);
|
||||
|
||||
mCompoundCreator = NULL;
|
||||
mPolygonTriangulator = NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::clear()
|
||||
{
|
||||
for(int i = 0 ; i < (int)mActors.size(); i++)
|
||||
{
|
||||
mActors[i]->clear();
|
||||
}
|
||||
deleteCompounds();
|
||||
mPickActor = NULL;
|
||||
|
||||
++mSceneVersion;
|
||||
}
|
||||
|
||||
void SimScene::addActor(Actor* a)
|
||||
{
|
||||
mActors.pushBack(a);
|
||||
}
|
||||
|
||||
void SimScene::removeActor(Actor* a)
|
||||
{
|
||||
for(int i = 0; i < (int)mActors.size(); i++)
|
||||
{
|
||||
if( a == mActors[i] )
|
||||
{
|
||||
mActors[i] = mActors[mActors.size()-1];
|
||||
mActors.popBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::addCompound(Compound *c)
|
||||
{
|
||||
mActors[0]->addCompound(c);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::removeCompound(Compound *c)
|
||||
{
|
||||
mActors[0]->removeCompound(c);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::deleteCompounds()
|
||||
{
|
||||
for (int i = 0; i < (int)delCompoundList.size(); i++)
|
||||
{
|
||||
PX_DELETE(delCompoundList[i]);
|
||||
}
|
||||
delCompoundList.clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::preSim(float dt)
|
||||
{
|
||||
for(int i = 0 ; i < (int)mActors.size(); i++)
|
||||
{
|
||||
mActors[i]->preSim(dt);
|
||||
}
|
||||
|
||||
|
||||
// make sure we use the apex user notify... if the application
|
||||
// changes their custom one make sure we map to it.
|
||||
mScene->lockWrite();
|
||||
PxSimulationEventCallback* userNotify = mScene->getSimulationEventCallback();
|
||||
if (userNotify != this)
|
||||
{
|
||||
mAppNotify = userNotify;
|
||||
mScene->setSimulationEventCallback(this);
|
||||
}
|
||||
mScene->unlockWrite();
|
||||
}
|
||||
|
||||
//float4* posVelG = 0;
|
||||
//int numPosVelG = 0;
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::postSim(float dt)
|
||||
{
|
||||
for(int i = 0 ; i < (int)mActors.size(); i++)
|
||||
{
|
||||
mActors[i]->postSim(dt);
|
||||
}
|
||||
|
||||
mFrameNr++;
|
||||
mNoFractureFrames--;
|
||||
mNoSoundFrames--;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SimScene::pickStart(const PxVec3 &orig, const PxVec3 &dir)
|
||||
{
|
||||
PX_ASSERT(mPickActor == NULL);
|
||||
|
||||
float dist = 1000.f;
|
||||
|
||||
PxRaycastBuffer buffer;
|
||||
if (!getScene()->raycast(orig, dir, dist, buffer, PxHitFlag::eDEFAULT, PxQueryFilterData(PxQueryFlag::eDYNAMIC)))
|
||||
return false;
|
||||
|
||||
PxRigidDynamic* pickedActor = buffer.getAnyHit(0).actor->is<PxRigidDynamic>();
|
||||
|
||||
dist = buffer.getAnyHit(0).distance;
|
||||
|
||||
|
||||
|
||||
//mPickActor = mActors[actorNr]->mCompounds[compoundNr]->getPxActor();
|
||||
mPickPos = orig + dir * dist;
|
||||
|
||||
mPickActor = PxGetPhysics().createRigidDynamic(PxTransform(mPickPos));
|
||||
mPickActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
|
||||
getScene()->addActor(*mPickActor);
|
||||
|
||||
mPickLocalPos = PxVec3(0.f);
|
||||
|
||||
mPickJoint = PxD6JointCreate(PxGetPhysics(), mPickActor, PxTransform(PxIdentity), pickedActor, PxTransform(pickedActor->getGlobalPose().transformInv(mPickPos)));
|
||||
mPickJoint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
|
||||
mPickJoint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
|
||||
mPickJoint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
|
||||
|
||||
mPickDepth = dist;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SimScene::pickMove(const PxVec3 &orig, const PxVec3 &dir)
|
||||
{
|
||||
if (mPickActor == NULL)
|
||||
return;
|
||||
|
||||
mPickPos = orig + dir * mPickDepth;
|
||||
mPickActor->setKinematicTarget(PxTransform(mPickPos));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SimScene::pickRelease()
|
||||
{
|
||||
if (mPickJoint)
|
||||
mPickJoint->release();
|
||||
mPickJoint = NULL;
|
||||
if (mPickActor)
|
||||
mPickActor->release();
|
||||
mPickActor = NULL;
|
||||
}
|
||||
|
||||
bool SimScene::findCompound(const Compound* c, int& actorNr, int& compoundNr)
|
||||
{
|
||||
actorNr = -1;
|
||||
compoundNr = -1;
|
||||
for(int i = 0; i < (int)mActors.size(); i++)
|
||||
{
|
||||
if (mActors[i]->findCompound(c,compoundNr))
|
||||
{
|
||||
actorNr = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// CPU
|
||||
void SimScene::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
|
||||
{
|
||||
// Pass along to application's callback, if defined
|
||||
if (mAppNotify != NULL)
|
||||
{
|
||||
mAppNotify->onContact(pairHeader, pairs, nbPairs);
|
||||
}
|
||||
}
|
||||
|
||||
shdfnd::Array<PxVec3>& SimScene::getDebugPoints() {
|
||||
return debugPoints;
|
||||
}
|
||||
|
||||
bool SimScene::mapShapeToConvex(const PxShape& shape, Convex& convex)
|
||||
{
|
||||
return mShapeMap.insert(&shape, &convex);
|
||||
}
|
||||
|
||||
bool SimScene::unmapShape(const PxShape& shape)
|
||||
{
|
||||
return mShapeMap.erase(&shape);
|
||||
}
|
||||
|
||||
Convex* SimScene::findConvexForShape(const PxShape& shape)
|
||||
{
|
||||
const physx::shdfnd::HashMap<const PxShape*, Convex*>::Entry* entry = mShapeMap.find(&shape);
|
||||
return entry != NULL ? entry->second : NULL; // Since we don't expect *entry to be NULL, we shouldn't lose information here
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
275
kaplademo/source/kaplaDemo/Fracture/Core/SimSceneBase.h
Normal file
275
kaplademo/source/kaplaDemo/Fracture/Core/SimSceneBase.h
Normal file
@ -0,0 +1,275 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "RTdef.h"
|
||||
#if RT_COMPILE
|
||||
#ifndef SIM_SCENE_BASE
|
||||
#define SIM_SCENE_BASE
|
||||
|
||||
#include "PxSimulationEventCallback.h"
|
||||
#include <PsArray.h>
|
||||
#include <PsUserAllocated.h>
|
||||
#include "PsHashMap.h"
|
||||
|
||||
#include "RTdef.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxPhysics;
|
||||
class PxCooking;
|
||||
class PxScene;
|
||||
class PxRigidDynamic;
|
||||
class PxD6Joint;
|
||||
namespace fracture
|
||||
{
|
||||
namespace base
|
||||
{
|
||||
|
||||
class Actor;
|
||||
class Compound;
|
||||
class Convex;
|
||||
class FracturePattern;
|
||||
class CompoundCreator;
|
||||
class Delaunay2d;
|
||||
class Delaunay3d;
|
||||
class PolygonTriangulator;
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
class SimScene :
|
||||
public PxSimulationEventCallback, public ::physx::shdfnd::UserAllocated
|
||||
{
|
||||
friend class Actor;
|
||||
public:
|
||||
static SimScene* createSimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath);
|
||||
protected:
|
||||
SimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath);
|
||||
public:
|
||||
virtual ~SimScene();
|
||||
|
||||
// Creates Scene Level Singletons
|
||||
virtual void createSingletons();
|
||||
// Access singletons
|
||||
CompoundCreator* getCompoundCreator() {return mCompoundCreator;}
|
||||
PolygonTriangulator* getPolygonTriangulator() {return mPolygonTriangulator;}
|
||||
|
||||
// Create non-Singletons
|
||||
virtual Actor* createActor();
|
||||
virtual Convex* createConvex();
|
||||
virtual Compound* createCompound(const FracturePattern *pattern, const FracturePattern *secondaryPattern = NULL, PxReal contactOffset = 0.005f, PxReal restOffset = -0.001f);
|
||||
virtual void clear();
|
||||
void addCompound(Compound *m);
|
||||
void removeCompound(Compound *m);
|
||||
// perform deferred deletion
|
||||
void deleteCompounds();
|
||||
|
||||
void setScene(PxScene* scene) { mScene = scene; }
|
||||
//
|
||||
bool findCompound(const Compound* c, int& actorNr, int& compoundNr);
|
||||
|
||||
void removeActor(Actor* a);
|
||||
|
||||
// Profiler hooks
|
||||
virtual void profileBegin(const char* /*name*/) {}
|
||||
virtual void profileEnd(const char* /*name*/) {}
|
||||
|
||||
virtual void playSound(const char * /*name*/, int /*nr*/ = -1) {}
|
||||
|
||||
// accessors
|
||||
shdfnd::Array<Compound*> getCompounds(); //{ return mCompounds; }
|
||||
shdfnd::Array<Actor*> getActors() { return mActors; }
|
||||
PxPhysics* getPxPhysics() { return mPxPhysics; }
|
||||
PxCooking* getPxCooking() { return mPxCooking; }
|
||||
PxScene* getScene() { return mScene; }
|
||||
|
||||
//ConvexRenderer &getConvexRenderer() { return mConvexRenderer; }
|
||||
|
||||
void preSim(float dt);
|
||||
void postSim(float dt); //, RegularCell3D* fluidSim);
|
||||
|
||||
void setPlaySounds(bool play) { mPlaySounds = play; }
|
||||
void setContactImpactRadius(float radius) { mContactImpactRadius = radius; }
|
||||
void setNumNoFractureFrames(int num) { mNumNoFractureFrames = num; }
|
||||
|
||||
void setCamera(const PxVec3 &pos, const PxVec3 &dir, const PxVec3 &up, float fov ) {
|
||||
mCameraPos = pos; mCameraDir = dir; mCameraUp = up; mCameraFov = fov;
|
||||
}
|
||||
|
||||
//void draw(bool useShader, Shader* particleShader = NULL) {}
|
||||
//void setShaderMaterial(Shader* shader, const ShaderMaterial& mat) {this->mShader = shader; this->mShaderMat = mat;}
|
||||
//void setFractureForceThreshold(float threshold) { mFractureForceThreshold = threshold; }
|
||||
|
||||
PxMaterial *getPxDefaultMaterial() { return mPxDefaultMaterial; }
|
||||
|
||||
void toggleDebugDrawing() { mDebugDraw = !mDebugDraw; }
|
||||
|
||||
virtual bool pickStart(const PxVec3 &orig, const PxVec3 &dir);
|
||||
virtual void pickMove(const PxVec3 &orig, const PxVec3 &dir);
|
||||
virtual void pickRelease();
|
||||
PxRigidDynamic* getPickActor() { return mPickActor; }
|
||||
const PxVec3 &getPickPos() { return mPickPos; }
|
||||
const PxVec3 &getPickLocalPos() { return mPickLocalPos; }
|
||||
|
||||
// callback interface
|
||||
|
||||
void onContactNotify(unsigned int arraySizes, void ** shape0Array, void ** shape1Array, void ** actor0Array, void ** actor1Array, float * positionArray, float * normalArray);
|
||||
void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { PX_UNUSED((constraints, count)); }
|
||||
void onWake(PxActor** actors, PxU32 count) { PX_UNUSED((actors, count)); }
|
||||
void onSleep(PxActor** actors, PxU32 count) { PX_UNUSED((actors, count)); }
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count) { PX_UNUSED((pairs, count)); }
|
||||
void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs);
|
||||
void onAdvance(const PxRigidBody*const* bodyBuffer, const PxTransform* poseBuffer, const PxU32 count) { PX_UNUSED(bodyBuffer); PX_UNUSED(poseBuffer); PX_UNUSED(count); }
|
||||
|
||||
void toggleRenderDebris() {mRenderDebris = !mRenderDebris;}
|
||||
bool getRenderDebrs() {return mRenderDebris;}
|
||||
//virtual void dumpSceneGeometry() {}
|
||||
shdfnd::Array<PxVec3>& getDebugPoints();
|
||||
//virtual void createRenderBuffers() {}
|
||||
//void loadAndCreateTextureArrays();
|
||||
|
||||
shdfnd::Array<PxVec3>& getCrackNormals() {return crackNormals;}
|
||||
shdfnd::Array<PxVec3>& getTmpPoints() {return tmpPoints;}
|
||||
|
||||
bool mapShapeToConvex(const PxShape& shape, Convex& convex);
|
||||
bool unmapShape(const PxShape& shape);
|
||||
Convex* findConvexForShape(const PxShape& shape);
|
||||
bool owns(const PxShape& shape) {return NULL != findConvexForShape(shape);}
|
||||
|
||||
protected:
|
||||
//virtual void create3dTexture() {}
|
||||
//virtual void updateConvexesTex() {}
|
||||
//void playShatterSound(float objectSize);
|
||||
|
||||
void addActor(Actor* a); // done internally upon creation
|
||||
|
||||
PxPhysics *mPxPhysics;
|
||||
PxCooking *mPxCooking;
|
||||
PxScene *mScene;
|
||||
const char *mResourcePath;
|
||||
bool mPlaySounds;
|
||||
|
||||
//shdfnd::Array<Compound*> mCompounds;
|
||||
shdfnd::Array<Actor*> mActors;
|
||||
|
||||
float mFractureForceThreshold;
|
||||
float mContactImpactRadius;
|
||||
|
||||
shdfnd::Array<PxContactPairPoint> mContactPoints;
|
||||
struct FractureEvent {
|
||||
void init() {
|
||||
compound = NULL;
|
||||
pos = normal = PxVec3(0.0f, 0.0f, 0.0f);
|
||||
additionalRadialImpulse = additionalNormalImpulse = 0.0f;
|
||||
withStatic = false;
|
||||
}
|
||||
Compound *compound;
|
||||
PxVec3 pos;
|
||||
PxVec3 normal;
|
||||
float additionalRadialImpulse;
|
||||
float additionalNormalImpulse;
|
||||
bool withStatic;
|
||||
};
|
||||
|
||||
struct RenderBuffers {
|
||||
void init() {
|
||||
numVertices = 0; numIndices = 0;
|
||||
VBO = 0; IBO = 0; matTex = 0; volTex = 0;
|
||||
texSize = 0; numConvexes = -1;
|
||||
}
|
||||
shdfnd::Array<float> tmpVertices;
|
||||
shdfnd::Array<unsigned int> tmpIndices;
|
||||
shdfnd::Array<float> tmpTexCoords;
|
||||
int numVertices, numIndices;
|
||||
unsigned int VBO;
|
||||
unsigned int IBO;
|
||||
unsigned int volTex;
|
||||
unsigned int matTex;
|
||||
int texSize;
|
||||
int numConvexes;
|
||||
};
|
||||
RenderBuffers mRenderBuffers;
|
||||
unsigned int mSceneVersion; // changed on each update
|
||||
unsigned int mRenderBufferVersion; // to handle updates
|
||||
unsigned int mOptixBufferVersion; // to handle updates
|
||||
|
||||
PxMaterial *mPxDefaultMaterial;
|
||||
|
||||
//ConvexRenderer mConvexRenderer;
|
||||
|
||||
int mNoFractureFrames;
|
||||
int mNoSoundFrames;
|
||||
int mFrameNr;
|
||||
bool mDebugDraw;
|
||||
|
||||
float mPickDepth;
|
||||
PxRigidDynamic *mPickActor;
|
||||
PxD6Joint* mPickJoint;
|
||||
PxVec3 mPickPos;
|
||||
PxVec3 mPickLocalPos;
|
||||
|
||||
float mMinConvexSize;
|
||||
int mNumNoFractureFrames; // > 1 to prevent a slow down by too many fracture events
|
||||
|
||||
PxVec3 mCameraPos, mCameraDir, mCameraUp;
|
||||
float mCameraFov;
|
||||
|
||||
float bumpTextureUVScale;
|
||||
float extraNoiseScale;
|
||||
float roughnessScale;
|
||||
|
||||
float particleBumpTextureUVScale;
|
||||
float particleRoughnessScale;
|
||||
float particleExtraNoiseScale;
|
||||
shdfnd::Array<PxVec3> debugPoints;
|
||||
bool mRenderDebris;
|
||||
|
||||
PxSimulationEventCallback* mAppNotify;
|
||||
|
||||
//GLuint diffuseTexArray, bumpTexArray, specularTexArray, emissiveReflectSpecPowerTexArray;
|
||||
|
||||
//GLuint loadTextureArray(std::vector<std::string>& names);
|
||||
|
||||
//Singletons
|
||||
CompoundCreator* mCompoundCreator;
|
||||
PolygonTriangulator* mPolygonTriangulator;
|
||||
|
||||
//Array for use by Compound (effectively static)
|
||||
shdfnd::Array<PxVec3> crackNormals;
|
||||
shdfnd::Array<PxVec3> tmpPoints;
|
||||
|
||||
// Deferred Deletion list
|
||||
shdfnd::Array<Compound*> delCompoundList;
|
||||
|
||||
// Map used to determine SimScene ownership of shape
|
||||
shdfnd::HashMap<const PxShape*,Convex*> mShapeMap;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
192
kaplademo/source/kaplaDemo/Fracture/Mesh.cpp
Normal file
192
kaplademo/source/kaplaDemo/Fracture/Mesh.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include <foundation/PxBounds3.h>
|
||||
|
||||
#include "Mesh.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
struct SimpleVertexRef {
|
||||
int vert, normal, texCoord;
|
||||
int indexNr, subMeshNr;
|
||||
bool operator < (const SimpleVertexRef &r) const {
|
||||
if (vert < r.vert) return true;
|
||||
if (vert > r.vert) return false;
|
||||
if (normal < r.normal) return true;
|
||||
if (normal > r.normal) return false;
|
||||
return texCoord < r.texCoord;
|
||||
}
|
||||
bool operator == (const SimpleVertexRef &r) const {
|
||||
return vert == r.vert && normal == r.normal && texCoord == r.texCoord;
|
||||
}
|
||||
void parse(char *s, int indexNr) {
|
||||
int nr[3] = {0,0,0};
|
||||
char *p = s;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
while (*p != 0 && *p != '/') p++;
|
||||
bool end = (*p == 0);
|
||||
*p = 0;
|
||||
sscanf_s(s, "%i", &nr[i]);
|
||||
if (end) break;
|
||||
p++; s = p;
|
||||
}
|
||||
vert = nr[0]-1; texCoord = nr[1]-1; normal = nr[2]-1;
|
||||
this->indexNr = indexNr;
|
||||
}
|
||||
};
|
||||
|
||||
#define OBJ_STR_LEN 256
|
||||
// -------------------------------------------------------------------
|
||||
bool Mesh::loadFromObjFile(const std::string &filename)
|
||||
{
|
||||
const int maxVertsPerFace = 8;
|
||||
|
||||
char s[OBJ_STR_LEN], ps[maxVertsPerFace][OBJ_STR_LEN], sub[OBJ_STR_LEN];
|
||||
int matNr = -1;
|
||||
PxVec3 p;
|
||||
float u,v;
|
||||
shdfnd::Array<SimpleVertexRef> refs;
|
||||
SimpleVertexRef ref[maxVertsPerFace];
|
||||
|
||||
shdfnd::Array<PxVec3> vertices;
|
||||
shdfnd::Array<PxVec3> normals;
|
||||
shdfnd::Array<float> texCoords;
|
||||
int numIndices = 0;
|
||||
|
||||
mSubMeshes.resize(1);
|
||||
mNames.resize(1);
|
||||
mSubMeshes[0].init();
|
||||
mNames[0] = "";
|
||||
mSubMeshes[0].firstIndex = 0;
|
||||
|
||||
FILE *f;
|
||||
|
||||
if (fopen_s(&f, filename.c_str(), "r") != 0) {
|
||||
std::cerr << "Could not load OBJ file: " << filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// first a vertex ref is generated for each v/n/t combination
|
||||
while (!feof(f)) {
|
||||
if (fgets(s, OBJ_STR_LEN, f) == NULL) break;
|
||||
|
||||
if (strncmp(s, "usemtl", 6) == 0 || strncmp(s, "g ", 2) == 0) { // new group
|
||||
bool isGroup = strncmp(s, "g ", 2) == 0;
|
||||
if (isGroup)
|
||||
strcpy(sub, &s[2]);
|
||||
else
|
||||
strcpy(sub, &s[6]);
|
||||
int numSubs = mSubMeshes.size();
|
||||
if (mSubMeshes[numSubs-1].numIndices > 0) {
|
||||
mSubMeshes.resize(numSubs+1);
|
||||
mNames.resize(numSubs+1);
|
||||
mSubMeshes[numSubs].init();
|
||||
mNames[numSubs] = "";
|
||||
mSubMeshes[numSubs].firstIndex = mIndices.size();
|
||||
}
|
||||
int subNr = mSubMeshes.size() - 1;
|
||||
if (mNames[subNr] == "" || isGroup)
|
||||
mNames[subNr] = std::string(sub);
|
||||
}
|
||||
else if (strncmp(s, "v ", 2) == 0) { // vertex
|
||||
sscanf_s(s, "v %f %f %f", &p.x, &p.y, &p.z);
|
||||
vertices.pushBack(p);
|
||||
}
|
||||
else if (strncmp(s, "vn ", 3) == 0) { // normal
|
||||
sscanf_s(s, "vn %f %f %f", &p.x, &p.y, &p.z);
|
||||
normals.pushBack(p);
|
||||
}
|
||||
else if (strncmp(s, "vt ", 3) == 0) { // texture coords
|
||||
sscanf_s(s, "vt %f %f", &u, &v);
|
||||
texCoords.pushBack(u);
|
||||
texCoords.pushBack(v);
|
||||
}
|
||||
else if (strncmp(s, "f ", 2) == 0) { // face, tri or quad
|
||||
int nr;
|
||||
nr = sscanf_s(s, "f %s %s %s %s %s %s",
|
||||
ps[0], OBJ_STR_LEN, ps[1], OBJ_STR_LEN, ps[2], OBJ_STR_LEN, ps[3], OBJ_STR_LEN,
|
||||
ps[4], OBJ_STR_LEN, ps[5], OBJ_STR_LEN, ps[6], OBJ_STR_LEN, ps[7], OBJ_STR_LEN);
|
||||
|
||||
if (nr >= 3) {
|
||||
for (int i = 0; i < nr; i++)
|
||||
ref[i].parse(ps[i], 0);
|
||||
for (int i = 1; i < nr-1; i++) {
|
||||
ref[0].indexNr = numIndices++; refs.pushBack(ref[0]); mIndices.pushBack(0);
|
||||
ref[i].indexNr = numIndices++; refs.pushBack(ref[i]); mIndices.pushBack(0);
|
||||
ref[i+1].indexNr = numIndices++; refs.pushBack(ref[i+1]); mIndices.pushBack(0);
|
||||
mSubMeshes[mSubMeshes.size()-1].numIndices += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
// now we merge multiple v/n/t triplets
|
||||
std::sort(refs.begin(), refs.end());
|
||||
|
||||
int i = 0;
|
||||
PxVec3 defNormal(1.0f, 0.0f, 0.0f);
|
||||
bool normalsOK = true;
|
||||
bool mTextured = true;
|
||||
int numTexCoords = texCoords.size();
|
||||
|
||||
int baseVertNr = 0;
|
||||
|
||||
while (i < (int)refs.size()) {
|
||||
int vertNr = mVertices.size();
|
||||
SimpleVertexRef &r = refs[i];
|
||||
mVertices.pushBack(vertices[r.vert]);
|
||||
|
||||
if (r.normal >= 0) mNormals.pushBack(normals[r.normal]);
|
||||
else { mNormals.pushBack(defNormal); normalsOK = false; }
|
||||
|
||||
if (r.texCoord >= 0 && r.texCoord < numTexCoords) {
|
||||
//mTexCoords.pushBack(texCoords[2*r.texCoord]);
|
||||
//mTexCoords.pushBack(texCoords[2*r.texCoord+1]);
|
||||
mTexCoords.pushBack(PxVec2(texCoords[2*r.texCoord],texCoords[2*r.texCoord+1]));
|
||||
}
|
||||
else {
|
||||
//mTexCoords.pushBack(0.0f);
|
||||
//mTexCoords.pushBack(0.0f);
|
||||
mTexCoords.pushBack(PxVec2(0.0f,0.0f));
|
||||
}
|
||||
|
||||
mIndices[r.indexNr] = vertNr;
|
||||
i++;
|
||||
while (i < (int)refs.size() && r == refs[i]) {
|
||||
mIndices[refs[i].indexNr] = vertNr;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!normalsOK)
|
||||
updateNormals();
|
||||
|
||||
return true;
|
||||
}
|
||||
59
kaplademo/source/kaplaDemo/Fracture/Mesh.h
Normal file
59
kaplademo/source/kaplaDemo/Fracture/Mesh.h
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef MESH
|
||||
#define MESH
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <PsArray.h>
|
||||
#include <PsAllocator.h>
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
#include "MeshBase.h"
|
||||
|
||||
using namespace physx::fracture;
|
||||
|
||||
class Mesh : public base::Mesh
|
||||
{
|
||||
public:
|
||||
bool loadFromObjFile(const std::string &filename);
|
||||
|
||||
void setShader(Shader* shader, const ShaderMaterial &mat) { mShader = shader; mShaderMat = mat; }
|
||||
Shader* getShader() const { return mShader; }
|
||||
const ShaderMaterial& getShaderMat() { return mShaderMat; }
|
||||
void draw(bool useShader);
|
||||
protected:
|
||||
// shading
|
||||
Shader *mShader;
|
||||
ShaderMaterial mShaderMat;
|
||||
Shader *mWrinkleShader;
|
||||
|
||||
shdfnd::Array<std::string> mNames;
|
||||
};
|
||||
|
||||
#endif
|
||||
31
kaplademo/source/kaplaDemo/Fracture/PolygonTriangulator.cpp
Normal file
31
kaplademo/source/kaplaDemo/Fracture/PolygonTriangulator.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "PolygonTriangulator.h"
|
||||
#include <assert.h>
|
||||
|
||||
// Empty until base has code proven to be non-portable
|
||||
49
kaplademo/source/kaplaDemo/Fracture/PolygonTriangulator.h
Normal file
49
kaplademo/source/kaplaDemo/Fracture/PolygonTriangulator.h
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef POLYGON_TRIANGULATOR_H
|
||||
#define POLYGON_TRIANGULATOR_H
|
||||
|
||||
#include <foundation/PxVec3.h>
|
||||
#include <PsArray.h>
|
||||
|
||||
using namespace physx;
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "PolygonTriangulatorBase.h"
|
||||
|
||||
using namespace physx::fracture;
|
||||
|
||||
class PolygonTriangulator : public base::PolygonTriangulator
|
||||
{
|
||||
friend class SimScene;
|
||||
protected:
|
||||
PolygonTriangulator(SimScene* scene): base::PolygonTriangulator((base::SimScene*)scene) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
35
kaplademo/source/kaplaDemo/Fracture/RTdef.h
Normal file
35
kaplademo/source/kaplaDemo/Fracture/RTdef.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
// This file exists primarily for APEX integration
|
||||
#ifndef RT_DEF_H
|
||||
#define RT_DEF_H
|
||||
|
||||
#define RT_COMPILE 1
|
||||
#define NO_IMPACT_FRACTURE 0
|
||||
|
||||
#endif
|
||||
736
kaplademo/source/kaplaDemo/Fracture/SimScene.cpp
Normal file
736
kaplademo/source/kaplaDemo/Fracture/SimScene.cpp
Normal file
@ -0,0 +1,736 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "SimScene.h"
|
||||
#include <foundation/PxMat44.h>
|
||||
#include "PxRigidBodyExt.h"
|
||||
|
||||
#include "Actor.h"
|
||||
#include "Compound.h"
|
||||
#include "Convex.h"
|
||||
#include "CompoundCreator.h"
|
||||
#include "PolygonTriangulator.h"
|
||||
|
||||
#include "SampleViewerScene.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <vector>
|
||||
#include "TerrainMesh.h"
|
||||
|
||||
#define USE_CONVEX_RENDERER 1
|
||||
#define NUM_NO_SOUND_FRAMES 1
|
||||
|
||||
//#define REL_VEL_FRACTURE_THRESHOLD 5.0f
|
||||
#define REL_VEL_FRACTURE_THRESHOLD 0.1f
|
||||
|
||||
//extern std::vector<Compound*> delCompoundList;
|
||||
|
||||
SimScene* SimScene::createSimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath)
|
||||
{
|
||||
SimScene* s = PX_NEW(SimScene)(pxPhysics,pxCooking,isGrbScene,minConvexSize,defaultMat,resourcePath);
|
||||
s->createSingletons();
|
||||
return s;
|
||||
}
|
||||
|
||||
void SimScene::createSingletons()
|
||||
{
|
||||
mCompoundCreator = PX_NEW(CompoundCreator)(this);
|
||||
mPolygonTriangulator = PX_NEW(PolygonTriangulator)(this);
|
||||
addActor(createActor());
|
||||
}
|
||||
|
||||
base::Actor* SimScene::createActor()
|
||||
{
|
||||
return (base::Actor*)PX_NEW(Actor)(this);
|
||||
}
|
||||
|
||||
base::Convex* SimScene::createConvex()
|
||||
{
|
||||
return (base::Convex*)PX_NEW(Convex)(this);
|
||||
}
|
||||
|
||||
base::Compound* SimScene::createCompound(PxReal contactOffset, PxReal restOffset)
|
||||
{
|
||||
return (base::Compound*)PX_NEW(Compound)(this, contactOffset, restOffset);
|
||||
}
|
||||
|
||||
SimScene::SimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath):
|
||||
base::SimScene(pxPhysics,pxCooking,isGrbScene,minConvexSize,defaultMat,resourcePath)
|
||||
{
|
||||
//mParticles = NULL;
|
||||
|
||||
diffuseTexArray = 0;
|
||||
bumpTexArray = 0;
|
||||
specularTexArray = 0;
|
||||
emissiveReflectSpecPowerTexArray = 0;
|
||||
|
||||
create3dTexture();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SimScene::~SimScene()
|
||||
{
|
||||
mShader = NULL;
|
||||
mShaderMat.init();
|
||||
|
||||
if (mRenderBuffers.volTex) glDeleteTextures(1, &mRenderBuffers.volTex);
|
||||
if (mRenderBuffers.VBO) glDeleteBuffersARB(1, &mRenderBuffers.VBO);
|
||||
if (mRenderBuffers.IBO) glDeleteBuffersARB(1, &mRenderBuffers.IBO);
|
||||
if (mRenderBuffers.matTex) glDeleteTextures(1, &mRenderBuffers.matTex);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::clear()
|
||||
{
|
||||
base::SimScene::clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::postSim(float dt, RegularCell3D* fluidSim)
|
||||
{
|
||||
for (int i = 0; i < mActors.size(); i++)
|
||||
{
|
||||
mActors[i]->postSim(dt);
|
||||
}
|
||||
|
||||
mFrameNr++;
|
||||
mNoFractureFrames--;
|
||||
mNoSoundFrames--;
|
||||
}
|
||||
|
||||
void SimScene::profileBegin(const char* name)
|
||||
{
|
||||
}
|
||||
|
||||
void SimScene::profileEnd(const char* name)
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------- Renderering --------------------------------
|
||||
|
||||
GLuint SimScene::loadTextureArray(std::vector<std::string>& names) {
|
||||
|
||||
GLuint texid;
|
||||
glGenTextures(1, &texid);
|
||||
glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, texid);
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
|
||||
class BmpLoaderBuffer : public ::BmpLoaderBuffer, public ::physx::shdfnd::UserAllocated {};
|
||||
BmpLoaderBuffer *bmps;
|
||||
bmps = PX_NEW(BmpLoaderBuffer)[names.size()];
|
||||
|
||||
char path[512];
|
||||
|
||||
int w = 0, h = 0, d = 0;
|
||||
for (int i = 0; i < (int)names.size(); i++) {
|
||||
|
||||
if (names[i].size() > 0) {
|
||||
sprintf_s(path, 512, "%s", names[i].c_str());
|
||||
int len = strlen(path);
|
||||
|
||||
int mw = 0, mh = 0;
|
||||
if (strcmp(&path[len-4], ".jpg") == 0) {
|
||||
printf("Can't load %s, jpg no longer supported\n", path);
|
||||
} else {
|
||||
bmps[i].loadFile(path);
|
||||
mw = bmps[i].mWidth;
|
||||
mh = bmps[i].mHeight;
|
||||
}
|
||||
|
||||
if ((mw != 0) && (mh != 0)) {
|
||||
if ( ((w != 0) && (w != mw)) ||
|
||||
((h != 0) && (h != mh)) ) {
|
||||
printf("Textures in array need to be same size!\n");
|
||||
}
|
||||
w = mw;
|
||||
h = mh;
|
||||
}
|
||||
}
|
||||
}
|
||||
d = names.size();
|
||||
if (w == 0) {
|
||||
w=h=128;
|
||||
|
||||
}
|
||||
unsigned char* tmpBlack = (unsigned char*)PX_ALLOC(sizeof(unsigned char)*w*h*3,PX_DEBUG_EXP("RT_FRACTURE"));
|
||||
memset(tmpBlack, 0, w*h*3);
|
||||
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8, w, h, d, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
for (int i = 0; i < (int)names.size(); i++) {
|
||||
glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, i, w, h, 1, GL_RGB, GL_UNSIGNED_BYTE, (bmps[i].mRGB) ? bmps[i].mRGB :tmpBlack
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
glGenerateMipmapEXT(GL_TEXTURE_2D_ARRAY_EXT);
|
||||
|
||||
PX_FREE(tmpBlack);
|
||||
PX_DELETE_ARRAY(bmps);
|
||||
|
||||
/* names
|
||||
// 2D Texture arrays a loaded just like 3D textures
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGBA8, images[0].getWidth(), images[0].getHeight(), NIMAGES, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
for (int i = 0; i < NIMAGES; i++) {
|
||||
glTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 0, 0, i, images[i].getWidth(), images[i].getHeight(), 1, images[i].getFormat(), images[i].getType(), images[i].getLevel(0));
|
||||
}
|
||||
*/
|
||||
return texid;
|
||||
|
||||
}
|
||||
|
||||
void SimScene::loadAndCreateTextureArrays() {
|
||||
diffuseTexArray = loadTextureArray(diffuseTexNames);
|
||||
bumpTexArray = loadTextureArray(bumpTexNames);
|
||||
specularTexArray = loadTextureArray(specularTexNames);
|
||||
emissiveReflectSpecPowerTexArray = loadTextureArray(emissiveReflectSpecPowerTexNames);
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#define WIDTH 128
|
||||
#define HEIGHT 128
|
||||
#define DEPTH 128
|
||||
#define BYTES_PER_TEXEL 3
|
||||
#define LAYER(r) (WIDTH * HEIGHT * r * BYTES_PER_TEXEL)
|
||||
// 2->1 dimension mapping function
|
||||
#define TEXEL2(s, t) (BYTES_PER_TEXEL * (s * WIDTH + t))
|
||||
// 3->1 dimension mapping function
|
||||
#define TEXEL3(s, t, r) (TEXEL2(s, t) + LAYER(r))
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::create3dTexture()
|
||||
{
|
||||
unsigned char *texels = (unsigned char *)malloc(WIDTH * HEIGHT * DEPTH * BYTES_PER_TEXEL);
|
||||
memset(texels, 0, WIDTH*HEIGHT*DEPTH);
|
||||
|
||||
// each of the following loops defines one layer of our 3d texture, there are 3 unsigned bytes (red, green, blue) for each texel so each iteration sets 3 bytes
|
||||
// the memory pointed to by texels is technically a single dimension (C++ won't allow more than one dimension to be of variable length), the
|
||||
// work around is to use a mapping function like the one above that maps the 3 coordinates onto one dimension
|
||||
// layer 0 occupies the first (width * height * bytes per texel) bytes, followed by layer 1, etc...
|
||||
// define layer 0 as red
|
||||
|
||||
// Perlin perlin(8,4,1,91114);
|
||||
unsigned char* tt = texels;
|
||||
float idx = 1.0f / DEPTH;
|
||||
for (int i = 0; i < DEPTH; i++) {
|
||||
for (int j = 0; j < HEIGHT; j++) {
|
||||
for (int k = 0; k < WIDTH; k++) {
|
||||
//float v[3] = {i*idx, j*idx, k*idx};
|
||||
//float val = (perlin.noise3(v)*0.5f + 0.5f)*255.0f;//cos( (perlin.Noise3(i*0.01f,j*0.01f,k*0.01f)*255000 + i*0.)*5.0f)*0.5f+0.5f;//perlin.Noise3(k,j,i)*255.0f;
|
||||
//(cos(perlin.Noise3(k,j,i) + j*0.01f) + 1.0f)*0.5f*255;
|
||||
unsigned char val = rand() % 255;
|
||||
tt[0] = val;
|
||||
tt[1] = val;
|
||||
tt[2] = val;
|
||||
tt+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// request 1 texture name from OpenGL
|
||||
glGenTextures(1, &mRenderBuffers.volTex);
|
||||
// tell OpenGL we're going to be setting up the texture name it gave us
|
||||
glBindTexture(GL_TEXTURE_3D, mRenderBuffers.volTex);
|
||||
// when this texture needs to be shrunk to fit on small polygons, use linear interpolation of the texels to determine the color
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// when this texture needs to be magnified to fit on a big polygon, use linear interpolation of the texels to determine the color
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// we want the texture to repeat over the S axis, so if we specify coordinates out of range we still get textured.
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
// same as above for T axis
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
// same as above for R axis
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
||||
// this is a 3d texture, level 0 (max detail), GL should store it in RGB8 format, its WIDTHxHEIGHTxDEPTH in size,
|
||||
// it doesnt have a border, we're giving it to GL in RGB format as a series of unsigned bytes, and texels is where the texel data is.
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, WIDTH, HEIGHT, DEPTH, 0, GL_RGB, GL_UNSIGNED_BYTE, texels);
|
||||
|
||||
glBindTexture(GL_TEXTURE_3D, 0);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::createRenderBuffers()
|
||||
{
|
||||
if (!mRenderBuffers.VBO) {
|
||||
glGenBuffersARB(1, &mRenderBuffers.VBO);
|
||||
}
|
||||
if (!mRenderBuffers.IBO) {
|
||||
glGenBuffersARB(1, &mRenderBuffers.IBO);
|
||||
}
|
||||
if (!mRenderBuffers.matTex) {
|
||||
glGenTextures(1, &mRenderBuffers.matTex);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
}
|
||||
|
||||
// Count number of vertices and indices in convexes
|
||||
// Count number of indices in convexes
|
||||
mRenderBuffers.numConvexes = 0;
|
||||
mRenderBuffers.numVertices = 0;
|
||||
mRenderBuffers.numIndices = 0;
|
||||
|
||||
for (int k = 0; k < (int)mActors.size(); k++)
|
||||
{
|
||||
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
if (((Compound*)mCompounds[i])->getShader() != mShader)
|
||||
continue;
|
||||
const shdfnd::Array<base::Convex*> &convexes = mCompounds[i]->getConvexes();
|
||||
mRenderBuffers.numConvexes += convexes.size();
|
||||
for (int j = 0; j < (int)convexes.size(); j++) {
|
||||
mRenderBuffers.numVertices += convexes[j]->getVisVertices().size();
|
||||
mRenderBuffers.numIndices += convexes[j]->getVisTriIndices().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mRenderBuffers.numVertices == 0 || mRenderBuffers.numIndices == 0)
|
||||
return;
|
||||
|
||||
mRenderBuffers.tmpVertices.resize(mRenderBuffers.numVertices*12);
|
||||
mRenderBuffers.tmpIndices.resize(mRenderBuffers.numIndices);
|
||||
float* vp = &mRenderBuffers.tmpVertices[0];
|
||||
unsigned int* ip = &mRenderBuffers.tmpIndices[0];
|
||||
|
||||
int sumV = 0;
|
||||
// Make cpu copy of VBO and IBO
|
||||
|
||||
int convexNr = 0;
|
||||
|
||||
for (int k = 0; k < (int)mActors.size(); k++)
|
||||
{
|
||||
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
if (((Compound*)mCompounds[i])->getShader() != mShader)
|
||||
continue;
|
||||
|
||||
const shdfnd::Array<base::Convex*> &convexes = mCompounds[i]->getConvexes();
|
||||
for (int j = 0; j < (int)convexes.size(); j++, convexNr++) {
|
||||
Convex* c = (Convex*)convexes[j];
|
||||
// PxVec3 matOff = c->getMaterialOffset();
|
||||
|
||||
int nv = c->getVisVertices().size();
|
||||
int ni = c->getVisTriIndices().size();
|
||||
|
||||
if (nv > 0) {
|
||||
float* cvp = (float*)&c->getVisVertices()[0]; // float3
|
||||
float* cnp = (float*)&c->getVisNormals()[0]; // float3
|
||||
// float* c3dtp = (float*)&c->getVisVertices()[0]; // float3
|
||||
float* c2dtp = (float*)&c->getVisTexCoords()[0]; // float2
|
||||
float* ctanp = (float*)&c->getVisTangents()[0]; // float3
|
||||
|
||||
int* cip = (int*)&c->getVisTriIndices()[0];
|
||||
for (int k = 0; k < nv; k++) {
|
||||
*(vp++) = *(cvp++);
|
||||
*(vp++) = *(cvp++);
|
||||
*(vp++) = *(cvp++);
|
||||
|
||||
*(vp++) = *(cnp++);
|
||||
*(vp++) = *(cnp++);
|
||||
*(vp++) = *(cnp++);
|
||||
|
||||
*(vp++) = *(ctanp++);
|
||||
*(vp++) = *(ctanp++);
|
||||
*(vp++) = *(ctanp++);
|
||||
*(vp++) = (float)convexNr;
|
||||
|
||||
*(vp++) = *(c2dtp++);
|
||||
*(vp++) = *(c2dtp++);
|
||||
|
||||
}
|
||||
for (int k = 0; k < ni; k++) {
|
||||
*(ip++) = *(cip++) + sumV;
|
||||
}
|
||||
}
|
||||
//memcpy(ip, cip, sizeof(int)*ni);
|
||||
//ip += 3*ni;
|
||||
|
||||
//std::vector<PxVec3> mTriVertices;
|
||||
//std::vector<PxVec3> mTriNormals;
|
||||
//std::vector<int> mTriIndices;
|
||||
//std::vector<float> mTriTexCoords; // 3d + obj nr
|
||||
sumV += nv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mRenderBuffers.VBO);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, mRenderBuffers.tmpVertices.size()*sizeof(float), &mRenderBuffers.tmpVertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mRenderBuffers.IBO);
|
||||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mRenderBuffers.tmpIndices.size()*sizeof(unsigned int), &mRenderBuffers.tmpIndices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
int oldTexSize = mRenderBuffers.texSize;
|
||||
if (mRenderBuffers.texSize == 0) {
|
||||
// First time
|
||||
oldTexSize = 1;
|
||||
mRenderBuffers.texSize = 32;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int convexesPerRow = mRenderBuffers.texSize / 4;
|
||||
if (convexesPerRow * mRenderBuffers.texSize >= mRenderBuffers.numConvexes) {
|
||||
break;
|
||||
} else {
|
||||
mRenderBuffers.texSize *= 2;
|
||||
}
|
||||
}
|
||||
if (mRenderBuffers.texSize != oldTexSize) {
|
||||
mRenderBuffers.tmpTexCoords.resize(mRenderBuffers.texSize*mRenderBuffers.texSize*4);
|
||||
// Let's allocate texture
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, mRenderBuffers.texSize, mRenderBuffers.texSize, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
mRenderBufferVersion = mSceneVersion;
|
||||
|
||||
//instanceVBOCPU.resize( newSize * 16);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::updateConvexesTex()
|
||||
{
|
||||
float* tt = &mRenderBuffers.tmpTexCoords[0];
|
||||
|
||||
for (int k = 0; k < (int)mActors.size(); k++)
|
||||
{
|
||||
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++) {
|
||||
if ( ((Compound*)mCompounds[i])->getShader() != mShader)
|
||||
continue;
|
||||
|
||||
const shdfnd::Array<base::Convex*> &convexes = mCompounds[i]->getConvexes();
|
||||
for (int j = 0; j < (int)convexes.size(); j++) {
|
||||
Convex* c = (Convex*)convexes[j];
|
||||
|
||||
PxMat44 pose(convexes[j]->getGlobalPose());
|
||||
float* mp = (float*)pose.front();
|
||||
|
||||
float* ta = tt;
|
||||
for (int k = 0; k < 16; k++) {
|
||||
*(tt++) = *(mp++);
|
||||
}
|
||||
PxVec3 matOff = c->getMaterialOffset();
|
||||
ta[3] = matOff.x;
|
||||
ta[7] = matOff.y;
|
||||
ta[11] = matOff.z;
|
||||
int idFor2DTex = c->getSurfaceMaterialId();
|
||||
int idFor3DTex = 0;
|
||||
const int MAX_3D_TEX = 8;
|
||||
ta[15] = (float)(idFor2DTex*MAX_3D_TEX + idFor3DTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mRenderBuffers.texSize, mRenderBuffers.texSize,
|
||||
GL_RGBA, GL_FLOAT, &mRenderBuffers.tmpTexCoords[0]);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#ifdef USE_OPTIX
|
||||
|
||||
// Updater class for Optix renderer.
|
||||
class FractureModelUpdate : public optix_demo::IModelUpdate
|
||||
{
|
||||
public:
|
||||
|
||||
FractureModelUpdate( shdfnd::Array< Compound* > const& compounds, bool complete_update )
|
||||
: m_compounds(compounds), m_is_complete_update( complete_update )
|
||||
{}
|
||||
|
||||
bool isCompleteUpdate() const {return m_is_complete_update;}
|
||||
void to_first();
|
||||
void to_next();
|
||||
bool at_end() const;
|
||||
|
||||
size_t num_vertices() const {return (*m_iconvex)->getVisVertices().size();}
|
||||
size_t num_indices() const {return (*m_iconvex)->getVisTriIndices().size();}
|
||||
float const* vertices() const {return &(*m_iconvex)->getVisVertices()[0].x;}
|
||||
float const* normals() const {return &(*m_iconvex)->getVisNormals()[0].x;}
|
||||
int const* indices() const {return &(*m_iconvex)->getVisTriIndices()[0];}
|
||||
|
||||
void global_transform( float* rmat3x3, float* translation );
|
||||
|
||||
private:
|
||||
void advance();
|
||||
bool is_valid_convex( Convex const* c ) const
|
||||
{
|
||||
return !c->getVisVertices().empty();
|
||||
}
|
||||
|
||||
shdfnd::Array< Compound* > const& m_compounds;
|
||||
bool m_is_complete_update;
|
||||
shdfnd::Array< Compound* >::ConstIterator m_icompound;
|
||||
shdfnd::Array< Convex* >::ConstIterator m_iconvex;
|
||||
};
|
||||
|
||||
void FractureModelUpdate::to_first()
|
||||
{
|
||||
m_icompound = m_compounds.begin();
|
||||
if (m_icompound == m_compounds.end()) return;
|
||||
|
||||
while ((*m_icompound)->getConvexes().empty()) {
|
||||
++m_icompound;
|
||||
if (m_icompound == m_compounds.end()) return;
|
||||
}
|
||||
m_iconvex = (*m_icompound)->getConvexes().begin();
|
||||
while (!is_valid_convex(*m_iconvex)) {
|
||||
advance();
|
||||
if (m_icompound == m_compounds.end()) return;
|
||||
}
|
||||
}
|
||||
|
||||
void FractureModelUpdate::to_next()
|
||||
{
|
||||
if (m_icompound != m_compounds.end()) {
|
||||
do {
|
||||
advance();
|
||||
} while (m_icompound != m_compounds.end() && !is_valid_convex(*m_iconvex));
|
||||
}
|
||||
}
|
||||
|
||||
void FractureModelUpdate::advance()
|
||||
{
|
||||
if (m_iconvex != (*m_icompound)->getConvexes().end()) {
|
||||
++m_iconvex;
|
||||
}
|
||||
if (m_iconvex == (*m_icompound)->getConvexes().end()) {
|
||||
// End of convexes of this compound.
|
||||
do {
|
||||
++m_icompound;
|
||||
if (m_icompound == m_compounds.end()) return;
|
||||
} while ((*m_icompound)->getConvexes().empty());
|
||||
m_iconvex = (*m_icompound)->getConvexes().begin();
|
||||
}
|
||||
}
|
||||
|
||||
bool FractureModelUpdate::at_end() const
|
||||
{
|
||||
return m_icompound == m_compounds.end();
|
||||
}
|
||||
|
||||
void FractureModelUpdate::global_transform( float* rmat3x3, float* translation )
|
||||
{
|
||||
PxTransform pose = (*m_iconvex)->getGlobalPose();
|
||||
PxMat33 rot(pose.q);
|
||||
rmat3x3[0] = rot.column0.x; rmat3x3[1] = rot.column1.x; rmat3x3[2] = rot.column2.x;
|
||||
rmat3x3[3] = rot.column0.y; rmat3x3[4] = rot.column1.y; rmat3x3[5] = rot.column2.y;
|
||||
rmat3x3[6] = rot.column0.z; rmat3x3[7] = rot.column1.z; rmat3x3[8] = rot.column2.z;
|
||||
translation[0] = pose.p.x;
|
||||
translation[1] = pose.p.y;
|
||||
translation[2] = pose.p.z;
|
||||
}
|
||||
|
||||
#endif //USE_OPTIX
|
||||
|
||||
extern bool gConvexTexOutdate;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::draw(bool useShader)
|
||||
{
|
||||
if (mDebugDraw) {
|
||||
for (int k = 0; k < (int)mActors.size(); k++)
|
||||
{
|
||||
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
|
||||
for (int i = 0; i < (int)mCompounds.size(); i++)
|
||||
mCompounds[i]->draw(false, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int numCompounds = 0;
|
||||
for (int k = 0; k < (int)mActors.size(); k++)
|
||||
{
|
||||
const shdfnd::Array<base::Compound*>& mCompounds = mActors[k]->getCompounds();
|
||||
numCompounds += mCompounds.size();
|
||||
}
|
||||
if (numCompounds == 0) return;
|
||||
|
||||
|
||||
if (SampleViewerScene::getRenderType() == SampleViewerScene::rtOPENGL) {
|
||||
#if USE_CONVEX_RENDERER
|
||||
mConvexRenderer.setShaderMaterial(mShader, mShaderMat);
|
||||
mConvexRenderer.setTexArrays(diffuseTexArray, bumpTexArray,
|
||||
specularTexArray, emissiveReflectSpecPowerTexArray);
|
||||
mConvexRenderer.setVolTex(mRenderBuffers.volTex);
|
||||
mConvexRenderer.render();
|
||||
#else
|
||||
mConvexRenderer.setActive(false);
|
||||
|
||||
if (mRenderBufferVersion != mSceneVersion)
|
||||
createRenderBuffers();
|
||||
|
||||
if (mRenderBuffers.numIndices > 0) {
|
||||
|
||||
if (gConvexTexOutdate) {
|
||||
updateConvexesTex();
|
||||
gConvexTexOutdate = false;
|
||||
}
|
||||
|
||||
mShader->activate(mShaderMat);
|
||||
// Assume convex all use the same shader
|
||||
|
||||
glActiveTexture(GL_TEXTURE7);
|
||||
glBindTexture(GL_TEXTURE_3D, mRenderBuffers.volTex);
|
||||
|
||||
glActiveTexture(GL_TEXTURE8);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderBuffers.matTex);
|
||||
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, diffuseTexArray);
|
||||
glActiveTexture(GL_TEXTURE11);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, bumpTexArray);
|
||||
glActiveTexture(GL_TEXTURE12);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, specularTexArray);
|
||||
glActiveTexture(GL_TEXTURE13);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, emissiveReflectSpecPowerTexArray);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float itt = 1.0f/mRenderBuffers.texSize;
|
||||
|
||||
mShader->setUniform("diffuseTexArray", 10);
|
||||
mShader->setUniform("bumpTexArray", 11);
|
||||
mShader->setUniform("specularTexArray", 12);
|
||||
mShader->setUniform("emissiveReflectSpecPowerTexArray", 13);
|
||||
|
||||
mShader->setUniform("ttt3D", 7);
|
||||
mShader->setUniform("transTex", 8);
|
||||
mShader->setUniform("transTexSize", mRenderBuffers.texSize);
|
||||
mShader->setUniform("iTransTexSize", itt);
|
||||
mShader->setUniform("bumpTextureUVScale", bumpTextureUVScale);
|
||||
mShader->setUniform("extraNoiseScale",extraNoiseScale);
|
||||
mShader->setUniform("roughnessScale", roughnessScale);
|
||||
if (mShaderMat.color[3] < 1.0f) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glColor4f(mShaderMat.color[0], mShaderMat.color[1], mShaderMat.color[2], mShaderMat.color[3]);
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mRenderBuffers.VBO);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mRenderBuffers.IBO);
|
||||
|
||||
int stride = 12*sizeof(float);
|
||||
glVertexPointer(3, GL_FLOAT, stride, 0);
|
||||
|
||||
glNormalPointer(GL_FLOAT, stride, (void*)(3*sizeof(float)));
|
||||
|
||||
glTexCoordPointer(4, GL_FLOAT, stride, (void*)(6*sizeof(float)));
|
||||
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glTexCoordPointer(2, GL_FLOAT, stride, (void*)(10*sizeof(float)));
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, mRenderBuffers.numIndices, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
if (mShaderMat.color[3] < 1.0f) {
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
mShader->deactivate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_OPTIX
|
||||
else if (SampleViewerScene::getRenderType() == SampleViewerScene::rtOPTIX) {
|
||||
|
||||
FractureModelUpdate update( mCompounds, mOptixBufferVersion != mSceneVersion );
|
||||
|
||||
if (mOptixBufferVersion != mSceneVersion) {
|
||||
// Complete buffer update.
|
||||
mOptixBufferVersion = mSceneVersion;
|
||||
}
|
||||
|
||||
Profiler::getInstance()->begin("Optix data update");
|
||||
|
||||
SampleViewerScene::getOptixRenderer()->update( update );
|
||||
|
||||
OptixRenderer::Camera cam;
|
||||
const size_t size_of_float3 = sizeof(float) * 3;
|
||||
PxVec3 lookat = mCameraPos + mCameraDir;
|
||||
memcpy( cam.eye, &mCameraPos.x, size_of_float3);
|
||||
memcpy( cam.lookat, &lookat.x, size_of_float3);
|
||||
memcpy( cam.up, &mCameraUp.x, size_of_float3);
|
||||
cam.fov = mCameraFov;
|
||||
Profiler::getInstance()->end("Optix data update");
|
||||
|
||||
Profiler::getInstance()->begin("Optix render");
|
||||
SampleViewerScene::getOptixRenderer()->render( cam );
|
||||
Profiler::getInstance()->end("Optix render");
|
||||
}
|
||||
#endif // USE_OPTIX
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void SimScene::dumpSceneGeometry()
|
||||
{
|
||||
#ifdef USE_OPTIX
|
||||
if( SampleViewerScene::getRenderType() == SampleViewerScene::rtOPTIX && SampleViewerScene::getOptixRenderer()) {
|
||||
SampleViewerScene::getOptixRenderer()->dump_geometry();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
107
kaplademo/source/kaplaDemo/Fracture/SimScene.h
Normal file
107
kaplademo/source/kaplaDemo/Fracture/SimScene.h
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef SIM_SCENE
|
||||
#define SIM_SCENE
|
||||
|
||||
#include "Shader.h"
|
||||
#include "PxPhysics.h"
|
||||
#include "PxCooking.h"
|
||||
#include "PxSimulationEventCallback.h"
|
||||
#include <PsArray.h>
|
||||
#include "ConvexRenderer.h"
|
||||
|
||||
#include "SimSceneBase.h"
|
||||
|
||||
using namespace physx::fracture;
|
||||
|
||||
class TerrainMesh;
|
||||
struct ParticlesDesc;
|
||||
class Particles;
|
||||
class RegularCell3D;
|
||||
class Actor;
|
||||
|
||||
class SimScene : public base::SimScene
|
||||
{
|
||||
public:
|
||||
static SimScene* createSimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath);
|
||||
protected:
|
||||
SimScene(PxPhysics *pxPhysics, PxCooking *pxCooking, bool isGrbScene, float minConvexSize, PxMaterial* defaultMat, const char *resourcePath);
|
||||
public:
|
||||
virtual ~SimScene();
|
||||
|
||||
virtual void createSingletons();
|
||||
|
||||
virtual base::Actor* createActor();
|
||||
virtual base::Convex* createConvex();
|
||||
virtual base::Compound* createCompound(PxReal contactOffset = 0.005f, PxReal restOffset = -0.001f);
|
||||
|
||||
virtual void clear();
|
||||
|
||||
virtual void profileBegin(const char* name);
|
||||
virtual void profileEnd(const char* name);
|
||||
|
||||
bool addXml(const std::string &path, const std::string &filename, bool ignoreVisualMesh, float scale, const PxTransform &trans,
|
||||
Shader* defaultShader, const ShaderMaterial &defaultMat);
|
||||
|
||||
void postSim(float dt, RegularCell3D* fluidSim);
|
||||
|
||||
//Particles* getParticles() { return mParticles; }
|
||||
|
||||
ConvexRenderer &getConvexRenderer() { return mConvexRenderer; }
|
||||
|
||||
void draw(bool useShader);
|
||||
void setShaderMaterial(Shader* shader, const ShaderMaterial& mat) {this->mShader = shader; this->mShaderMat = mat;}
|
||||
void setFractureForceThreshold(float threshold) { mFractureForceThreshold = threshold; }
|
||||
void createRenderBuffers();
|
||||
void dumpSceneGeometry();
|
||||
|
||||
void loadAndCreateTextureArrays();
|
||||
|
||||
std::vector<std::string> diffuseTexNames;
|
||||
std::vector<std::string> bumpTexNames;
|
||||
std::vector<std::string> specularTexNames;
|
||||
std::vector<std::string> emissiveReflectSpecPowerTexNames;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void create3dTexture();
|
||||
virtual void updateConvexesTex();
|
||||
|
||||
GLuint diffuseTexArray, bumpTexArray, specularTexArray, emissiveReflectSpecPowerTexArray;
|
||||
|
||||
GLuint loadTextureArray(std::vector<std::string>& names);
|
||||
|
||||
//Particles *mParticles;
|
||||
|
||||
ConvexRenderer mConvexRenderer;
|
||||
|
||||
Shader* mShader;
|
||||
ShaderMaterial mShaderMat;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user