diff --git a/units/Graf3DScene/Graf3DPrimitives.pas b/units/Graf3DScene/Graf3DPrimitives.pas index 5a58dc6..a633ef4 100644 --- a/units/Graf3DScene/Graf3DPrimitives.pas +++ b/units/Graf3DScene/Graf3DPrimitives.pas @@ -4,66 +4,142 @@ interface uses FixMath, Graf3D, Graf3DScene; - procedure SetArc3D (var shape: Shape3D; x, y, z, w, h, d: Fixed); - procedure SetBox3D (var shape: Shape3D; x, y, z, w, h, d, ax, az: Fixed); +{2d} + procedure SetTri3D (var shape: Shape3D; x, y, z, w, h: Fixed); + procedure SetRect3D (var shape: Shape3D; x, y, z, w, d: Fixed); + procedure SetCircle3D (var shape: Shape3D; x, y, z, r: Fixed); +{3d} procedure SetWedge3D (var shape: Shape3D; x, y, z, w, h, d, a: Fixed); + procedure SetBox3D (var shape: Shape3D; x, y, z, w, h, d, ax, az: Fixed); + procedure SetCyl3D (var shape: Shape3D; x, y, z, w, h, d, r: Fixed); procedure SetPyramid3D (var shape: Shape3D; x, y, z, w, h, d, ax, az: Fixed); implementation +{privates} + procedure AddLink3D (var shape: Shape3D; a, b: Integer); + begin + shape.length := shape.length + 1; + SetLk3D(shape.edges[shape.length], @shape.vertices[a], @shape.vertices[b]); + end; + + procedure AddTri3D (var shape: Shape3D; x, y, z, w, h: Fixed); + var + voff, eoff, foff: Integer; { vertices offset} + begin + voff := shape.verticesLength; + foff := shape.facesLength; + eoff := shape.length; + SetPt3D(shape.vertices[voff + 1], Long2Fix(x), Long2Fix(y + h div 2), Long2Fix(z)); + SetPt3D(shape.vertices[voff + 2], Long2Fix(x + w div 2), Long2Fix(y - h div 2), Long2Fix(z)); + SetPt3D(shape.vertices[voff + 3], Long2Fix(x - w div 2), Long2Fix(y - h div 2), Long2Fix(z)); + SetLk3D(shape.edges[eoff + 1], @shape.vertices[voff + 1], @shape.vertices[voff + 2]); + SetLk3D(shape.edges[eoff + 2], @shape.vertices[voff + 2], @shape.vertices[voff + 3]); + SetLk3D(shape.edges[eoff + 3], @shape.vertices[voff + 3], @shape.vertices[voff + 1]); + SetFc3D(shape.faces[foff + 1], @shape.vertices[voff + 1], @shape.vertices[voff + 2], @shape.vertices[voff + 3]); + shape.verticesLength := voff + 3; + shape.facesLength := foff + 1; + shape.length := eoff + 3; + end; + + procedure AddRect3D (var shape: Shape3D; x, y, z, w, h: Fixed); + var + voff, eoff, foff: Integer; { vertices offset} + begin + voff := shape.verticesLength; + foff := shape.facesLength; + eoff := shape.length; + SetPt3D(shape.vertices[voff + 1], Long2Fix(x + w div 2), Long2Fix(y + h div 2), Long2Fix(z)); + SetPt3D(shape.vertices[voff + 2], Long2Fix(x + w div 2), Long2Fix(y - h div 2), Long2Fix(z)); + SetPt3D(shape.vertices[voff + 3], Long2Fix(x - w div 2), Long2Fix(y - h div 2), Long2Fix(z)); + SetPt3D(shape.vertices[voff + 4], Long2Fix(x - w div 2), Long2Fix(y + h div 2), Long2Fix(z)); + SetLk3D(shape.edges[eoff + 1], @shape.vertices[voff + 1], @shape.vertices[voff + 2]); + SetLk3D(shape.edges[eoff + 2], @shape.vertices[voff + 2], @shape.vertices[voff + 3]); + SetLk3D(shape.edges[eoff + 3], @shape.vertices[voff + 3], @shape.vertices[voff + 4]); + SetLk3D(shape.edges[eoff + 4], @shape.vertices[voff + 4], @shape.vertices[voff + 1]); + SetFc3D(shape.faces[foff + 1], @shape.vertices[voff + 1], @shape.vertices[voff + 2], @shape.vertices[voff + 3]); + SetFc3D(shape.faces[foff + 2], @shape.vertices[voff + 3], @shape.vertices[voff + 4], @shape.vertices[voff + 1]); + shape.verticesLength := voff + 4; + shape.facesLength := foff + 2; + shape.length := eoff + 4; + end; + + procedure AddCircle3D (var shape: Shape3D; x, y, z, r: Fixed); + var + voff, eoff, foff: Integer; { vertices offset} + i, segs: Integer; + offx, offy: Fixed; + pi, radians: Fixed; + arc, angle: Fixed; + begin + voff := shape.verticesLength; + foff := shape.facesLength; + eoff := shape.length; + segs := 16; + arc := FracDiv(360, Long2Fix(segs)); + for i := 1 to segs do + begin + angle := FixMul(arc, Long2Fix(i)); + radians := FracMul(angle, FixDiv(205887, 180)); + offx := FracMul(Long2Fix(r), FracCos(radians)); + offy := FracMul(Long2Fix(r), FracSin(radians)); + SetPt3D(shape.vertices[voff + i], round(Long2Fix(x) + offx), round(Long2Fix(y) + offy), round(Long2Fix(z))); + if i <> segs then + SetLk3D(shape.edges[eoff + i], @shape.vertices[voff + i], @shape.vertices[voff + i + 1]); + end; + SetLk3D(shape.edges[eoff + segs], @shape.vertices[voff + segs], @shape.vertices[voff + 1]); + shape.verticesLength := voff + segs; + shape.facesLength := foff + 0; + shape.length := eoff + segs; + end; + +{publics} + procedure SetTri3D (var shape: Shape3D; x, y, z, w, h: Fixed); + begin + AddTri3D(shape, x, y, z, w, h); + end; + + procedure SetRect3D (var shape: Shape3D; x, y, z, w, d: Fixed); + begin + AddRect3D(shape, x, y, z, w, d); + end; + + procedure SetCircle3D (var shape: Shape3D; x, y, z, r: Fixed); + begin + AddCircle3D(shape, x, y, z, r); + end; + procedure SetBox3D (var shape: Shape3D; x, y, z, w, h, d, ax, az: Fixed); + var + i: Integer; begin SetPt3D(shape.origin, Long2Fix(x), Long2Fix(y), Long2Fix(z)); - SetPt3D(shape.vertices[1], Long2Fix(x + w div 2 - ax), Long2Fix(y + h div 2), Long2Fix(z + d div 2 - az)); - SetPt3D(shape.vertices[2], Long2Fix(x + w div 2 - ax), Long2Fix(y + h div 2), Long2Fix(z - d div 2 + ax)); - SetPt3D(shape.vertices[3], Long2Fix(x - w div 2 + ax), Long2Fix(y + h div 2), Long2Fix(z - d div 2 + az)); - SetPt3D(shape.vertices[4], Long2Fix(x - w div 2 + ax), Long2Fix(y + h div 2), Long2Fix(z + d div 2 - az)); - SetPt3D(shape.vertices[5], Long2Fix(x + w div 2), Long2Fix(y - h div 2), Long2Fix(z + d div 2)); - SetPt3D(shape.vertices[6], Long2Fix(x + w div 2), Long2Fix(y - h div 2), Long2Fix(z - d div 2)); - SetPt3D(shape.vertices[7], Long2Fix(x - w div 2), Long2Fix(y - h div 2), Long2Fix(z - d div 2)); - SetPt3D(shape.vertices[8], Long2Fix(x - w div 2), Long2Fix(y - h div 2), Long2Fix(z + d div 2)); - SetLk3D(shape.edges[1], @shape.vertices[1], @shape.vertices[2]); - SetLk3D(shape.edges[2], @shape.vertices[2], @shape.vertices[3]); - SetLk3D(shape.edges[3], @shape.vertices[3], @shape.vertices[4]); - SetLk3D(shape.edges[4], @shape.vertices[4], @shape.vertices[1]); - SetLk3D(shape.edges[5], @shape.vertices[5], @shape.vertices[6]); - SetLk3D(shape.edges[6], @shape.vertices[6], @shape.vertices[7]); - SetLk3D(shape.edges[7], @shape.vertices[7], @shape.vertices[8]); - SetLk3D(shape.edges[8], @shape.vertices[8], @shape.vertices[5]); - SetLk3D(shape.edges[9], @shape.vertices[1], @shape.vertices[5]); - SetLk3D(shape.edges[10], @shape.vertices[2], @shape.vertices[6]); - SetLk3D(shape.edges[11], @shape.vertices[3], @shape.vertices[7]); - SetLk3D(shape.edges[12], @shape.vertices[4], @shape.vertices[8]); - SetFc3D(shape.faces[1], @shape.vertices[1], @shape.vertices[2], @shape.vertices[5]); - SetFc3D(shape.faces[2], @shape.vertices[2], @shape.vertices[5], @shape.vertices[6]); - shape.verticesLength := 8; - shape.facesLength := 2; - shape.length := 12; + AddRect3D(shape, x, y, z + d div 2, w, h); + AddRect3D(shape, x, y, z - d div 2, w, h); + for i := 1 to 4 do + AddLink3D(shape, i, i + 4); end; procedure SetWedge3D (var shape: Shape3D; x, y, z, w, h, d, a: Fixed); + var + i: Integer; begin SetPt3D(shape.origin, Long2Fix(x), Long2Fix(y), Long2Fix(z)); - SetPt3D(shape.vertices[1], Long2Fix(x + a), Long2Fix(y + h div 2), Long2Fix(z - d div 2)); - SetPt3D(shape.vertices[2], Long2Fix(x + a), Long2Fix(y + h div 2), Long2Fix(z + d div 2)); - SetPt3D(shape.vertices[3], Long2Fix(x + w div 2), Long2Fix(y - h div 2), Long2Fix(z + d div 2)); - SetPt3D(shape.vertices[4], Long2Fix(x + w div 2), Long2Fix(y - h div 2), Long2Fix(z - d div 2)); - SetPt3D(shape.vertices[5], Long2Fix(x - w div 2), Long2Fix(y - h div 2), Long2Fix(z - d div 2)); - SetPt3D(shape.vertices[6], Long2Fix(x - w div 2), Long2Fix(y - h div 2), Long2Fix(z + d div 2)); - SetLk3D(shape.edges[1], @shape.vertices[1], @shape.vertices[2]); - SetLk3D(shape.edges[2], @shape.vertices[1], @shape.vertices[4]); - SetLk3D(shape.edges[3], @shape.vertices[1], @shape.vertices[5]); - SetLk3D(shape.edges[4], @shape.vertices[2], @shape.vertices[3]); - SetLk3D(shape.edges[5], @shape.vertices[2], @shape.vertices[6]); - SetLk3D(shape.edges[6], @shape.vertices[3], @shape.vertices[4]); - SetLk3D(shape.edges[7], @shape.vertices[4], @shape.vertices[5]); - SetLk3D(shape.edges[8], @shape.vertices[5], @shape.vertices[6]); - SetLk3D(shape.edges[9], @shape.vertices[6], @shape.vertices[3]); - SetFc3D(shape.faces[1], @shape.vertices[1], @shape.vertices[2], @shape.vertices[3]); - SetFc3D(shape.faces[2], @shape.vertices[1], @shape.vertices[3], @shape.vertices[4]); - shape.verticesLength := 6; - shape.facesLength := 2; - shape.length := 9; + AddTri3D(shape, x, y, z + d div 2, w, h); + AddTri3D(shape, x, y, z - d div 2, w, h); + for i := 1 to 3 do + AddLink3D(shape, i, i + 3); + end; + + procedure SetCyl3D (var shape: Shape3D; x, y, z, w, h, d, r: Fixed); + var + i: Integer; + begin + SetPt3D(shape.origin, Long2Fix(x), Long2Fix(y), Long2Fix(z)); + AddCircle3D(shape, x, y, z + d div 2, r); + AddCircle3D(shape, x, y, z - d div 2, r); + for i := 1 to 16 do + AddLink3D(shape, i, i + 16); end; procedure SetPyramid3D (var shape: Shape3D; x, y, z, w, h, d, ax, az: Fixed); diff --git a/units/Graf3DScene/Graf3DScene.pas b/units/Graf3DScene/Graf3DScene.pas index 11e4d20..8b00392 100644 --- a/units/Graf3DScene/Graf3DScene.pas +++ b/units/Graf3DScene/Graf3DScene.pas @@ -21,7 +21,7 @@ interface Shape3D = record origin: Point3D; length, verticesLength, facesLength: Integer; - vertices: array[1..9] of Point3D; + vertices: array[1..10] of Point3D; edges: array[1..13] of Link3D; faces: array[1..6] of Face3D; end; diff --git a/units/Graf3DScene/main.pas b/units/Graf3DScene/main.pas index b6a9f36..5e43f44 100644 --- a/units/Graf3DScene/main.pas +++ b/units/Graf3DScene/main.pas @@ -4,8 +4,8 @@ program ExampleScene; FixMath, Graf3D, Graf3DScene, Graf3DPrimitives, Graf3DStructures; var - arc1, box1, wed1, pyr1: Shape3D; - arc2, box2, wed2, pyr2: Shape3D; + wed1, box1, cyl1: Shape3D; + tri1, rec1, cir1: Shape3D; begin @@ -13,24 +13,21 @@ begin SetScene3D(scene); - SetArc3D(arc1, -100, 0, 100, 100, 100, 100); - SetBox3D(box1, -100, 0, 100, 100, 100, 100, 0, 0); - SetWedge3D(wed1, 0, 0, 100, 100, 100, 100, 0); - SetPyramid3D(pyr1, 100, 0, 100, 100, 100, 100, 0, 0); + SetWedge3D(wed1, -100, 0, 100, 100, 100, 100, 0); + SetBox3D(box1, 0, 0, 100, 100, 100, 100, 0, 0); + SetCyl3D(cyl1, 100, 0, 100, 100, 100, 100, 50); - SetBox3D(box2, -100, 0, -100, 100, 100, 100, 25, 25); - SetWedge3D(wed2, 0, 0, -100, 100, 100, 100, 50); - SetPyramid3D(pyr2, 100, 0, -100, 100, 100, 100, 50, 50); + SetTri3D(tri1, -100, -0, 300, 100, 100); + SetRect3D(rec1, 0, 0, 300, 100, 100); + SetCircle3D(cir1, 100, 0, 300, 50); - AddShape3D(scene, @arc1); - AddShape3D(scene, @arc2); - AddShape3D(scene, @box1); AddShape3D(scene, @wed1); - AddShape3D(scene, @pyr1); + AddShape3D(scene, @box1); + AddShape3D(scene, @cyl1); - AddShape3D(scene, @box2); - AddShape3D(scene, @wed2); - AddShape3D(scene, @pyr2); + AddShape3D(scene, @tri1); + AddShape3D(scene, @rec1); + AddShape3D(scene, @cir1); InitWindow;