void Update(Scene* scene, float dt) { Particle* particles = &scene->mParticles[0]; Triangle* triangles = &scene->mTriangles[0]; Element* elements = &scene->mElements[0]; const Vec3* planes = &scene->mPlanes[0]; uint32_t numParticles = NumParticles(scene); uint32_t numTriangles = NumTriangles(scene); uint32_t numPlanes = scene->mPlanes.size(); SceneParams params = scene->mParams; FractureEvent* fractures = &scene->mFractures[0]; uint32_t maxFractures = scene->mFractures.size(); uint32_t numFractures = UpdateForces(particles, numParticles, triangles, elements, numTriangles, params.mGravity, params.mLameLambda, params.mLameMu, params.mDamping, params.mDrag, dt, fractures, maxFractures, params.mToughness, params.mYield, params.mCreep); CollidePlanes(particles, numParticles, planes, numPlanes, params.mFriction); IntegrateForces(particles, numParticles, dt); //if (numFractures) // cout << "numFractures: " << numFractures << endl; // todo. ugh figure out a better way to manage this scene->mParticles.resize(2*numParticles); particles = &scene->mParticles[0]; /* glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_LINES); for (size_t i=0; i < numFractures; ++i) { Vec2 p = Vec2(fractures[i].mPlane)*-fractures[i].mPlane.z; Vec2 n = PerpCCW(Vec2(fractures[i].mPlane)); glVertex2fv(p+n*100.0f); glVertex2fv(p-n*100.0f); glVertex2fv(p); glVertex2fv(p + Vec2(fractures[i].mPlane)); } glEnd(); */ if (params.mToughness > 0.0f) { numParticles = Fracture(particles, numParticles, triangles, numTriangles, fractures, numFractures); numParticles = SeparateSingular(particles, numParticles, triangles, numTriangles); } scene->mParticles.resize(numParticles); particles = &scene->mParticles[0]; }
Sphere::Sphere(int numSubdiv, bool smooth) : _vertices(NULL), _indices(NULL), _numVerts(0) { // not exception-safe _numVerts = NumVertices(numSubdiv); _vertices = new Mesh::Vertex[_numVerts]; _indices = new Mesh::Index[_numVerts]; Mesh::Vertex* vert = _vertices; unsigned numTris = NumTriangles(numSubdiv); for(Mesh::Index i = 0; i < 20; ++i) { Subdivide(&vert, numSubdiv, smooth, g_vertices[g_indices[i][0]].position, g_vertices[g_indices[i][1]].position, g_vertices[g_indices[i][2]].position); } for(Mesh::Index i = 0; i < _numVerts; i++) { _indices[i] = i; } }
/** * Exports all geometry into a D3D .x file into the current working folder. * @param Filename Desired filename (may include path) * @param bShow Whether the D3D .x file viewer should be invoked. If shown, we'll block until it has been closed. */ void F3DVisualizer::Export( const TCHAR* Filename, bool bShow/*=false*/ ) { ID3DXMesh* Mesh; Mesh = NULL; int32 NumPrimitives = NumTriangles() + NumLines()*2; int32 NumVertices = NumTriangles()*3 + NumLines()*4; HRESULT Result = D3DXCreateMeshFVF( NumPrimitives, NumVertices, D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_SPECULAR, D3D->D3DDevice, &Mesh ); void* VertexBuffer = NULL; void* IndexBuffer = NULL; Result = Mesh->LockVertexBuffer(D3DLOCK_DISCARD, &VertexBuffer); Result = Mesh->LockIndexBuffer(D3DLOCK_DISCARD, &IndexBuffer); D3DXVertex* Vertices = (D3DXVertex*)VertexBuffer; uint32* Indices = (uint32*) IndexBuffer; int32 NumVerticesStored = 0; int32 NumIndicesStored = 0; // Add the triangles to the vertexbuffer and indexbuffer. for ( int32 TriangleIndex=0; TriangleIndex < NumTriangles(); ++TriangleIndex ) { const FVector4& P1 = Triangles[TriangleIndex].Vertices[0]; const FVector4& P2 = Triangles[TriangleIndex].Vertices[1]; const FVector4& P3 = Triangles[TriangleIndex].Vertices[2]; const FColor& Color = Triangles[TriangleIndex].Color; Vertices[NumVerticesStored+0].Pos[0] = P1[0]; Vertices[NumVerticesStored+0].Pos[1] = P1[1]; Vertices[NumVerticesStored+0].Pos[2] = P1[2]; Vertices[NumVerticesStored+0].Color1 = Color.DWColor(); Vertices[NumVerticesStored+0].Color2 = 0; Vertices[NumVerticesStored+1].Pos[0] = P2[0]; Vertices[NumVerticesStored+1].Pos[1] = P2[1]; Vertices[NumVerticesStored+1].Pos[2] = P2[2]; Vertices[NumVerticesStored+1].Color1 = Color.DWColor(); Vertices[NumVerticesStored+1].Color2 = 0; Vertices[NumVerticesStored+2].Pos[0] = P3[0]; Vertices[NumVerticesStored+2].Pos[1] = P3[1]; Vertices[NumVerticesStored+2].Pos[2] = P3[2]; Vertices[NumVerticesStored+2].Color1 = Color.DWColor(); Vertices[NumVerticesStored+2].Color2 = 0; // Reverse triangle winding order for the .x file. Indices[NumIndicesStored+0] = NumVerticesStored + 0; Indices[NumIndicesStored+1] = NumVerticesStored + 2; Indices[NumIndicesStored+2] = NumVerticesStored + 1; NumVerticesStored += 3; NumIndicesStored += 3; } // Add the lines to the vertexbuffer and indexbuffer. for ( int32 LineIndex=0; LineIndex < NumLines(); ++LineIndex ) { const FVector4& P1 = Lines[LineIndex].Vertices[0]; const FVector4& P2 = Lines[LineIndex].Vertices[1]; const FColor& Color = Lines[LineIndex].Color; Vertices[NumVerticesStored+0].Pos[0] = P1[0]; Vertices[NumVerticesStored+0].Pos[1] = P1[1] - 5.0f; Vertices[NumVerticesStored+0].Pos[2] = P1[2]; Vertices[NumVerticesStored+0].Color1 = 0; Vertices[NumVerticesStored+0].Color2 = Color.DWColor(); Vertices[NumVerticesStored+1].Pos[0] = P1[0]; Vertices[NumVerticesStored+1].Pos[1] = P1[1] + 5.0f; Vertices[NumVerticesStored+1].Pos[2] = P1[2]; Vertices[NumVerticesStored+1].Color1 = 0; Vertices[NumVerticesStored+1].Color2 = Color.DWColor(); Vertices[NumVerticesStored+2].Pos[0] = P2[0]; Vertices[NumVerticesStored+2].Pos[1] = P2[1] - 5.0f; Vertices[NumVerticesStored+2].Pos[2] = P2[2]; Vertices[NumVerticesStored+2].Color1 = 0; Vertices[NumVerticesStored+2].Color2 = Color.DWColor(); Vertices[NumVerticesStored+3].Pos[0] = P2[0]; Vertices[NumVerticesStored+3].Pos[1] = P2[1] + 5.0f; Vertices[NumVerticesStored+3].Pos[2] = P2[2]; Vertices[NumVerticesStored+3].Color1 = 0; Vertices[NumVerticesStored+3].Color2 = Color.DWColor(); Indices[NumIndicesStored+0] = NumVerticesStored+0; Indices[NumIndicesStored+1] = NumVerticesStored+2; Indices[NumIndicesStored+2] = NumVerticesStored+1; Indices[NumIndicesStored+3] = NumVerticesStored+2; Indices[NumIndicesStored+4] = NumVerticesStored+3; Indices[NumIndicesStored+5] = NumVerticesStored+1; NumVerticesStored += 4; NumIndicesStored += 6; } Mesh->UnlockVertexBuffer(); Mesh->UnlockIndexBuffer(); Result = D3DXComputeNormals( Mesh, NULL ); D3DXMATERIAL MeshMaterial; MeshMaterial.MatD3D.Ambient.r = 0.1f; MeshMaterial.MatD3D.Ambient.g = 0.1f; MeshMaterial.MatD3D.Ambient.b = 0.1f; MeshMaterial.MatD3D.Ambient.a = 0.0f; MeshMaterial.MatD3D.Diffuse.r = 1.0f; MeshMaterial.MatD3D.Diffuse.g = 1.0f; MeshMaterial.MatD3D.Diffuse.b = 1.0f; MeshMaterial.MatD3D.Diffuse.a = 1.0f; MeshMaterial.MatD3D.Emissive.r = 1.0f; MeshMaterial.MatD3D.Emissive.g = 1.0f; MeshMaterial.MatD3D.Emissive.b = 1.0f; MeshMaterial.MatD3D.Emissive.a = 1.0f; MeshMaterial.MatD3D.Specular.r = 1.0f; MeshMaterial.MatD3D.Specular.g = 1.0f; MeshMaterial.MatD3D.Specular.b = 1.0f; MeshMaterial.MatD3D.Specular.a = 1.0f; MeshMaterial.MatD3D.Power = 16.0f; MeshMaterial.pTextureFilename = NULL; D3DXEFFECTINSTANCE EffectInstance; EffectInstance.pEffectFilename = "D3DExport.fx"; EffectInstance.NumDefaults = 0; EffectInstance.pDefaults = NULL; // Write out the .x file. D3DXSaveMeshToX( Filename, Mesh, NULL, &MeshMaterial, &EffectInstance, 1, D3DXF_FILEFORMAT_BINARY ); Mesh->Release(); // Write out the .fx file, if it doesn't always exist. HANDLE ShaderFile = CreateFile( TEXT("D3DExport.fx"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (ShaderFile != INVALID_HANDLE_VALUE) { ::DWORD BytesWritten; WriteFile(ShaderFile, ShaderFxFile, (uint32)FCStringAnsi::Strlen(ShaderFxFile), &BytesWritten, NULL); CloseHandle( ShaderFile ); } // If specified, run the default viewer for .x files and block until it's closed. if ( bShow ) { system( TCHAR_TO_ANSI(Filename) ); } }
// computes toTangent*/toObject* stuff void Mesh::Prepare(void) { if(_prepared) return; unsigned numVertices = 3 * NumTriangles(); _vertices = new Vertex[numVertices]; for(unsigned i = 0; i < numVertices; ++i) { _vertices[i].numTri = 0; _vertices[i].toObject[2] = M::Vector3::Zero; } for(unsigned i = 0; i < NumTriangles(); ++i) { const Triangle* triangle = &Triangles()[i]; for(int j = 0; j < 3; ++j) { int x0 = triangle->vertices[j]; int x1 = triangle->vertices[(j + 1) % 3]; int x2 = triangle->vertices[(j + 2) % 3]; M::Vector3 a0 = Vertices()[x0]; M::Vector3 a1 = Vertices()[x1]; M::Vector3 a2 = Vertices()[x2]; M::Vector3 v1 = Vertices()[x1] - Vertices()[x0]; M::Vector3 v2 = Vertices()[x2] - Vertices()[x0]; float d1_0 = TexCoords()[x1].s - TexCoords()[x0].s; float d1_1 = TexCoords()[x1].t - TexCoords()[x0].t; float d2_0 = TexCoords()[x2].s - TexCoords()[x0].s; float d2_1 = TexCoords()[x2].t - TexCoords()[x0].t; float det = d1_0 * d2_1 - d2_0 * d1_1; _vertices[x0].toObject[0] = (d2_1 * v1 - d1_1 * v2) / det; _vertices[x0].toObject[1] = (-d2_0 * v1 + d1_0 * v2) / det; _vertices[x0].toObject[2] += M::Cross(v2, v1); _vertices[x0].numTri++; } } for(unsigned i = 0; i < numVertices; ++i) { _vertices[i].toObject[2] /= (float)_vertices[i].numTri; for(int j = 0; j < 3; ++j) { _vertices[i].toObject[j].Normalize(); } M::Vector3 A0 = _vertices[i].toObject[0]; M::Vector3 A1 = _vertices[i].toObject[1]; M::Vector3 A2 = _vertices[i].toObject[2]; M::Matrix3 mat = M::Mat3::FromColumns(A0, A1, A2); M::Matrix3 inv = M::Mat3::Inverse(mat); M::Mat3::ToColumns(inv, A0, A1, A2); _vertices[i].toTangent[0] = A0; _vertices[i].toTangent[1] = A1; _vertices[i].toTangent[2] = A2; } _prepared = true; }
void GetTriangles(const Scene* scene, Triangle* dest) { if (!scene->mTriangles.empty()) memcpy(dest, &scene->mTriangles[0], sizeof(Triangle)*NumTriangles(scene)); }