babylon.geometry.ts 58 KB

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