GLVerletClothify.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLVerletClothify;
  5. (* Methods for turning a TGLBaseMesh into a Verlet cloth / jelly *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. Winapi.OpenGL,
  10. System.Classes,
  11. System.SysUtils,
  12. OpenGLTokens,
  13. GLVectorFileObjects,
  14. GLVerletTypes,
  15. GLVectorTypes,
  16. GLVectorLists,
  17. GLVectorGeometry,
  18. GLTexture,
  19. GLRenderContextInfo,
  20. GLState,
  21. GLPersistentClasses,
  22. GLContext;
  23. type
  24. (* Class that represents a face. This structure
  25. is not used for rendering, but for extracting info from meshes *)
  26. TFace = class
  27. public
  28. Vertices : array[0..2] of integer;
  29. Normal : TAffineVector;
  30. MeshObject : TMeshObject;
  31. Active : boolean;
  32. procedure UpdateNormal;
  33. constructor Create(aMeshObject : TMeshObject);
  34. end;
  35. // List of faces
  36. TFaceList = class(TList)
  37. private
  38. function GetItems(i: integer): TFace;
  39. procedure SetItems(i: integer; const Value: TFace);
  40. public
  41. property Items[i : integer] : TFace read GetItems write SetItems; default;
  42. end;
  43. // Class that extracts faces from a GLBaseMesh
  44. TFaceExtractor = class
  45. private
  46. FFaceList : TFaceList;
  47. FGLBaseMesh : TGLBaseMesh;
  48. FNodeList : TVerletNodeList;
  49. FWeldDistance: single;
  50. FEdgeDoublesSkipped : integer;
  51. procedure SetWeldDistance(const Value: single);
  52. protected
  53. procedure ProcessMeshObject(const MeshObject : TMeshObject); virtual;
  54. public
  55. procedure ExtractFacesFromVertexIndexList(
  56. const FaceGroup : TFGVertexIndexList; const MeshObject : TMeshObject);
  57. property FaceList : TFaceList read FFaceList;
  58. procedure Clear; virtual;
  59. procedure ProcessMesh; virtual;
  60. property WeldDistance : single read FWeldDistance write SetWeldDistance;
  61. property EdgeDoublesSkipped : integer read FEdgeDoublesSkipped;
  62. property GLBaseMesh : TGLBaseMesh read FGLBaseMesh;
  63. property NodeList : TVerletNodeList read FNodeList;
  64. function AddFace(const Vi0, Vi1, Vi2 : integer; const MeshObject : TMeshObject) : TFace; virtual;
  65. constructor Create(const aGLBaseMesh : TGLBaseMesh); virtual;
  66. destructor Destroy; override;
  67. end;
  68. TEdgeDetector = class;
  69. TEdge = class
  70. private
  71. FSolid: boolean;
  72. FLength: single;
  73. FMeshObject: TMeshObject;
  74. FOwner: TEdgeDetector;
  75. public
  76. Vertices : array[0..1] of integer;
  77. Faces : array[0..1] of TFace;
  78. procedure Contract;
  79. property Owner : TEdgeDetector read FOwner;
  80. property MeshObject : TMeshObject read FMeshObject write FMeshObject;
  81. property Length : single read FLength write FLength;
  82. property Solid : boolean read FSolid write FSolid;
  83. procedure UpdateEdgeLength;
  84. constructor Create(const AOwner: TEdgeDetector; AVi0, AVi1 : integer;
  85. AFace0, AFace1 : TFace; AMeshObject : TMeshObject; ASolid : boolean);
  86. end;
  87. TEdgeList = class(TList)
  88. private
  89. function GetItems(i: integer): TEdge;
  90. procedure SetItems(i: integer; const Value: TEdge);
  91. public
  92. property Items[i : integer] : TEdge read GetItems write SetItems; default;
  93. procedure SortByLength;
  94. function InsertSorted(AEdge : TEdge) : integer;
  95. end;
  96. TEdgeDetector = class(TFaceExtractor)
  97. private
  98. FEdgeList : TEdgeList;
  99. FCurrentNodeOffset : integer;
  100. FNodesAdded : boolean;
  101. procedure BuildOpposingEdges;
  102. protected
  103. FCalcEdgeLength : boolean;
  104. public
  105. property EdgeList : TEdgeList read FEdgeList;
  106. procedure Clear; override;
  107. procedure ProcessMesh; override;
  108. function AddEdge(const Vi0, Vi1 : integer; const Face : TFace; const AMeshObject : TMeshObject) : TEdge;
  109. function AddFace(const Vi0, Vi1, Vi2 : integer; const MeshObject : TMeshObject) : TFace; override;
  110. function AddNode(const VerletWorld : TGLVerletWorld; const MeshObject : TMeshObject; const VertexIndex : integer) : TVerletNode; virtual;
  111. procedure AddNodes(const VerletWorld : TGLVerletWorld);
  112. procedure AddEdgesAsSticks(const VerletWorld : TGLVerletWorld; const Slack : single);
  113. procedure AddEdgesAsSprings(const VerletWorld : TGLVerletWorld; const Strength, Damping, Slack : single);
  114. procedure AddEdgesAsSolidEdges(const VerletWorld : TGLVerletWorld);
  115. procedure AddOuterEdgesAsSolidEdges(const VerletWorld : TGLVerletWorld);
  116. procedure RenderEdges(var rci : TGLRenderContextInfo);
  117. property CurrentNodeOffset : integer read FCurrentNodeOffset;
  118. property NodesAdded : boolean read FNodesAdded;
  119. procedure ReplaceVertexIndex(const ViRemove, ViReplaceWith : integer);
  120. constructor Create(const aGLBaseMesh : TGLBaseMesh); override;
  121. destructor Destroy; override;
  122. end;
  123. TMeshObjectVerletNode = class(TVerletNode)
  124. private
  125. MeshObject : TMeshObject;
  126. VertexIndices : TIntegerList;
  127. public
  128. procedure AfterProgress; override;
  129. constructor CreateOwned(const aOwner : TGLVerletWorld); override;
  130. destructor Destroy; override;
  131. end;
  132. //----------------------------------------------------
  133. implementation
  134. //----------------------------------------------------
  135. //------------------
  136. // TFaceExtractor
  137. //------------------
  138. procedure TFaceExtractor.Clear;
  139. var
  140. i : integer;
  141. begin
  142. for i := 0 to FaceList.Count-1 do
  143. FaceList[i].Free;
  144. FaceList.Clear;
  145. end;
  146. constructor TFaceExtractor.Create(const aGLBaseMesh : TGLBaseMesh);
  147. begin
  148. FFaceList := TFaceList.Create;
  149. FGLBaseMesh := aGLBaseMesh;
  150. FNodeList := TVerletNodeList.Create;
  151. FWeldDistance := 0.01;
  152. end;
  153. destructor TFaceExtractor.Destroy;
  154. begin
  155. Clear;
  156. FreeAndNil(FNodeList);
  157. FreeAndNil(FFaceList);
  158. inherited;
  159. end;
  160. procedure TFaceExtractor.ExtractFacesFromVertexIndexList(
  161. const FaceGroup : TFGVertexIndexList; const MeshObject : TMeshObject);
  162. var
  163. List : PIntegerArray;
  164. iFace, iVertex : integer;
  165. begin
  166. case FaceGroup.Mode of
  167. fgmmTriangles, fgmmFlatTriangles :
  168. begin
  169. for iFace := 0 to FaceGroup.TriangleCount - 1 do
  170. begin
  171. List := @FaceGroup.VertexIndices.List[iFace * 3 + 0];
  172. AddFace(List^[0], List^[1], List^[2], MeshObject);
  173. end;
  174. end;
  175. fgmmTriangleStrip :
  176. begin
  177. for iFace:=0 to FaceGroup.VertexIndices.Count-3 do
  178. begin
  179. List := @FaceGroup.VertexIndices.List[iFace];
  180. if (iFace and 1)=0 then
  181. AddFace(List^[0], List^[1], List^[2], MeshObject)
  182. else
  183. AddFace(List^[2], List^[1], List^[0], MeshObject);
  184. end;
  185. end;
  186. fgmmTriangleFan :
  187. begin
  188. List := @FaceGroup.VertexIndices.List;
  189. for iVertex:=2 to FaceGroup.VertexIndices.Count-1 do
  190. AddFace(List^[0], List^[iVertex-1], List^[iVertex], MeshObject)
  191. end;
  192. else
  193. Assert(false,'Not supported');
  194. end;
  195. end;
  196. procedure TFaceExtractor.ProcessMesh;
  197. var
  198. iMeshObject : integer;
  199. MeshObject : TMeshObject;
  200. begin
  201. for iMeshObject := 0 to FGLBaseMesh.MeshObjects.Count - 1 do
  202. begin
  203. MeshObject := FGLBaseMesh.MeshObjects[iMeshObject];
  204. ProcessMeshObject(MeshObject);
  205. end;
  206. end;
  207. procedure TFaceExtractor.ProcessMeshObject(const MeshObject : TMeshObject);
  208. var
  209. iFaceGroup : integer;
  210. begin
  211. if MeshObject.Mode = momFaceGroups then
  212. begin
  213. for iFaceGroup := 0 to MeshObject.FaceGroups.Count - 1 do
  214. begin
  215. if MeshObject.FaceGroups[iFaceGroup] is TFGVertexIndexList then
  216. begin
  217. ExtractFacesFromVertexIndexList(MeshObject.FaceGroups[iFaceGroup] as TFGVertexIndexList, MeshObject);
  218. end else
  219. Assert(false);
  220. end;
  221. end else
  222. Assert(false);
  223. end;
  224. function TFaceExtractor.AddFace(const Vi0, Vi1, Vi2: integer; const MeshObject : TMeshObject) : TFace;
  225. var
  226. Face : TFace;
  227. begin
  228. Face := TFace.Create(MeshObject);
  229. FaceList.Add(Face);
  230. Face.Vertices[0] := Vi0;
  231. Face.Vertices[1] := Vi1;
  232. Face.Vertices[2] := Vi2;
  233. result := Face;
  234. end;
  235. procedure TFaceExtractor.SetWeldDistance(const Value: single);
  236. begin
  237. FWeldDistance := Value;
  238. end;
  239. //------------------
  240. // TFaceList
  241. //------------------
  242. function TFaceList.GetItems(i: integer): TFace;
  243. begin
  244. result := TFace(Get(i));
  245. end;
  246. procedure TFaceList.SetItems(i: integer; const Value: TFace);
  247. begin
  248. Put(i, Value);
  249. end;
  250. //------------------
  251. // TEdgeList
  252. //------------------
  253. function TEdgeList.GetItems(i: integer): TEdge;
  254. begin
  255. result := TEdge(Get(i));
  256. end;
  257. function TEdgeList.InsertSorted(AEdge: TEdge): integer;
  258. var
  259. i : integer;
  260. begin
  261. for i := 0 to Count-1 do
  262. begin
  263. if AEdge.Length<Items[i].Length then
  264. begin
  265. Insert(i, AEdge);
  266. result := i;
  267. exit;
  268. end;
  269. end;
  270. result := Add(AEdge);
  271. end;
  272. procedure TEdgeList.SetItems(i: integer; const Value: TEdge);
  273. begin
  274. Put(i, Value);
  275. end;
  276. function EdgeLength(Item1, Item2 : pointer) : integer;
  277. begin
  278. if TEdge(Item1).Length < TEdge(Item2).Length then
  279. result := -1
  280. else if TEdge(Item1).Length = TEdge(Item2).Length then
  281. result := 0
  282. else
  283. result := 1;
  284. end;
  285. procedure TEdgeList.SortByLength;
  286. begin
  287. Sort(@EdgeLength);
  288. end;
  289. //--------------------------
  290. { TMeshObjectVerletNode }
  291. //--------------------------
  292. constructor TMeshObjectVerletNode.CreateOwned(const aOwner: TGLVerletWorld);
  293. begin
  294. inherited;
  295. VertexIndices := TIntegerList.Create;
  296. end;
  297. destructor TMeshObjectVerletNode.Destroy;
  298. begin
  299. VertexIndices.Free;
  300. inherited;
  301. end;
  302. procedure TMeshObjectVerletNode.AfterProgress;
  303. var
  304. i : integer;
  305. begin
  306. // Update the actual vertex
  307. for i := 0 to VertexIndices.Count-1 do
  308. MeshObject.Vertices[VertexIndices[i]] := MeshObject.Owner.Owner.AbsoluteToLocal(Location);
  309. end;
  310. //--------------------------
  311. // TEdgeDetector
  312. //--------------------------
  313. procedure TEdgeDetector.Clear;
  314. var
  315. i : integer;
  316. begin
  317. inherited;
  318. for i := 0 to EdgeList.Count-1 do
  319. EdgeList[i].Free;
  320. EdgeList.Clear;
  321. FCurrentNodeOffset := 0;
  322. FNodesAdded := false;
  323. end;
  324. constructor TEdgeDetector.Create(const aGLBaseMesh: TGLBaseMesh);
  325. begin
  326. FEdgeList := TEdgeList.Create;
  327. FCurrentNodeOffset := 0;
  328. FNodesAdded := false;
  329. FCalcEdgeLength := false;
  330. inherited;
  331. end;
  332. destructor TEdgeDetector.Destroy;
  333. begin
  334. inherited;
  335. FreeAndNil(FEdgeList);
  336. end;
  337. function TEdgeDetector.AddEdge(const Vi0, Vi1: integer;
  338. const Face: TFace; const AMeshObject : TMeshObject): TEdge;
  339. var
  340. i : integer;
  341. Edge : TEdge;
  342. begin
  343. // Find an indentical edge, if there is one
  344. for i := 0 to EdgeList.Count - 1 do
  345. begin
  346. Edge := EdgeList[i];
  347. if (Edge.Vertices[0]=Vi0) and (Edge.Vertices[1]=Vi1) or
  348. (Edge.Vertices[1]=Vi0) and (Edge.Vertices[0]=Vi1) then
  349. begin
  350. Edge.Faces[1] := Face;
  351. result := Edge;
  352. exit;
  353. end;
  354. end;
  355. // No edge was found, create a new one
  356. Edge := TEdge.Create(self, Vi0, Vi1, Face, nil, AMeshObject, true);
  357. EdgeList.Add(Edge);
  358. result := Edge;
  359. end;
  360. function TEdgeDetector.AddFace(const Vi0, Vi1, Vi2: integer;
  361. const MeshObject: TMeshObject): TFace;
  362. var
  363. Face : TFace;
  364. begin
  365. Face := TFace.Create(MeshObject);
  366. FaceList.Add(Face);
  367. Face.Vertices[0] := Vi0;
  368. Face.Vertices[1] := Vi1;
  369. Face.Vertices[2] := Vi2;
  370. AddEdge(Vi0, Vi1, Face, MeshObject);
  371. AddEdge(Vi1, Vi2, Face, MeshObject);
  372. AddEdge(Vi2, Vi0, Face, MeshObject);//}
  373. result := Face;
  374. end;
  375. procedure TEdgeDetector.AddNodes(const VerletWorld : TGLVerletWorld);
  376. var
  377. i : integer;
  378. MO : TMeshObject;
  379. begin
  380. FNodesAdded := true;
  381. FCurrentNodeOffset := FNodeList.Count;
  382. MO := FGLBaseMesh.MeshObjects[0];
  383. for i := 0 to MO.Vertices.Count-1 do
  384. AddNode(VerletWorld, MO, i);
  385. // Assert(FNodeList.Count = MO.Vertices.Count, Format('%d <> %d',[FNodeList.Count, MO.Vertices.Count]));
  386. end;
  387. procedure TEdgeDetector.AddEdgesAsSprings(const VerletWorld : TGLVerletWorld;
  388. const Strength, Damping, Slack: single);
  389. var
  390. i : integer;
  391. Edge : TEdge;
  392. begin
  393. if not FNodesAdded then
  394. AddNodes(VerletWorld);
  395. for i := 0 to EdgeList.Count-1 do
  396. begin
  397. // if not EdgeList[i].SameSame(FNodeList) then
  398. Edge := EdgeList[i];
  399. if FNodeList[FCurrentNodeOffset+Edge.Vertices[0]] <> FNodeList[FCurrentNodeOffset+Edge.Vertices[1]] then
  400. begin
  401. VerletWorld.CreateSpring(
  402. FNodeList[FCurrentNodeOffset+Edge.Vertices[0]],
  403. FNodeList[FCurrentNodeOffset+Edge.Vertices[1]],
  404. Strength, Damping, Slack);
  405. end;
  406. end;
  407. end;
  408. procedure TEdgeDetector.AddEdgesAsSticks(const VerletWorld : TGLVerletWorld;
  409. const Slack : single);
  410. var
  411. i : integer;
  412. Edge : TEdge;
  413. begin
  414. if not FNodesAdded then
  415. AddNodes(VerletWorld);
  416. for i := 0 to EdgeList.Count-1 do
  417. begin
  418. // if not EdgeList[i].SameSame(FNodeList) then
  419. Edge := EdgeList[i];
  420. if FNodeList[FCurrentNodeOffset+Edge.Vertices[0]] <> FNodeList[FCurrentNodeOffset+Edge.Vertices[1]] then
  421. begin
  422. VerletWorld.CreateStick(
  423. FNodeList[FCurrentNodeOffset + Edge.Vertices[0]],
  424. FNodeList[FCurrentNodeOffset + Edge.Vertices[1]],
  425. Slack);
  426. end;
  427. end;
  428. end;
  429. procedure TEdgeDetector.AddEdgesAsSolidEdges(
  430. const VerletWorld: TGLVerletWorld);
  431. var
  432. i : integer;
  433. Edge : TEdge;
  434. begin
  435. if not FNodesAdded then
  436. AddNodes(VerletWorld);
  437. for i := 0 to EdgeList.Count-1 do
  438. begin
  439. // if not EdgeList[i].SameSame(FNodeList) then
  440. Edge := EdgeList[i];
  441. if FNodeList[FCurrentNodeOffset+Edge.Vertices[0]] <> FNodeList[FCurrentNodeOffset+Edge.Vertices[1]] then
  442. begin
  443. if Edge.Solid then
  444. VerletWorld.AddSolidEdge(
  445. FNodeList[FCurrentNodeOffset + Edge.Vertices[0]],
  446. FNodeList[FCurrentNodeOffset + Edge.Vertices[1]]);
  447. end;
  448. end;
  449. end;
  450. procedure TEdgeDetector.AddOuterEdgesAsSolidEdges(
  451. const VerletWorld: TGLVerletWorld);
  452. var
  453. i : integer;
  454. Edge : TEdge;
  455. begin
  456. if not FNodesAdded then
  457. AddNodes(VerletWorld);
  458. for i := 0 to EdgeList.Count-1 do
  459. begin
  460. // if not EdgeList[i].SameSame(FNodeList) then
  461. Edge := EdgeList[i];
  462. if FNodeList[FCurrentNodeOffset+Edge.Vertices[0]] <> FNodeList[FCurrentNodeOffset+Edge.Vertices[1]] then
  463. begin
  464. if Edge.Solid and (Edge.Faces[1]=nil) then
  465. VerletWorld.AddSolidEdge(
  466. FNodeList[FCurrentNodeOffset + Edge.Vertices[0]],
  467. FNodeList[FCurrentNodeOffset + Edge.Vertices[1]]);
  468. end;
  469. end;
  470. end;
  471. procedure TEdgeDetector.RenderEdges(var rci: TGLRenderContextInfo);
  472. var
  473. i : integer;
  474. Edge : TEdge;
  475. Vertex0, Vertex1 : TAffineVector;
  476. begin
  477. if EdgeList.Count>0 then
  478. begin
  479. rci.GLStates.Disable(stLighting);
  480. rci.GLStates.LineWidth := 3;
  481. gl.Color3f(1,1,1);
  482. gl.Begin_(GL_LINES);
  483. for i := 0 to EdgeList.Count - 1 do
  484. begin
  485. Edge := EdgeList[i];
  486. Vertex0 := Edge.MeshObject.Vertices[Edge.Vertices[0]];
  487. Vertex1 := Edge.MeshObject.Vertices[Edge.Vertices[1]];
  488. gl.Vertex3fv(PGLfloat(@Vertex0));
  489. gl.Vertex3fv(PGLfloat(@Vertex1));
  490. end;
  491. gl.End_;
  492. end;//}
  493. end;
  494. procedure TEdgeDetector.BuildOpposingEdges;
  495. var
  496. iEdge, EdgeCount, vi0, vi1, iEdgeTest : integer;
  497. Face0, Face1 : TFace;
  498. Edge, NewEdge, TestEdge : TEdge;
  499. begin
  500. // For each edge that's connected by two triangles, create a new edge that
  501. // connects the two "extra" vertices.... makes sense?
  502. EdgeCount := EdgeList.Count;
  503. for iEdge := 0 to EdgeCount-1 do
  504. begin
  505. Edge := EdgeList[iEdge];
  506. if Assigned(Edge.Faces[1]) then
  507. begin
  508. Face0 := Edge.Faces[0];
  509. Face1 := Edge.Faces[1];
  510. if (Face0.Vertices[0] <> Edge.Vertices[0]) and (Face0.Vertices[0] <> Edge.Vertices[1]) then
  511. vi0 := Face0.Vertices[0]
  512. else if (Face0.Vertices[1] <> Edge.Vertices[0]) and (Face0.Vertices[1] <> Edge.Vertices[1]) then
  513. vi0 := Face0.Vertices[1]
  514. else
  515. vi0 := Face0.Vertices[2];
  516. if (Face1.Vertices[0] <> Edge.Vertices[0]) and (Face1.Vertices[0] <> Edge.Vertices[1]) then
  517. vi1 := Face1.Vertices[0]
  518. else if (Face1.Vertices[1] <> Edge.Vertices[0]) and (Face1.Vertices[1] <> Edge.Vertices[1]) then
  519. vi1 := Face1.Vertices[1]
  520. else
  521. vi1 := Face1.Vertices[2];
  522. if (vi0=vi1) or
  523. (vi0=Edge.Vertices[0]) or
  524. (vi0=Edge.Vertices[1]) or
  525. (vi1=Edge.Vertices[0]) or
  526. (vi1=Edge.Vertices[1]) then
  527. continue;
  528. // Find an indentical edge, if there is one
  529. for iEdgeTest := 0 to EdgeList.Count - 1 do
  530. begin
  531. TestEdge := EdgeList[iEdgeTest];
  532. if (TestEdge.Vertices[0]=Vi0) and (TestEdge.Vertices[1]=Vi1) or
  533. (TestEdge.Vertices[1]=Vi0) and (TestEdge.Vertices[0]=Vi1) then
  534. begin
  535. // Edge allready exists!
  536. inc(FEdgeDoublesSkipped);
  537. continue;
  538. end;
  539. end;
  540. NewEdge := TEdge.Create(self, Vi0, Vi1, nil, nil, Edge.MeshObject, false);
  541. EdgeList.Add(NewEdge);//}
  542. end;
  543. end;
  544. end;
  545. function TEdgeDetector.AddNode(const VerletWorld : TGLVerletWorld; const MeshObject: TMeshObject;
  546. const VertexIndex: integer): TVerletNode;
  547. var
  548. Location : TAffineVector;
  549. aNode : TMeshObjectVerletNode;
  550. i : integer;
  551. begin
  552. // Is there an identical node?
  553. Location := MeshObject.Owner.Owner.LocalToAbsolute(MeshObject.Vertices[VertexIndex]);
  554. for i := FCurrentNodeOffset to FNodeList.Count-1 do
  555. begin
  556. aNode := TMeshObjectVerletNode(FNodeList[i]);
  557. if VectorDistance2(Location, aNode.Location)<=FWeldDistance then
  558. begin
  559. FNodeList.Add(aNode);
  560. aNode.VertexIndices.Add(VertexIndex);
  561. Result:=aNode;
  562. Exit;
  563. end;
  564. end;//}
  565. aNode := TMeshObjectVerletNode.CreateOwned(VerletWorld);
  566. aNode.MeshObject := MeshObject;
  567. aNode.VertexIndices.Add(VertexIndex);
  568. aNode.Location := Location;
  569. aNode.OldLocation := Location;
  570. FNodeList.Add(aNode);
  571. Result:=aNode;
  572. end;
  573. procedure TEdgeDetector.ProcessMesh;
  574. begin
  575. inherited;
  576. BuildOpposingEdges;
  577. end;
  578. procedure TEdgeDetector.ReplaceVertexIndex(const ViRemove,
  579. ViReplaceWith: integer);
  580. var
  581. i : integer;
  582. Done : boolean;
  583. Edge : TEdge;
  584. begin
  585. for i := 0 to FaceList.Count-1 do
  586. with FaceList[i] do
  587. begin
  588. if Active then
  589. begin
  590. if Vertices[0] = ViRemove then
  591. Vertices[0] := ViReplaceWith;
  592. if Vertices[1] = ViRemove then
  593. Vertices[1] := ViReplaceWith;
  594. if Vertices[2] = ViRemove then
  595. Vertices[2] := ViReplaceWith;
  596. if (Vertices[0]=Vertices[1]) or
  597. (Vertices[1]=Vertices[2]) or
  598. (Vertices[2]=Vertices[0]) then
  599. Active := false;
  600. end;
  601. end;
  602. Done := false;
  603. while not Done do
  604. begin
  605. Done := true;
  606. for i := 0 to EdgeList.Count-1 do
  607. with EdgeList[i] do
  608. begin
  609. if (Vertices[0] = ViRemove) or (Vertices[1] = ViRemove) then
  610. begin
  611. if Vertices[0] = ViRemove then
  612. Vertices[0] := ViReplaceWith;
  613. if Vertices[1] = ViRemove then
  614. Vertices[1] := ViReplaceWith;
  615. UpdateEdgeLength;
  616. Edge := EdgeList[i];
  617. EdgeList.Delete(i);
  618. if Edge.Length=-1 then
  619. Edge.Free
  620. else
  621. EdgeList.InsertSorted(Edge);
  622. Done := false;
  623. break;//}
  624. end;
  625. end;
  626. end;
  627. end;
  628. //--------------------------
  629. // TFace
  630. //--------------------------
  631. constructor TFace.Create(aMeshObject: TMeshObject);
  632. begin
  633. MeshObject := aMeshObject;
  634. Active := true;
  635. end;
  636. procedure TFace.UpdateNormal;
  637. begin
  638. CalcPlaneNormal(
  639. MeshObject.Vertices[Vertices[0]],
  640. MeshObject.Vertices[Vertices[1]],
  641. MeshObject.Vertices[Vertices[2]], Normal);
  642. end;
  643. //------------------
  644. { TEdge }
  645. //------------------
  646. procedure TEdge.Contract;
  647. begin
  648. // We're removing vertex 1 and replacing it with vertex 0
  649. FOwner.ReplaceVertexIndex(Vertices[1], Vertices[0]);
  650. //MeshObject.Vertices[Vertices[0]] := MeshObject.Vertices[Vertices[1]];
  651. Length := -1;
  652. end;
  653. constructor TEdge.Create(const AOwner: TEdgeDetector; AVi0, AVi1 : integer;
  654. AFace0, AFace1 : TFace; AMeshObject : TMeshObject; ASolid : boolean);
  655. begin
  656. FOwner := AOwner;
  657. Vertices[0] := AVi0;
  658. Vertices[1] := AVi1;
  659. Faces[0] := AFace0;
  660. Faces[1] := AFace1;
  661. FMeshObject := AMeshObject;
  662. FSolid := true;
  663. UpdateEdgeLength;
  664. end;
  665. procedure TEdge.UpdateEdgeLength;
  666. begin
  667. if FOwner.FCalcEdgeLength then
  668. begin
  669. if Vertices[0] = Vertices[1] then
  670. Length := -1
  671. else
  672. Length := VectorDistance(
  673. FOwner.GLBaseMesh.LocalToAbsolute(FMeshObject.Vertices[Vertices[0]]),
  674. FOwner.GLBaseMesh.LocalToAbsolute(FMeshObject.Vertices[Vertices[1]]));
  675. end;
  676. end;
  677. end.