123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- //
- // The graphics engine GLXEngine. The unit of GXScene for Delphi
- //
- unit GXS.MeshBuilder;
- (*
- Build mesh objects.
- How often do you miss a BuildSphereMesh function for testing or editors?
- Well this unit is intended to solve that problem. We want fast,
- flexible functions with lots of options...
- *)
- interface
- uses
- System.SysUtils,
- System.Classes,
- GXS.Scene,
- GXS.VectorFileObjects,
- Stage.VectorTypes,
- Stage.VectorGeometry,
- GXS.VectorLists;
- procedure BuildCube(Mesh: TgxMeshObject; Position, Scale: TAffineVector);
- procedure BuildCylinder(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
- Slices: Integer);
- procedure BuildCylinder2(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
- TopRadius, BottomRadius, Height: single; Slices: Integer);
- // ----------------------------------------------------------------------------
- implementation
- // ----------------------------------------------------------------------------
- function VectorCombineWeighted(Position, Scale: TAffineVector; X, Y, Z: single)
- : TAffineVector;
- begin
- Result.X := Position.X + Scale.X * X;
- Result.Y := Position.Y + Scale.Y * Y;
- Result.Z := Position.Z + Scale.Z * Z;
- end;
- procedure BuildCube(Mesh: TgxMeshObject; Position, Scale: TAffineVector);
- var
- FGR: TFGVertexNormalTexIndexList;
- VertexOffset: Integer;
- NormalOffset: Integer;
- TextureOffset: Integer;
- begin
- // Vertexes
- VertexOffset := Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5,
- 0.5, 0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, 0.5, 0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5, -0.5, 0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, -0.5, 0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5, 0.5, -0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, 0.5, -0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5, -0.5, -0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, -0.5, -0.5));
- // Normals
- NormalOffset := Mesh.Normals.Add(AffineVectorMake(0, 0, 1));
- Mesh.Normals.Add(AffineVectorMake(0, 0, -1));
- Mesh.Normals.Add(AffineVectorMake(1, 0, 0));
- Mesh.Normals.Add(AffineVectorMake(-1, 0, 0));
- Mesh.Normals.Add(AffineVectorMake(0, 1, 0));
- Mesh.Normals.Add(AffineVectorMake(0, -1, 0));
- // Texture Coordinates
- TextureOffset := Mesh.TexCoords.Add(AffineVectorMake(1, 1, 1));
- Mesh.TexCoords.Add(AffineVectorMake(0, 1, 1));
- Mesh.TexCoords.Add(AffineVectorMake(1, 0, 1));
- Mesh.TexCoords.Add(AffineVectorMake(0, 0, 1));
- Mesh.TexCoords.Add(AffineVectorMake(1, 1, 0));
- Mesh.TexCoords.Add(AffineVectorMake(0, 1, 0));
- Mesh.TexCoords.Add(AffineVectorMake(1, 0, 0));
- Mesh.TexCoords.Add(AffineVectorMake(0, 0, 0));
- FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
- FGR.Mode := fgmmTriangles;
- // front
- FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 1, VertexOffset + 3);
- FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 3, VertexOffset + 2);
- FGR.NormalIndices.Add(NormalOffset + 0, NormalOffset + 0, NormalOffset + 0);
- FGR.NormalIndices.Add(NormalOffset + 0, NormalOffset + 0, NormalOffset + 0);
- FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 1,
- TextureOffset + 3);
- FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 3,
- TextureOffset + 2);
- // back
- FGR.VertexIndices.Add(VertexOffset + 4, VertexOffset + 6, VertexOffset + 7);
- FGR.VertexIndices.Add(VertexOffset + 4, VertexOffset + 7, VertexOffset + 5);
- FGR.NormalIndices.Add(NormalOffset + 1, NormalOffset + 1, NormalOffset + 1);
- FGR.NormalIndices.Add(NormalOffset + 1, NormalOffset + 1, NormalOffset + 1);
- FGR.TexCoordIndices.Add(TextureOffset + 4, TextureOffset + 6,
- TextureOffset + 7);
- FGR.TexCoordIndices.Add(TextureOffset + 4, TextureOffset + 7,
- TextureOffset + 5);
- // right
- FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 2, VertexOffset + 6);
- FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 6, VertexOffset + 4);
- FGR.NormalIndices.Add(NormalOffset + 2, NormalOffset + 2, NormalOffset + 2);
- FGR.NormalIndices.Add(NormalOffset + 2, NormalOffset + 2, NormalOffset + 2);
- FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 2,
- TextureOffset + 6);
- FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 6,
- TextureOffset + 4);
- // left
- FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + 5, VertexOffset + 7);
- FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + 7, VertexOffset + 3);
- FGR.NormalIndices.Add(NormalOffset + 3, NormalOffset + 3, NormalOffset + 3);
- FGR.NormalIndices.Add(NormalOffset + 3, NormalOffset + 3, NormalOffset + 3);
- FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + 5,
- TextureOffset + 7);
- FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + 7,
- TextureOffset + 3);
- // top
- FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 4, VertexOffset + 5);
- FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 5, VertexOffset + 1);
- FGR.NormalIndices.Add(NormalOffset + 4, NormalOffset + 4, NormalOffset + 4);
- FGR.NormalIndices.Add(NormalOffset + 4, NormalOffset + 4, NormalOffset + 4);
- FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 4,
- TextureOffset + 5);
- FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 5,
- TextureOffset + 1);
- // bottom
- FGR.VertexIndices.Add(VertexOffset + 2, VertexOffset + 3, VertexOffset + 7);
- FGR.VertexIndices.Add(VertexOffset + 2, VertexOffset + 7, VertexOffset + 6);
- FGR.NormalIndices.Add(NormalOffset + 5, NormalOffset + 5, NormalOffset + 5);
- FGR.NormalIndices.Add(NormalOffset + 5, NormalOffset + 5, NormalOffset + 5);
- FGR.TexCoordIndices.Add(TextureOffset + 2, TextureOffset + 3,
- TextureOffset + 7);
- FGR.TexCoordIndices.Add(TextureOffset + 2, TextureOffset + 7,
- TextureOffset + 6);
- end;
- procedure BuildCylinder(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
- Slices: Integer);
- var
- FGR: TFGVertexNormalTexIndexList;
- VertexOffset: Integer;
- NormalOffset: Integer;
- TextureOffset: Integer;
- Cosine, Sine: Array of single;
- xc, yc: Integer;
- begin
- If Slices < 3 then
- Exit;
- SetLength(Sine, Slices + 1);
- SetLength(Cosine, Slices + 1);
- PrepareSinCosCache(Sine, Cosine, 0, 360);
- VertexOffset := Mesh.Vertices.Count;
- NormalOffset := Mesh.Normals.Count;
- TextureOffset := Mesh.TexCoords.Count;
- For xc := 0 to Slices - 1 do
- begin
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5 * Cosine[xc],
- 0.5 * Sine[xc], 0.5));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5 * Cosine[xc],
- 0.5 * Sine[xc], -0.5));
- // Normals
- Mesh.Normals.Add(AffineVectorMake(Cosine[xc], Sine[xc], 0));
- // Texture Coordinates
- Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
- 0.5 * Cosine[xc], 0.5 * Sine[xc], 0.5));
- Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
- 0.5 * Cosine[xc], 0.5 * Sine[xc], -0.5));
- end;
- Mesh.Normals.Add(AffineVectorMake(0, 0, 1));
- Mesh.Normals.Add(AffineVectorMake(0, 0, -1));
- FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
- FGR.Mode := fgmmTriangles;
- for xc := 0 to Slices - 1 do
- begin
- yc := xc + 1;
- If yc = Slices then
- yc := 0;
- FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + xc * 2 + 1,
- VertexOffset + yc * 2 + 1);
- FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + yc * 2 + 1,
- VertexOffset + yc * 2);
- FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + xc,
- NormalOffset + yc);
- FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + yc,
- NormalOffset + yc);
- FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + xc * 2 + 1,
- TextureOffset + yc * 2 + 1);
- FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + yc * 2 + 1,
- TextureOffset + yc * 2);
- end;
- for xc := 1 to Slices - 2 do
- begin
- yc := xc + 1;
- FGR.VertexIndices.Add(VertexOffset, VertexOffset + xc * 2,
- VertexOffset + yc * 2);
- FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + yc * 2 + 1,
- VertexOffset + xc * 2 + 1);
- FGR.NormalIndices.Add(NormalOffset + Slices, NormalOffset + Slices,
- NormalOffset + Slices);
- FGR.NormalIndices.Add(NormalOffset + Slices + 1, NormalOffset + Slices + 1,
- NormalOffset + Slices + 1);
- FGR.TexCoordIndices.Add(TextureOffset, TextureOffset + xc * 2,
- TextureOffset + yc * 2);
- FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + yc * 2 + 1,
- TextureOffset + xc * 2 + 1);
- end;
- end;
- procedure BuildCylinder2(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
- TopRadius, BottomRadius, Height: single; Slices: Integer);
- var
- FGR: TFGVertexNormalTexIndexList;
- VertexOffset: Integer;
- NormalOffset: Integer;
- TextureOffset: Integer;
- Cosine, Sine: Array of single;
- xc, yc: Integer;
- begin
- If Slices < 3 then
- Exit;
- SetLength(Sine, Slices + 1);
- SetLength(Cosine, Slices + 1);
- PrepareSinCosCache(Sine, Cosine, 0, 360);
- VertexOffset := Mesh.Vertices.Count;
- NormalOffset := Mesh.Normals.Count;
- TextureOffset := Mesh.TexCoords.Count;
- for xc := 0 to Slices - 1 do
- Begin
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale,
- TopRadius * 0.5 * Cosine[xc], TopRadius * 0.5 * Sine[xc], Height / 2));
- Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale,
- BottomRadius * 0.5 * Cosine[xc], BottomRadius * 0.5 * Sine[xc],
- -Height / 2));
- // Normals
- Mesh.Normals.Add(AffineVectorMake(Cosine[xc], Sine[xc], 0));
- // Texture Coordinates
- Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
- TopRadius * 0.5 * Cosine[xc], TopRadius * 0.5 * Sine[xc], Height / 2));
- Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
- BottomRadius * 0.5 * Cosine[xc], BottomRadius * 0.5 * Sine[xc],
- -Height / 2));
- end;
- Mesh.Normals.Add(AffineVectorMake(0, 0, 1));
- Mesh.Normals.Add(AffineVectorMake(0, 0, -1));
- FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
- FGR.Mode := fgmmTriangles;
- for xc := 0 to Slices - 1 do
- begin
- yc := xc + 1;
- If yc = Slices then
- yc := 0;
- FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + xc * 2 + 1,
- VertexOffset + yc * 2 + 1);
- FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + yc * 2 + 1,
- VertexOffset + yc * 2);
- FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + xc,
- NormalOffset + yc);
- FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + yc,
- NormalOffset + yc);
- FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + xc * 2 + 1,
- TextureOffset + yc * 2 + 1);
- FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + yc * 2 + 1,
- TextureOffset + yc * 2);
- end;
- for xc := 1 to Slices - 2 do
- begin
- yc := xc + 1;
- FGR.VertexIndices.Add(VertexOffset, VertexOffset + xc * 2,
- VertexOffset + yc * 2);
- FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + yc * 2 + 1,
- VertexOffset + xc * 2 + 1);
- FGR.NormalIndices.Add(NormalOffset + Slices, NormalOffset + Slices,
- NormalOffset + Slices);
- FGR.NormalIndices.Add(NormalOffset + Slices + 1, NormalOffset + Slices + 1,
- NormalOffset + Slices + 1);
- FGR.TexCoordIndices.Add(TextureOffset, TextureOffset + xc * 2,
- TextureOffset + yc * 2);
- FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + yc * 2 + 1,
- TextureOffset + xc * 2 + 1);
- end;
- end;
- end.
|