forked from gbegreg/GBE3D
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGBESphereExtend.pas
169 lines (145 loc) · 4.36 KB
/
GBESphereExtend.pas
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
{
Ecrit par Grégory Bersegeay
Le TGBESphereExtend permet à l'origine de créer des MEsh à partir d'une TSphere
}
unit GBESphereExtend;
interface
uses
System.SysUtils, System.Classes, FMX.Types, FMX.Controls3D, FMX.Objects3D, FMX.Types3D, System.RTLConsts,
System.Math.Vectors, FMX.MaterialSources;
type
TCustomMeshHelper = class(TCustomMesh);
TForme = (capsule, dome, culbuto, sphere, pomme, pot, losange);
TGBESphereExtend = class(TMesh)
private
{ Déclarations privées }
fSubdivisionsAxes, fSubdivisionsHeight : integer;
fForme: TForme;
fLongueur: single;
fShowlines: boolean;
fMaterialLignes: TColorMaterialSource;
procedure CreateGBESphere(Const aData:TMeshData; Const aForme: TForme = TForme.sphere; Const aLength: Single = 1.0);
protected
{ Déclarations protégées }
procedure setForme(value : TForme);
procedure setLongueur(value : single);
procedure setSubdivisionsAxes(value: integer);
procedure setSubdivisionsHeight(value : integer);
public
{ Déclarations publiques }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Render; override;
published
{ Déclarations publiées }
property SubdivisionsAxes: integer read fSubdivisionsAxes write setSubdivisionsAxes;
property SubdivisionsHeight: integer read fSubdivisionsHeight write setSubdivisionsHeight;
property ShowLines: boolean read fShowlines write fShowLines;
property Forme: TForme read fForme write setForme;
property Longueur: single read fLongueur write setLongueur;
property MaterialLines : TColorMaterialSource read fMaterialLignes write fMaterialLignes;
end;
procedure Register;
implementation
constructor TGBESphereExtend.Create(AOwner: TComponent);
begin
inherited;
SubdivisionsHeight := 12;
SubdivisionsAxes := 16;
CreateGBESphere(self.Data);
end;
procedure TGBESphereExtend.CreateGBESphere(Const aData:TMeshData; Const aForme: TForme = TForme.sphere; Const aLength: Single = 1.0);
var
D:TMeshData;
Sp:TSphere;
SbA, SbH, Vw, H, A : integer;
P:PPoint3d;
K,Yh, L: Single;
begin
D:=TMeshData.Create;
SP:=TSphere.Create(nil);
sp.SubdivisionsAxes:=SubdivisionsAxes;
sp.SubdivisionsHeight:=SubdivisionsHeight;
SbA:=Sp.SubdivisionsAxes;
SbH:=SP.SubdivisionsHeight div 2;
D.Assign(TCustomMeshHelper(Sp).Data);
TCustomMeshHelper(Sp).data.Clear;
Sp.Free;
if (aForme <> TForme.sphere) and (aForme <> TForme.losange) then
begin
L:=aLength;
K := L / SbH;
Yh:=L;
Vw := SbA + 1;
for H := 0 to SbH - 1 do
begin
for A :=0 to SbA do
begin
P:=D.VertexBuffer.VerticesPtr[A + (H * Vw)];
if (aForme = TForme.dome) or (aForme = TForme.pot) then P^.Y := -L
else P^.Y:=P^.Y - Yh;
end;
if (aForme = TForme.culbuto) or (aForme = TForme.pomme) then Yh := Yh - K;
end;
end;
if (aForme = TForme.dome) or (aForme = TForme.pot) then D.CalcTangentBinormals
else D.CalcSmoothNormals;
aData.Clear;
aData.Assign(D);
D.Free;
end;
procedure Register;
begin
RegisterComponents('GBE3D', [TGBESphereExtend]);
end;
destructor TGBESphereExtend.Destroy;
begin
inherited;
end;
procedure TGBESphereExtend.setLongueur(value: single);
begin
if value <> fLongueur then
begin
fLongueur := value;
CreateGBESphere(self.Data, fForme, fLongueur);
end;
end;
procedure TGBESphereExtend.setForme(value: TForme);
begin
if value <> fForme then
begin
fForme := value;
case FForme of
TForme.pomme : fLongueur := -0.4;
TForme.pot : fLongueur := -0.15;
TForme.losange : begin
fSubdivisionsAxes := 4;
fSubdivisionsHeight := 2;
end;
end;
CreateGBESphere(self.Data, fForme, fLongueur);
end;
end;
procedure TGBESphereExtend.setSubdivisionsAxes(value: integer);
begin
if value <> fSubdivisionsAxes then
begin
fSubdivisionsAxes := value;
CreateGBESphere(self.Data, fForme, fLongueur);
end;
end;
procedure TGBESphereExtend.setSubdivisionsHeight(value: integer);
begin
if value <> fSubdivisionsHeight then
begin
fSubdivisionsHeight := value;
CreateGBESphere(self.Data, fForme, fLongueur);
end;
end;
procedure TGBESphereExtend.Render;
begin
inherited;
if ShowLines then
Context.DrawLines(self.Data.VertexBuffer, self.Data.IndexBuffer, TMaterialSource.ValidMaterial(fMaterialLignes),1);
end;
end.