babylon.geometry.ts 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. module BABYLON {
  2. export class Geometry implements IGetSetVerticesData {
  3. // Members
  4. public id: string;
  5. public delayLoadState = Engine.DELAYLOADSTATE_NONE;
  6. public delayLoadingFile: string;
  7. public onGeometryUpdated: (geometry: Geometry, kind?: string) => void;
  8. // Private
  9. private _scene: Scene;
  10. private _engine: Engine;
  11. private _meshes: Mesh[];
  12. private _totalVertices = 0;
  13. private _indices: number[] | Int32Array;
  14. private _vertexBuffers;
  15. private _isDisposed = false;
  16. private _extend: { minimum: Vector3, maximum: Vector3 };
  17. public _delayInfo; //ANY
  18. private _indexBuffer;
  19. public _boundingInfo: BoundingInfo;
  20. public _delayLoadingFunction: (any: any, geometry: Geometry) => void;
  21. constructor(id: string, scene: Scene, vertexData?: VertexData, updatable?: boolean, mesh?: Mesh) {
  22. this.id = id;
  23. this._engine = scene.getEngine();
  24. this._meshes = [];
  25. this._scene = scene;
  26. //Init vertex buffer cache
  27. this._vertexBuffers = {};
  28. this._indices = [];
  29. // vertexData
  30. if (vertexData) {
  31. this.setAllVerticesData(vertexData, updatable);
  32. }
  33. else {
  34. this._totalVertices = 0;
  35. this._indices = [];
  36. }
  37. // applyToMesh
  38. if (mesh) {
  39. this.applyToMesh(mesh);
  40. mesh.computeWorldMatrix(true);
  41. }
  42. }
  43. public get extend(): { minimum: Vector3, maximum: Vector3 } {
  44. return this._extend;
  45. }
  46. public getScene(): Scene {
  47. return this._scene;
  48. }
  49. public getEngine(): Engine {
  50. return this._engine;
  51. }
  52. public isReady(): boolean {
  53. return this.delayLoadState === Engine.DELAYLOADSTATE_LOADED || this.delayLoadState === Engine.DELAYLOADSTATE_NONE;
  54. }
  55. public setAllVerticesData(vertexData: VertexData, updatable?: boolean): void {
  56. vertexData.applyToGeometry(this, updatable);
  57. this.notifyUpdate();
  58. }
  59. public setVerticesData(kind: string, data: number[] | Float32Array, updatable?: boolean, stride?: number): void {
  60. if (this._vertexBuffers[kind]) {
  61. this._vertexBuffers[kind].dispose();
  62. }
  63. this._vertexBuffers[kind] = new VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
  64. if (kind === VertexBuffer.PositionKind) {
  65. stride = this._vertexBuffers[kind].getStrideSize();
  66. this._totalVertices = data.length / stride;
  67. this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices);
  68. var meshes = this._meshes;
  69. var numOfMeshes = meshes.length;
  70. for (var index = 0; index < numOfMeshes; index++) {
  71. var mesh = meshes[index];
  72. mesh._resetPointsArrayCache();
  73. mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
  74. mesh._createGlobalSubMesh();
  75. mesh.computeWorldMatrix(true);
  76. }
  77. }
  78. this.notifyUpdate(kind);
  79. }
  80. public updateVerticesDataDirectly(kind: string, data: Float32Array, offset: number): void {
  81. var vertexBuffer = this.getVertexBuffer(kind);
  82. if (!vertexBuffer) {
  83. return;
  84. }
  85. vertexBuffer.updateDirectly(data, offset);
  86. this.notifyUpdate(kind);
  87. }
  88. public updateVerticesData(kind: string, data: number[] | Float32Array, updateExtends?: boolean): void {
  89. var vertexBuffer = this.getVertexBuffer(kind);
  90. if (!vertexBuffer) {
  91. return;
  92. }
  93. vertexBuffer.update(data);
  94. if (kind === VertexBuffer.PositionKind) {
  95. var stride = vertexBuffer.getStrideSize();
  96. this._totalVertices = data.length / stride;
  97. if (updateExtends) {
  98. this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices);
  99. }
  100. var meshes = this._meshes;
  101. var numOfMeshes = meshes.length;
  102. for (var index = 0; index < numOfMeshes; index++) {
  103. var mesh = meshes[index];
  104. mesh._resetPointsArrayCache();
  105. if (updateExtends) {
  106. mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
  107. for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
  108. var subMesh = mesh.subMeshes[subIndex];
  109. subMesh.refreshBoundingInfo();
  110. }
  111. }
  112. }
  113. }
  114. this.notifyUpdate(kind);
  115. }
  116. public getTotalVertices(): number {
  117. if (!this.isReady()) {
  118. return 0;
  119. }
  120. return this._totalVertices;
  121. }
  122. public getVerticesData(kind: string, copyWhenShared?: boolean): number[] | Float32Array {
  123. var vertexBuffer = this.getVertexBuffer(kind);
  124. if (!vertexBuffer) {
  125. return null;
  126. }
  127. var orig = vertexBuffer.getData();
  128. if (!copyWhenShared || this._meshes.length === 1) {
  129. return orig;
  130. } else {
  131. var len = orig.length;
  132. var copy = [];
  133. for (var i = 0; i < len; i++) {
  134. copy.push(orig[i]);
  135. }
  136. return copy;
  137. }
  138. }
  139. public getVertexBuffer(kind: string): VertexBuffer {
  140. if (!this.isReady()) {
  141. return null;
  142. }
  143. return this._vertexBuffers[kind];
  144. }
  145. public getVertexBuffers(): VertexBuffer[] {
  146. if (!this.isReady()) {
  147. return null;
  148. }
  149. return this._vertexBuffers;
  150. }
  151. public isVerticesDataPresent(kind: string): boolean {
  152. if (!this._vertexBuffers) {
  153. if (this._delayInfo) {
  154. return this._delayInfo.indexOf(kind) !== -1;
  155. }
  156. return false;
  157. }
  158. return this._vertexBuffers[kind] !== undefined;
  159. }
  160. public getVerticesDataKinds(): string[] {
  161. var result = [];
  162. var kind;
  163. if (!this._vertexBuffers && this._delayInfo) {
  164. for (kind in this._delayInfo) {
  165. result.push(kind);
  166. }
  167. } else {
  168. for (kind in this._vertexBuffers) {
  169. result.push(kind);
  170. }
  171. }
  172. return result;
  173. }
  174. public setIndices(indices: number[] | Int32Array, totalVertices?: number): void {
  175. if (this._indexBuffer) {
  176. this._engine._releaseBuffer(this._indexBuffer);
  177. }
  178. this._indices = indices;
  179. if (this._meshes.length !== 0 && this._indices) {
  180. this._indexBuffer = this._engine.createIndexBuffer(this._indices);
  181. }
  182. if (totalVertices !== undefined) {
  183. this._totalVertices = totalVertices;
  184. }
  185. var meshes = this._meshes;
  186. var numOfMeshes = meshes.length;
  187. for (var index = 0; index < numOfMeshes; index++) {
  188. meshes[index]._createGlobalSubMesh();
  189. }
  190. this.notifyUpdate();
  191. }
  192. public getTotalIndices(): number {
  193. if (!this.isReady()) {
  194. return 0;
  195. }
  196. return this._indices.length;
  197. }
  198. public getIndices(copyWhenShared?: boolean): number[] | Int32Array {
  199. if (!this.isReady()) {
  200. return null;
  201. }
  202. var orig = this._indices;
  203. if (!copyWhenShared || this._meshes.length === 1) {
  204. return orig;
  205. } else {
  206. var len = orig.length;
  207. var copy = [];
  208. for (var i = 0; i < len; i++) {
  209. copy.push(orig[i]);
  210. }
  211. return copy;
  212. }
  213. }
  214. public getIndexBuffer(): any {
  215. if (!this.isReady()) {
  216. return null;
  217. }
  218. return this._indexBuffer;
  219. }
  220. public releaseForMesh(mesh: Mesh, shouldDispose?: boolean): void {
  221. var meshes = this._meshes;
  222. var index = meshes.indexOf(mesh);
  223. if (index === -1) {
  224. return;
  225. }
  226. for (var kind in this._vertexBuffers) {
  227. this._vertexBuffers[kind].dispose();
  228. }
  229. if (this._indexBuffer && this._engine._releaseBuffer(this._indexBuffer)) {
  230. this._indexBuffer = null;
  231. }
  232. meshes.splice(index, 1);
  233. mesh._geometry = null;
  234. if (meshes.length === 0 && shouldDispose) {
  235. this.dispose();
  236. }
  237. }
  238. public applyToMesh(mesh: Mesh): void {
  239. if (mesh._geometry === this) {
  240. return;
  241. }
  242. var previousGeometry = mesh._geometry;
  243. if (previousGeometry) {
  244. previousGeometry.releaseForMesh(mesh);
  245. }
  246. var meshes = this._meshes;
  247. // must be done before setting vertexBuffers because of mesh._createGlobalSubMesh()
  248. mesh._geometry = this;
  249. this._scene.pushGeometry(this);
  250. meshes.push(mesh);
  251. if (this.isReady()) {
  252. this._applyToMesh(mesh);
  253. }
  254. else {
  255. mesh._boundingInfo = this._boundingInfo;
  256. }
  257. }
  258. private _applyToMesh(mesh: Mesh): void {
  259. var numOfMeshes = this._meshes.length;
  260. // vertexBuffers
  261. for (var kind in this._vertexBuffers) {
  262. if (numOfMeshes === 1) {
  263. this._vertexBuffers[kind].create();
  264. }
  265. this._vertexBuffers[kind]._buffer.references = numOfMeshes;
  266. if (kind === VertexBuffer.PositionKind) {
  267. mesh._resetPointsArrayCache();
  268. if (!this._extend) {
  269. this._extend = Tools.ExtractMinAndMax(this._vertexBuffers[kind].getData(), 0, this._totalVertices);
  270. }
  271. mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
  272. mesh._createGlobalSubMesh();
  273. //bounding info was just created again, world matrix should be applied again.
  274. mesh._updateBoundingInfo();
  275. }
  276. }
  277. // indexBuffer
  278. if (numOfMeshes === 1 && this._indices) {
  279. this._indexBuffer = this._engine.createIndexBuffer(this._indices);
  280. }
  281. if (this._indexBuffer) {
  282. this._indexBuffer.references = numOfMeshes;
  283. }
  284. }
  285. private notifyUpdate(kind?: string) {
  286. if (this.onGeometryUpdated) {
  287. this.onGeometryUpdated(this, kind);
  288. }
  289. }
  290. public load(scene: Scene, onLoaded?: () => void): void {
  291. if (this.delayLoadState === Engine.DELAYLOADSTATE_LOADING) {
  292. return;
  293. }
  294. if (this.isReady()) {
  295. if (onLoaded) {
  296. onLoaded();
  297. }
  298. return;
  299. }
  300. this.delayLoadState = Engine.DELAYLOADSTATE_LOADING;
  301. scene._addPendingData(this);
  302. Tools.LoadFile(this.delayLoadingFile, data => {
  303. this._delayLoadingFunction(JSON.parse(data), this);
  304. this.delayLoadState = Engine.DELAYLOADSTATE_LOADED;
  305. this._delayInfo = [];
  306. scene._removePendingData(this);
  307. var meshes = this._meshes;
  308. var numOfMeshes = meshes.length;
  309. for (var index = 0; index < numOfMeshes; index++) {
  310. this._applyToMesh(meshes[index]);
  311. }
  312. if (onLoaded) {
  313. onLoaded();
  314. }
  315. }, () => { }, scene.database);
  316. }
  317. public isDisposed(): boolean {
  318. return this._isDisposed;
  319. }
  320. public dispose(): void {
  321. var meshes = this._meshes;
  322. var numOfMeshes = meshes.length;
  323. var index: number;
  324. for (index = 0; index < numOfMeshes; index++) {
  325. this.releaseForMesh(meshes[index]);
  326. }
  327. this._meshes = [];
  328. for (var kind in this._vertexBuffers) {
  329. this._vertexBuffers[kind].dispose();
  330. }
  331. this._vertexBuffers = [];
  332. this._totalVertices = 0;
  333. if (this._indexBuffer) {
  334. this._engine._releaseBuffer(this._indexBuffer);
  335. }
  336. this._indexBuffer = null;
  337. this._indices = [];
  338. this.delayLoadState = Engine.DELAYLOADSTATE_NONE;
  339. this.delayLoadingFile = null;
  340. this._delayLoadingFunction = null;
  341. this._delayInfo = [];
  342. this._boundingInfo = null;
  343. this._scene.removeGeometry(this);
  344. this._isDisposed = true;
  345. }
  346. public copy(id: string): Geometry {
  347. var vertexData = new VertexData();
  348. vertexData.indices = [];
  349. var indices = this.getIndices();
  350. for (var index = 0; index < indices.length; index++) {
  351. (<number[]>vertexData.indices).push(indices[index]);
  352. }
  353. var updatable = false;
  354. var stopChecking = false;
  355. var kind;
  356. for (kind in this._vertexBuffers) {
  357. // using slice() to make a copy of the array and not just reference it
  358. var data = this.getVerticesData(kind);
  359. if (data instanceof Float32Array) {
  360. vertexData.set(new Float32Array(<Float32Array>data), kind);
  361. } else {
  362. vertexData.set((<number[]>data).slice(0), kind);
  363. }
  364. if (!stopChecking) {
  365. updatable = this.getVertexBuffer(kind).isUpdatable();
  366. stopChecking = !updatable;
  367. }
  368. }
  369. var geometry = new Geometry(id, this._scene, vertexData, updatable, null);
  370. geometry.delayLoadState = this.delayLoadState;
  371. geometry.delayLoadingFile = this.delayLoadingFile;
  372. geometry._delayLoadingFunction = this._delayLoadingFunction;
  373. for (kind in this._delayInfo) {
  374. geometry._delayInfo = geometry._delayInfo || [];
  375. geometry._delayInfo.push(kind);
  376. }
  377. // Bounding info
  378. geometry._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
  379. return geometry;
  380. }
  381. public serialize(): any {
  382. var serializationObject: any = {};
  383. serializationObject.id = this.id;
  384. if (Tags.HasTags(this)) {
  385. serializationObject.tags = Tags.GetTags(this);
  386. }
  387. return serializationObject;
  388. }
  389. public serializeVerticeData(): any {
  390. var serializationObject = this.serialize();
  391. if (this.isVerticesDataPresent(VertexBuffer.PositionKind)) {
  392. serializationObject.positions = this.getVerticesData(VertexBuffer.PositionKind);
  393. }
  394. if (this.isVerticesDataPresent(VertexBuffer.NormalKind)) {
  395. serializationObject.normals = this.getVerticesData(VertexBuffer.NormalKind);
  396. }
  397. if (this.isVerticesDataPresent(VertexBuffer.UVKind)) {
  398. serializationObject.uvs = this.getVerticesData(VertexBuffer.UVKind);
  399. }
  400. if (this.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
  401. serializationObject.uvs2 = this.getVerticesData(VertexBuffer.UV2Kind);
  402. }
  403. if (this.isVerticesDataPresent(VertexBuffer.UV3Kind)) {
  404. serializationObject.uvs3 = this.getVerticesData(VertexBuffer.UV3Kind);
  405. }
  406. if (this.isVerticesDataPresent(VertexBuffer.UV4Kind)) {
  407. serializationObject.uvs4 = this.getVerticesData(VertexBuffer.UV4Kind);
  408. }
  409. if (this.isVerticesDataPresent(VertexBuffer.UV5Kind)) {
  410. serializationObject.uvs5 = this.getVerticesData(VertexBuffer.UV5Kind);
  411. }
  412. if (this.isVerticesDataPresent(VertexBuffer.UV6Kind)) {
  413. serializationObject.uvs6 = this.getVerticesData(VertexBuffer.UV6Kind);
  414. }
  415. if (this.isVerticesDataPresent(VertexBuffer.ColorKind)) {
  416. serializationObject.colors = this.getVerticesData(VertexBuffer.ColorKind);
  417. }
  418. if (this.isVerticesDataPresent(VertexBuffer.MatricesIndicesKind)) {
  419. serializationObject.matricesIndices = this.getVerticesData(VertexBuffer.MatricesIndicesKind);
  420. serializationObject.matricesIndices._isExpanded = true;
  421. }
  422. if (this.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind)) {
  423. serializationObject.matricesWeights = this.getVerticesData(VertexBuffer.MatricesWeightsKind);
  424. }
  425. serializationObject.indices = this.getIndices();
  426. return serializationObject;
  427. }
  428. // Statics
  429. public static ExtractFromMesh(mesh: Mesh, id: string): Geometry {
  430. var geometry = mesh._geometry;
  431. if (!geometry) {
  432. return null;
  433. }
  434. return geometry.copy(id);
  435. }
  436. // from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
  437. // be aware Math.random() could cause collisions
  438. public static RandomId(): string {
  439. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
  440. var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
  441. return v.toString(16);
  442. });
  443. }
  444. public static ImportGeometry(parsedGeometry: any, mesh: Mesh): void {
  445. var scene = mesh.getScene();
  446. // Geometry
  447. var geometryId = parsedGeometry.geometryId;
  448. if (geometryId) {
  449. var geometry = scene.getGeometryByID(geometryId);
  450. if (geometry) {
  451. geometry.applyToMesh(mesh);
  452. }
  453. } else if (parsedGeometry instanceof ArrayBuffer) {
  454. var binaryInfo = mesh._binaryInfo;
  455. if (binaryInfo.positionsAttrDesc && binaryInfo.positionsAttrDesc.count > 0) {
  456. var positionsData = new Float32Array(parsedGeometry, binaryInfo.positionsAttrDesc.offset, binaryInfo.positionsAttrDesc.count);
  457. mesh.setVerticesData(VertexBuffer.PositionKind, positionsData, false);
  458. }
  459. if (binaryInfo.normalsAttrDesc && binaryInfo.normalsAttrDesc.count > 0) {
  460. var normalsData = new Float32Array(parsedGeometry, binaryInfo.normalsAttrDesc.offset, binaryInfo.normalsAttrDesc.count);
  461. mesh.setVerticesData(VertexBuffer.NormalKind, normalsData, false);
  462. }
  463. if (binaryInfo.uvsAttrDesc && binaryInfo.uvsAttrDesc.count > 0) {
  464. var uvsData = new Float32Array(parsedGeometry, binaryInfo.uvsAttrDesc.offset, binaryInfo.uvsAttrDesc.count);
  465. mesh.setVerticesData(VertexBuffer.UVKind, uvsData, false);
  466. }
  467. if (binaryInfo.uvs2AttrDesc && binaryInfo.uvs2AttrDesc.count > 0) {
  468. var uvs2Data = new Float32Array(parsedGeometry, binaryInfo.uvs2AttrDesc.offset, binaryInfo.uvs2AttrDesc.count);
  469. mesh.setVerticesData(VertexBuffer.UV2Kind, uvs2Data, false);
  470. }
  471. if (binaryInfo.uvs3AttrDesc && binaryInfo.uvs3AttrDesc.count > 0) {
  472. var uvs3Data = new Float32Array(parsedGeometry, binaryInfo.uvs3AttrDesc.offset, binaryInfo.uvs3AttrDesc.count);
  473. mesh.setVerticesData(VertexBuffer.UV3Kind, uvs3Data, false);
  474. }
  475. if (binaryInfo.uvs4AttrDesc && binaryInfo.uvs4AttrDesc.count > 0) {
  476. var uvs4Data = new Float32Array(parsedGeometry, binaryInfo.uvs4AttrDesc.offset, binaryInfo.uvs4AttrDesc.count);
  477. mesh.setVerticesData(VertexBuffer.UV4Kind, uvs4Data, false);
  478. }
  479. if (binaryInfo.uvs5AttrDesc && binaryInfo.uvs5AttrDesc.count > 0) {
  480. var uvs5Data = new Float32Array(parsedGeometry, binaryInfo.uvs5AttrDesc.offset, binaryInfo.uvs5AttrDesc.count);
  481. mesh.setVerticesData(VertexBuffer.UV5Kind, uvs5Data, false);
  482. }
  483. if (binaryInfo.uvs6AttrDesc && binaryInfo.uvs6AttrDesc.count > 0) {
  484. var uvs6Data = new Float32Array(parsedGeometry, binaryInfo.uvs6AttrDesc.offset, binaryInfo.uvs6AttrDesc.count);
  485. mesh.setVerticesData(VertexBuffer.UV6Kind, uvs6Data, false);
  486. }
  487. if (binaryInfo.colorsAttrDesc && binaryInfo.colorsAttrDesc.count > 0) {
  488. var colorsData = new Float32Array(parsedGeometry, binaryInfo.colorsAttrDesc.offset, binaryInfo.colorsAttrDesc.count);
  489. mesh.setVerticesData(VertexBuffer.ColorKind, colorsData, false, binaryInfo.colorsAttrDesc.stride);
  490. }
  491. if (binaryInfo.matricesIndicesAttrDesc && binaryInfo.matricesIndicesAttrDesc.count > 0) {
  492. var matricesIndicesData = new Int32Array(parsedGeometry, binaryInfo.matricesIndicesAttrDesc.offset, binaryInfo.matricesIndicesAttrDesc.count);
  493. mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, matricesIndicesData, false);
  494. }
  495. if (binaryInfo.matricesWeightsAttrDesc && binaryInfo.matricesWeightsAttrDesc.count > 0) {
  496. var matricesWeightsData = new Float32Array(parsedGeometry, binaryInfo.matricesWeightsAttrDesc.offset, binaryInfo.matricesWeightsAttrDesc.count);
  497. mesh.setVerticesData(VertexBuffer.MatricesWeightsKind, matricesWeightsData, false);
  498. }
  499. if (binaryInfo.indicesAttrDesc && binaryInfo.indicesAttrDesc.count > 0) {
  500. var indicesData = new Int32Array(parsedGeometry, binaryInfo.indicesAttrDesc.offset, binaryInfo.indicesAttrDesc.count);
  501. mesh.setIndices(indicesData);
  502. }
  503. if (binaryInfo.subMeshesAttrDesc && binaryInfo.subMeshesAttrDesc.count > 0) {
  504. var subMeshesData = new Int32Array(parsedGeometry, binaryInfo.subMeshesAttrDesc.offset, binaryInfo.subMeshesAttrDesc.count * 5);
  505. mesh.subMeshes = [];
  506. for (var i = 0; i < binaryInfo.subMeshesAttrDesc.count; i++) {
  507. var materialIndex = subMeshesData[(i * 5) + 0];
  508. var verticesStart = subMeshesData[(i * 5) + 1];
  509. var verticesCount = subMeshesData[(i * 5) + 2];
  510. var indexStart = subMeshesData[(i * 5) + 3];
  511. var indexCount = subMeshesData[(i * 5) + 4];
  512. var subMesh = new SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh);
  513. }
  514. }
  515. } else if (parsedGeometry.positions && parsedGeometry.normals && parsedGeometry.indices) {
  516. mesh.setVerticesData(VertexBuffer.PositionKind, parsedGeometry.positions, false);
  517. mesh.setVerticesData(VertexBuffer.NormalKind, parsedGeometry.normals, false);
  518. if (parsedGeometry.uvs) {
  519. mesh.setVerticesData(VertexBuffer.UVKind, parsedGeometry.uvs, false);
  520. }
  521. if (parsedGeometry.uvs2) {
  522. mesh.setVerticesData(VertexBuffer.UV2Kind, parsedGeometry.uvs2, false);
  523. }
  524. if (parsedGeometry.uvs3) {
  525. mesh.setVerticesData(VertexBuffer.UV3Kind, parsedGeometry.uvs3, false);
  526. }
  527. if (parsedGeometry.uvs4) {
  528. mesh.setVerticesData(VertexBuffer.UV4Kind, parsedGeometry.uvs4, false);
  529. }
  530. if (parsedGeometry.uvs5) {
  531. mesh.setVerticesData(VertexBuffer.UV5Kind, parsedGeometry.uvs5, false);
  532. }
  533. if (parsedGeometry.uvs6) {
  534. mesh.setVerticesData(VertexBuffer.UV6Kind, parsedGeometry.uvs6, false);
  535. }
  536. if (parsedGeometry.colors) {
  537. mesh.setVerticesData(VertexBuffer.ColorKind, Color4.CheckColors4(parsedGeometry.colors, parsedGeometry.positions.length / 3), false);
  538. }
  539. if (parsedGeometry.matricesIndices) {
  540. if (!parsedGeometry.matricesIndices._isExpanded) {
  541. var floatIndices = [];
  542. for (var i = 0; i < parsedGeometry.matricesIndices.length; i++) {
  543. var matricesIndex = parsedGeometry.matricesIndices[i];
  544. floatIndices.push(matricesIndex & 0x000000FF);
  545. floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
  546. floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
  547. floatIndices.push(matricesIndex >> 24);
  548. }
  549. mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, floatIndices, false);
  550. } else {
  551. delete parsedGeometry.matricesIndices._isExpanded;
  552. mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, parsedGeometry.matricesIndices, false);
  553. }
  554. }
  555. if (parsedGeometry.matricesIndicesExtra) {
  556. if (!parsedGeometry.matricesIndicesExtra._isExpanded) {
  557. var floatIndices = [];
  558. for (var i = 0; i < parsedGeometry.matricesIndicesExtra.length; i++) {
  559. var matricesIndex = parsedGeometry.matricesIndicesExtra[i];
  560. floatIndices.push(matricesIndex & 0x000000FF);
  561. floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
  562. floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
  563. floatIndices.push(matricesIndex >> 24);
  564. }
  565. mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, floatIndices, false);
  566. } else {
  567. delete parsedGeometry.matricesIndices._isExpanded;
  568. mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, parsedGeometry.matricesIndicesExtra, false);
  569. }
  570. }
  571. if (parsedGeometry.matricesWeights) {
  572. mesh.setVerticesData(VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, false);
  573. }
  574. if (parsedGeometry.matricesWeightsExtra) {
  575. mesh.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, false);
  576. }
  577. mesh.setIndices(parsedGeometry.indices);
  578. }
  579. // SubMeshes
  580. if (parsedGeometry.subMeshes) {
  581. mesh.subMeshes = [];
  582. for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
  583. var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
  584. var subMesh = new SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
  585. }
  586. }
  587. // Flat shading
  588. if (mesh._shouldGenerateFlatShading) {
  589. mesh.convertToFlatShadedMesh();
  590. delete mesh._shouldGenerateFlatShading;
  591. }
  592. // Update
  593. mesh.computeWorldMatrix(true);
  594. // Octree
  595. if (scene['_selectionOctree']) {
  596. scene['_selectionOctree'].addMesh(mesh);
  597. }
  598. }
  599. public static Parse(parsedVertexData: any, scene: Scene, rootUrl: string): Geometry {
  600. if (scene.getGeometryByID(parsedVertexData.id)) {
  601. return null; // null since geometry could be something else than a box...
  602. }
  603. var geometry = new Geometry(parsedVertexData.id, scene);
  604. Tags.AddTagsTo(geometry, parsedVertexData.tags);
  605. if (parsedVertexData.delayLoadingFile) {
  606. geometry.delayLoadState = Engine.DELAYLOADSTATE_NOTLOADED;
  607. geometry.delayLoadingFile = rootUrl + parsedVertexData.delayLoadingFile;
  608. geometry._boundingInfo = new BoundingInfo(Vector3.FromArray(parsedVertexData.boundingBoxMinimum), Vector3.FromArray(parsedVertexData.boundingBoxMaximum));
  609. geometry._delayInfo = [];
  610. if (parsedVertexData.hasUVs) {
  611. geometry._delayInfo.push(VertexBuffer.UVKind);
  612. }
  613. if (parsedVertexData.hasUVs2) {
  614. geometry._delayInfo.push(VertexBuffer.UV2Kind);
  615. }
  616. if (parsedVertexData.hasUVs3) {
  617. geometry._delayInfo.push(VertexBuffer.UV3Kind);
  618. }
  619. if (parsedVertexData.hasUVs4) {
  620. geometry._delayInfo.push(VertexBuffer.UV4Kind);
  621. }
  622. if (parsedVertexData.hasUVs5) {
  623. geometry._delayInfo.push(VertexBuffer.UV5Kind);
  624. }
  625. if (parsedVertexData.hasUVs6) {
  626. geometry._delayInfo.push(VertexBuffer.UV6Kind);
  627. }
  628. if (parsedVertexData.hasColors) {
  629. geometry._delayInfo.push(VertexBuffer.ColorKind);
  630. }
  631. if (parsedVertexData.hasMatricesIndices) {
  632. geometry._delayInfo.push(VertexBuffer.MatricesIndicesKind);
  633. }
  634. if (parsedVertexData.hasMatricesWeights) {
  635. geometry._delayInfo.push(VertexBuffer.MatricesWeightsKind);
  636. }
  637. geometry._delayLoadingFunction = VertexData.ImportVertexData;
  638. } else {
  639. VertexData.ImportVertexData(parsedVertexData, geometry);
  640. }
  641. scene.pushGeometry(geometry, true);
  642. return geometry;
  643. }
  644. }
  645. /////// Primitives //////////////////////////////////////////////
  646. export module Geometry.Primitives {
  647. /// Abstract class
  648. export class _Primitive extends Geometry {
  649. // Private
  650. private _beingRegenerated: boolean;
  651. private _canBeRegenerated: boolean;
  652. constructor(id: string, scene: Scene, vertexData?: VertexData, canBeRegenerated?: boolean, mesh?: Mesh) {
  653. this._beingRegenerated = true;
  654. this._canBeRegenerated = canBeRegenerated;
  655. super(id, scene, vertexData, false, mesh); // updatable = false to be sure not to update vertices
  656. this._beingRegenerated = false;
  657. }
  658. public canBeRegenerated(): boolean {
  659. return this._canBeRegenerated;
  660. }
  661. public regenerate(): void {
  662. if (!this._canBeRegenerated) {
  663. return;
  664. }
  665. this._beingRegenerated = true;
  666. this.setAllVerticesData(this._regenerateVertexData(), false);
  667. this._beingRegenerated = false;
  668. }
  669. public asNewGeometry(id: string): Geometry {
  670. return super.copy(id);
  671. }
  672. // overrides
  673. public setAllVerticesData(vertexData: VertexData, updatable?: boolean): void {
  674. if (!this._beingRegenerated) {
  675. return;
  676. }
  677. super.setAllVerticesData(vertexData, false);
  678. }
  679. public setVerticesData(kind: string, data: number[] | Int32Array | Float32Array, updatable?: boolean): void {
  680. if (!this._beingRegenerated) {
  681. return;
  682. }
  683. super.setVerticesData(kind, data, false);
  684. }
  685. // to override
  686. // protected
  687. public _regenerateVertexData(): VertexData {
  688. throw new Error("Abstract method");
  689. }
  690. public copy(id: string): Geometry {
  691. throw new Error("Must be overriden in sub-classes.");
  692. }
  693. public serialize(): any {
  694. var serializationObject = super.serialize();
  695. serializationObject.canBeRegenerated = this.canBeRegenerated();
  696. return serializationObject;
  697. }
  698. }
  699. export class Ribbon extends _Primitive {
  700. // Members
  701. public pathArray: Vector3[][];
  702. public closeArray: boolean;
  703. public closePath: boolean;
  704. public offset: number;
  705. public side: number;
  706. constructor(id: string, scene: Scene, pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  707. this.pathArray = pathArray;
  708. this.closeArray = closeArray;
  709. this.closePath = closePath;
  710. this.offset = offset;
  711. this.side = side;
  712. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  713. }
  714. public _regenerateVertexData(): VertexData {
  715. return VertexData.CreateRibbon({ pathArray: this.pathArray, closeArray: this.closeArray, closePath: this.closePath, offset: this.offset, sideOrientation: this.side });
  716. }
  717. public copy(id: string): Geometry {
  718. return new Ribbon(id, this.getScene(), this.pathArray, this.closeArray, this.closePath, this.offset, this.canBeRegenerated(), null, this.side);
  719. }
  720. }
  721. export class Box extends _Primitive {
  722. // Members
  723. public size: number;
  724. public side: number;
  725. constructor(id: string, scene: Scene, size: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  726. this.size = size;
  727. this.side = side;
  728. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  729. }
  730. public _regenerateVertexData(): VertexData {
  731. return VertexData.CreateBox({ size: this.size, sideOrientation: this.side });
  732. }
  733. public copy(id: string): Geometry {
  734. return new Box(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
  735. }
  736. public serialize(): any {
  737. var serializationObject = super.serialize();
  738. serializationObject.size = this.size;
  739. return serializationObject;
  740. }
  741. public static Parse(parsedBox: any, scene: Scene): Box {
  742. if (scene.getGeometryByID(parsedBox.id)) {
  743. return null; // null since geometry could be something else than a box...
  744. }
  745. var box = new Geometry.Primitives.Box(parsedBox.id, scene, parsedBox.size, parsedBox.canBeRegenerated, null);
  746. Tags.AddTagsTo(box, parsedBox.tags);
  747. scene.pushGeometry(box, true);
  748. return box;
  749. }
  750. }
  751. export class Sphere extends _Primitive {
  752. // Members
  753. public segments: number;
  754. public diameter: number;
  755. public side: number;
  756. constructor(id: string, scene: Scene, segments: number, diameter: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  757. this.segments = segments;
  758. this.diameter = diameter;
  759. this.side = side;
  760. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  761. }
  762. public _regenerateVertexData(): VertexData {
  763. return VertexData.CreateSphere({ segments: this.segments, diameter: this.diameter, sideOrientation: this.side });
  764. }
  765. public copy(id: string): Geometry {
  766. return new Sphere(id, this.getScene(), this.segments, this.diameter, this.canBeRegenerated(), null, this.side);
  767. }
  768. public serialize(): any {
  769. var serializationObject = super.serialize();
  770. serializationObject.segments = this.segments;
  771. serializationObject.diameter = this.diameter;
  772. return serializationObject;
  773. }
  774. public static Parse(parsedSphere: any, scene: Scene): Geometry.Primitives.Sphere {
  775. if (scene.getGeometryByID(parsedSphere.id)) {
  776. return null; // null since geometry could be something else than a sphere...
  777. }
  778. var sphere = new Geometry.Primitives.Sphere(parsedSphere.id, scene, parsedSphere.segments, parsedSphere.diameter, parsedSphere.canBeRegenerated, null);
  779. Tags.AddTagsTo(sphere, parsedSphere.tags);
  780. scene.pushGeometry(sphere, true);
  781. return sphere;
  782. }
  783. }
  784. export class Disc extends _Primitive {
  785. // Members
  786. public radius: number;
  787. public tessellation: number;
  788. public side: number;
  789. constructor(id: string, scene: Scene, radius: number, tessellation: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  790. this.radius = radius;
  791. this.tessellation = tessellation;
  792. this.side = side;
  793. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  794. }
  795. public _regenerateVertexData(): VertexData {
  796. return VertexData.CreateDisc({ radius: this.radius, tessellation: this.tessellation, sideOrientation: this.side });
  797. }
  798. public copy(id: string): Geometry {
  799. return new Disc(id, this.getScene(), this.radius, this.tessellation, this.canBeRegenerated(), null, this.side);
  800. }
  801. }
  802. export class Cylinder extends _Primitive {
  803. // Members
  804. public height: number;
  805. public diameterTop: number;
  806. public diameterBottom: number;
  807. public tessellation: number;
  808. public subdivisions: number;
  809. public side: number;
  810. constructor(id: string, scene: Scene, height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: number = 1, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  811. this.height = height;
  812. this.diameterTop = diameterTop;
  813. this.diameterBottom = diameterBottom;
  814. this.tessellation = tessellation;
  815. this.subdivisions = subdivisions;
  816. this.side = side;
  817. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  818. }
  819. public _regenerateVertexData(): VertexData {
  820. return VertexData.CreateCylinder({ height: this.height, diameterTop: this.diameterTop, diameterBottom: this.diameterBottom, tessellation: this.tessellation, subdivisions: this.subdivisions, sideOrientation: this.side });
  821. }
  822. public copy(id: string): Geometry {
  823. return new Cylinder(id, this.getScene(), this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions, this.canBeRegenerated(), null, this.side);
  824. }
  825. public serialize(): any {
  826. var serializationObject = super.serialize();
  827. serializationObject.height = this.height;
  828. serializationObject.diameterTop = this.diameterTop;
  829. serializationObject.diameterBottom = this.diameterBottom;
  830. serializationObject.tessellation = this.tessellation;
  831. return serializationObject;
  832. }
  833. public static Parse(parsedCylinder: any, scene: Scene): Geometry.Primitives.Cylinder {
  834. if (scene.getGeometryByID(parsedCylinder.id)) {
  835. return null; // null since geometry could be something else than a cylinder...
  836. }
  837. var cylinder = new Geometry.Primitives.Cylinder(parsedCylinder.id, scene, parsedCylinder.height, parsedCylinder.diameterTop, parsedCylinder.diameterBottom, parsedCylinder.tessellation, parsedCylinder.subdivisions, parsedCylinder.canBeRegenerated, null);
  838. Tags.AddTagsTo(cylinder, parsedCylinder.tags);
  839. scene.pushGeometry(cylinder, true);
  840. return cylinder;
  841. }
  842. }
  843. export class Torus extends _Primitive {
  844. // Members
  845. public diameter: number;
  846. public thickness: number;
  847. public tessellation: number;
  848. public side: number;
  849. constructor(id: string, scene: Scene, diameter: number, thickness: number, tessellation: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  850. this.diameter = diameter;
  851. this.thickness = thickness;
  852. this.tessellation = tessellation;
  853. this.side = side;
  854. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  855. }
  856. public _regenerateVertexData(): VertexData {
  857. return VertexData.CreateTorus({ diameter: this.diameter, thickness: this.thickness, tessellation: this.tessellation, sideOrientation: this.side });
  858. }
  859. public copy(id: string): Geometry {
  860. return new Torus(id, this.getScene(), this.diameter, this.thickness, this.tessellation, this.canBeRegenerated(), null, this.side);
  861. }
  862. public serialize(): any {
  863. var serializationObject = super.serialize();
  864. serializationObject.diameter = this.diameter;
  865. serializationObject.thickness = this.thickness;
  866. serializationObject.tessellation = this.tessellation;
  867. return serializationObject;
  868. }
  869. public static Parse(parsedTorus: any, scene: Scene): Geometry.Primitives.Torus {
  870. if (scene.getGeometryByID(parsedTorus.id)) {
  871. return null; // null since geometry could be something else than a torus...
  872. }
  873. var torus = new Geometry.Primitives.Torus(parsedTorus.id, scene, parsedTorus.diameter, parsedTorus.thickness, parsedTorus.tessellation, parsedTorus.canBeRegenerated, null);
  874. Tags.AddTagsTo(torus, parsedTorus.tags);
  875. scene.pushGeometry(torus, true);
  876. return torus;
  877. }
  878. }
  879. export class Ground extends _Primitive {
  880. // Members
  881. public width: number;
  882. public height: number;
  883. public subdivisions: number;
  884. constructor(id: string, scene: Scene, width: number, height: number, subdivisions: number, canBeRegenerated?: boolean, mesh?: Mesh) {
  885. this.width = width;
  886. this.height = height;
  887. this.subdivisions = subdivisions;
  888. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  889. }
  890. public _regenerateVertexData(): VertexData {
  891. return VertexData.CreateGround({ width: this.width, height: this.height, subdivisions: this.subdivisions });
  892. }
  893. public copy(id: string): Geometry {
  894. return new Ground(id, this.getScene(), this.width, this.height, this.subdivisions, this.canBeRegenerated(), null);
  895. }
  896. public serialize(): any {
  897. var serializationObject = super.serialize();
  898. serializationObject.width = this.width;
  899. serializationObject.height = this.height;
  900. serializationObject.subdivisions = this.subdivisions;
  901. return serializationObject;
  902. }
  903. public static Parse(parsedGround: any, scene: Scene): Geometry.Primitives.Ground {
  904. if (scene.getGeometryByID(parsedGround.id)) {
  905. return null; // null since geometry could be something else than a ground...
  906. }
  907. var ground = new Geometry.Primitives.Ground(parsedGround.id, scene, parsedGround.width, parsedGround.height, parsedGround.subdivisions, parsedGround.canBeRegenerated, null);
  908. Tags.AddTagsTo(ground, parsedGround.tags);
  909. scene.pushGeometry(ground, true);
  910. return ground;
  911. }
  912. }
  913. export class TiledGround extends _Primitive {
  914. // Members
  915. public xmin: number;
  916. public zmin: number;
  917. public xmax: number;
  918. public zmax: number;
  919. public subdivisions: { w: number; h: number; };
  920. public precision: { w: number; h: number; };
  921. constructor(id: string, scene: Scene, xmin: number, zmin: number, xmax: number, zmax: number, subdivisions: { w: number; h: number; }, precision: { w: number; h: number; }, canBeRegenerated?: boolean, mesh?: Mesh) {
  922. this.xmin = xmin;
  923. this.zmin = zmin;
  924. this.xmax = xmax;
  925. this.zmax = zmax;
  926. this.subdivisions = subdivisions;
  927. this.precision = precision;
  928. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  929. }
  930. public _regenerateVertexData(): VertexData {
  931. return VertexData.CreateTiledGround({ xmin: this.xmin, zmin: this.zmin, xmax: this.xmax, zmax: this.zmax, subdivisions: this.subdivisions, precision: this.precision });
  932. }
  933. public copy(id: string): Geometry {
  934. return new TiledGround(id, this.getScene(), this.xmin, this.zmin, this.xmax, this.zmax, this.subdivisions, this.precision, this.canBeRegenerated(), null);
  935. }
  936. }
  937. export class Plane extends _Primitive {
  938. // Members
  939. public size: number;
  940. public side: number;
  941. constructor(id: string, scene: Scene, size: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  942. this.size = size;
  943. this.side = side;
  944. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  945. }
  946. public _regenerateVertexData(): VertexData {
  947. return VertexData.CreatePlane({ size: this.size, sideOrientation: this.side });
  948. }
  949. public copy(id: string): Geometry {
  950. return new Plane(id, this.getScene(), this.size, this.canBeRegenerated(), null, this.side);
  951. }
  952. public serialize(): any {
  953. var serializationObject = super.serialize();
  954. serializationObject.size = this.size;
  955. return serializationObject;
  956. }
  957. public static Parse(parsedPlane: any, scene: Scene): Geometry.Primitives.Plane {
  958. if (scene.getGeometryByID(parsedPlane.id)) {
  959. return null; // null since geometry could be something else than a ground...
  960. }
  961. var plane = new Geometry.Primitives.Plane(parsedPlane.id, scene, parsedPlane.size, parsedPlane.canBeRegenerated, null);
  962. Tags.AddTagsTo(plane, parsedPlane.tags);
  963. scene.pushGeometry(plane, true);
  964. return plane;
  965. }
  966. }
  967. export class TorusKnot extends _Primitive {
  968. // Members
  969. public radius: number;
  970. public tube: number;
  971. public radialSegments: number;
  972. public tubularSegments: number;
  973. public p: number;
  974. public q: number;
  975. public side: number;
  976. constructor(id: string, scene: Scene, radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, canBeRegenerated?: boolean, mesh?: Mesh, side: number = Mesh.DEFAULTSIDE) {
  977. this.radius = radius;
  978. this.tube = tube;
  979. this.radialSegments = radialSegments;
  980. this.tubularSegments = tubularSegments;
  981. this.p = p;
  982. this.q = q;
  983. this.side = side;
  984. super(id, scene, this._regenerateVertexData(), canBeRegenerated, mesh);
  985. }
  986. public _regenerateVertexData(): VertexData {
  987. return VertexData.CreateTorusKnot({ radius: this.radius, tube: this.tube, radialSegments: this.radialSegments, tubularSegments: this.tubularSegments, p: this.p, q: this.q, sideOrientation: this.side });
  988. }
  989. public copy(id: string): Geometry {
  990. return new TorusKnot(id, this.getScene(), this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q, this.canBeRegenerated(), null, this.side);
  991. }
  992. public serialize(): any {
  993. var serializationObject = super.serialize();
  994. serializationObject.radius = this.radius;
  995. serializationObject.tube = this.tube;
  996. serializationObject.radialSegments = this.radialSegments;
  997. serializationObject.tubularSegments = this.tubularSegments;
  998. serializationObject.p = this.p;
  999. serializationObject.q = this.q;
  1000. return serializationObject;
  1001. };
  1002. public static Parse(parsedTorusKnot: any, scene: Scene): Geometry.Primitives.TorusKnot {
  1003. if (scene.getGeometryByID(parsedTorusKnot.id)) {
  1004. return null; // null since geometry could be something else than a ground...
  1005. }
  1006. var torusKnot = new Geometry.Primitives.TorusKnot(parsedTorusKnot.id, scene, parsedTorusKnot.radius, parsedTorusKnot.tube, parsedTorusKnot.radialSegments, parsedTorusKnot.tubularSegments, parsedTorusKnot.p, parsedTorusKnot.q, parsedTorusKnot.canBeRegenerated, null);
  1007. Tags.AddTagsTo(torusKnot, parsedTorusKnot.tags);
  1008. scene.pushGeometry(torusKnot, true);
  1009. return torusKnot;
  1010. }
  1011. }
  1012. }
  1013. }