void BaseMesh::ReCreateCylinder(Vec3f (*PositionFunction) (float), float Start, float End, float radius, UINT slices, UINT stacks) { MeshVertex *V = Vertices(); Matrix4 Face, Translate; Vec3f Tangent; float DeltaT = 0.0001f,Time,Theta; float PI2_Slices = 2.0f * Math::PIf / float(slices); Vec3f CurPos; for(UINT i = 0; i <= stacks; i++) { Time = float(Math::LinearMap(0.0f,float(stacks),Start,End,float(i))); //get the approriate value between Start and End CurPos = PositionFunction(Time); //get the current position along the curve if(Time + DeltaT <= End) Tangent = PositionFunction(Time + DeltaT) - CurPos; //approximate the derivative (tangent vector) else Tangent = CurPos - PositionFunction(Time - DeltaT); Face = Matrix4::Face(Vec3f(0.0f, 0.0f, 1.0f), Tangent); //face Matrix4 causes the local cylinder ring to face the right direction Translate = Matrix4::Translation(CurPos); //the local cylinder ring should be centered on CurPos Face = Face * Translate; for(UINT i2 = 0; i2 < slices; i2++) { Theta = float(i2) * PI2_Slices; V[i*slices+i2].Pos = Vec3f(radius * cosf(Theta), radius * sinf(Theta), 0.0f); //construct the basic circle V[i*slices+i2].Pos = Face.TransformPoint(V[i*slices+i2].Pos); //transform the circle to its approrpriate using the Matrix4 } } GenerateNormals(); }
void BaseMesh::Split(float (*PositionFunction) (Vec3f &), BaseMesh &M1, BaseMesh &M2) { int i,vc=VertexCount(),ic=IndexCount(); MeshVertex *V = Vertices(); DWORD *I = Indices(); Vector<MeshVertex> NV1,NV2; Vector<TriMeshFace> NT1,NT2; SplitVMapper *VMap = new SplitVMapper[vc]; float Value; for(i=0;i<vc;i++) { Value = PositionFunction(V[i].Pos); if(Value < 0.0f) { VMap[i].Side = 0; VMap[i].NVMap1 = NV1.Length(); VMap[i].NVMap2 = -1; NV1.PushEnd(V[i]); } else { VMap[i].Side = 1; VMap[i].NVMap1 = -1; VMap[i].NVMap2 = NV2.Length(); NV2.PushEnd(V[i]); } } int TSide[3]; TriMeshFace Tri; int Oddball,State; for(i=0;i<ic;i+=3) { TSide[0] = VMap[I[i]].Side; TSide[1] = VMap[I[i+1]].Side; TSide[2] = VMap[I[i+2]].Side; if(TSide[0] && TSide[1] && TSide[2]) //all O2 { Tri.I[0] = VMap[I[i]].NVMap2; Tri.I[1] = VMap[I[i+1]].NVMap2; Tri.I[2] = VMap[I[i+2]].NVMap2; NT2.PushEnd(Tri); } else if(!(TSide[0] || TSide[1] || TSide[2])) //all O1 { Tri.I[0] = VMap[I[i]].NVMap1; Tri.I[1] = VMap[I[i+1]].NVMap1; Tri.I[2] = VMap[I[i+2]].NVMap1; NT1.PushEnd(Tri); } else { if(TSide[0] && TSide[1]) {Oddball = 2; State = 1;} if(TSide[0] && TSide[2]) {Oddball = 1; State = 1;} if(TSide[1] && TSide[2]) {Oddball = 0; State = 1;} if(!(TSide[0] || TSide[1])) {Oddball = 2; State = 2;} if(!(TSide[0] || TSide[2])) {Oddball = 1; State = 2;} if(!(TSide[1] || TSide[2])) {Oddball = 0; State = 2;} if(State == 1) //Add to Obj2 { if(VMap[I[i+Oddball]].NVMap2 == -1) { VMap[I[i+Oddball]].NVMap2 = NV2.Length(); NV2.PushEnd(V[I[i+Oddball]]); } Tri.I[0] = VMap[I[i]].NVMap2; Tri.I[1] = VMap[I[i+1]].NVMap2; Tri.I[2] = VMap[I[i+2]].NVMap2; NT2.PushEnd(Tri); } else { //Add to Obj1 if(VMap[I[i+Oddball]].NVMap1 == -1) { VMap[I[i+Oddball]].NVMap1 = NV1.Length(); NV1.PushEnd(V[I[i+Oddball]]); } Tri.I[0] = VMap[I[i]].NVMap1; Tri.I[1] = VMap[I[i+1]].NVMap1; Tri.I[2] = VMap[I[i+2]].NVMap1; NT1.PushEnd(Tri); } } } delete[] VMap; M1.Allocate(NV1.Length(),NT1.Length()); M2.Allocate(NV2.Length(),NT2.Length()); memcpy(M1.Vertices(), NV1.CArray(), M1.VertexCount() * sizeof(MeshVertex)); memcpy(M2.Vertices(), NV2.CArray(), M2.VertexCount() * sizeof(MeshVertex)); memcpy(M1.Indices(), NT1.CArray(), M1.IndexCount() * sizeof(DWORD)); memcpy(M2.Indices(), NT2.CArray(), M2.IndexCount() * sizeof(DWORD)); }