-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCPhysXCloth.h
180 lines (147 loc) · 5.28 KB
/
CPhysXCloth.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma once
#include <irrlicht.h>
using namespace irr;
class CPhysXCloth
{
//these are initial steps to use cloth in our game
//include them in the main class and return actor or node- preferrably node to aneble irrlicht rendering
//can't wait to see that working
//one issue I have, how on earth are we going to translate the cloth PhysX object to a renderable in Irrlicht object ?
//Create cloth
/*PxClothMeshDesc meshDesc;
meshDesc.setToDefault();
//Fill the geometry
int w = 8, h=7;
float hw = w / 2.0f;
float hh = h / 2.0f;
d = 0.2f;
int numX = (int)(w / d) + 1;
int numY = (int)(h / d) + 1;
meshDesc.points.count= (numX+1) * (numY+1);
meshDesc.triangles.count= numX*numY*2;
meshDesc.points.stride= sizeof(PxVec3);
meshDesc.triangles.stride= 3*sizeof(PxU32);
meshDesc.points.data= (PxVec3*)malloc(sizeof(PxVec3)*meshDesc.points.count);
meshDesc.triangles.data= (PxU32*)malloc(sizeof(PxU32)*meshDesc.triangles.count*3);
meshDesc.edgeFlags = 0;
//Fill the geometry
int i,j;
PxVec3 *p = (PxVec3*)meshDesc.points.data;
pos.resize(meshDesc.points.count);
normal.resize(meshDesc.points.count);
indices.resize(meshDesc.triangles.count*3);
for (i = 0; i <= numY; i++) {
for (j = 0; j <= numX; j++) {
p->x = d*j-hw;
p->y = float(h);
p->z = d*i;
p++;
}
}
memcpy(&pos[0].x, (meshDesc.points.data), sizeof(PxVec3)*meshDesc.points.count);
//Fill the topology
PxU32 *id = (PxU32*)meshDesc.triangles.data;
for (i = 0; i < numY; i++) {
for (j = 0; j < numX; j++) {
PxU32 i0 = i * (numX+1) + j;
PxU32 i1 = i0 + 1;
PxU32 i2 = i0 + (numX+1);
PxU32 i3 = i2 + 1;
if ((j+i)%2) {
*id++ = i0; *id++ = i2; *id++ = i1;
*id++ = i1; *id++ = i2; *id++ = i3;
} else {
*id++ = i0; *id++ = i2; *id++ = i3;
*id++ = i0; *id++ = i3; *id++ = i1;
}
}
}
memcpy(&indices[0], meshDesc.triangles.data, sizeof(PxU32)*meshDesc.triangles.count*3);
//Make sure everything is fine so far
if(!(meshDesc.isValid()))
cerr<<"Mesh invalid."<<endl;
//Start cooking of fibres
PxCookingParams cp;
PxCooking* cooking = PxCreateCooking(PX_PHYSICS_VERSION, &(gPhysicsSDK->getFoundation()), cp);
MemoryWriteBuffer buf;
bool status = cooking->cookClothFabric(meshDesc,sceneDesc.gravity, buf);
if(!status) {
cerr<<"Problem cooking mesh.\nExiting ..."<<endl;
exit(1);
}
PxClothFabric* fabric=gPhysicsSDK->createClothFabric(MemoryReadBuffer(buf.data));
PxTransform tr;
tr.p = PxVec3(0,10,0); tr.q = PxQuat::createIdentity();
PxClothParticle* points=(PxClothParticle*)malloc(sizeof(PxClothParticle)*meshDesc.points.count);
p = (PxVec3*)meshDesc.points.data;
for(size_t i=0;i<meshDesc.points.count;i++) {
points[i].pos = *p;
//Fixing the top corner points
if(i==0 || i==numX)
points[i].invWeight =0;
else
points[i].invWeight = 1.f;
p++;
}
PxClothCollisionData cd;
cd.setToDefault();
cd.numSpheres=1;
cd.pairIndexBuffer=0;
box_collider.pos= PxVec3(0.0f,2.0f,0.0f);
box_collider.radius=1;
cd.spheres=&box_collider;
cloth = gPhysicsSDK->createCloth(tr,*fabric,points, cd, PxClothFlag::eSWEPT_CONTACT);
if(cloth) {
PxClothPhaseSolverConfig bendCfg;
bendCfg.solverType= PxClothPhaseSolverConfig::eFAST;
bendCfg.stiffness = 1;
bendCfg.stretchStiffness = 0.5;
cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eBENDING, bendCfg) ;
cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eSTRETCHING, bendCfg) ;
cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eSHEARING, bendCfg) ;
cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eSTRETCHING_HORIZONTAL, bendCfg) ;
cloth->setDampingCoefficient(0.125f);
gScene->addActor(*cloth);
}
else
cerr<<"Cannot create cloth"<<endl;
void RenderCloth()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(PxVec3), &(pos[0].x));
glNormalPointer(GL_FLOAT, sizeof(PxVec3), &(normal[0].x));
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, &indices[0]);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
//update the cloth data
PxClothReadData* pData = cloth->lockClothReadData();
PxClothParticle* pParticles = const_cast<PxClothParticle*>(pData->particles);
//update the positions
for(size_t i=0;i<pos.size();i++) {
pos[i] = pParticles[i].pos;
if(pos[i].y<0)
{
pos[i].y=0;
pParticles[i].pos.y=0;
}
}
pData->unlock();
//update normals
for(size_t i=0;i<indices.size();i+=3)
{
PxVec3 p1 = pos[indices[i]];
PxVec3 p2 = pos[indices[i+1]];
PxVec3 p3 = pos[indices[i+2]];
PxVec3 n = (p2-p1).cross(p3-p1);
normal[indices[i]] += n/3.0f ;
normal[indices[i+1]] += n/3.0f ;
normal[indices[i+2]] += n/3.0f ;
}
for(size_t i=0;i<normal.size();i++)
{
PxVec3& n = normal[i];
n= n.getNormalized();
}*/
};