meshPropertyGridComponent.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import * as React from "react";
  2. import { Mesh, Observable } from "babylonjs";
  3. import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
  4. import { LineContainerComponent } from "../../../lineContainerComponent";
  5. import { TextLineComponent } from "../../../lines/textLineComponent";
  6. import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
  7. import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
  8. import { SliderLineComponent } from "../../../lines/sliderLineComponent";
  9. import { QuaternionLineComponent } from "../../../lines/quaternionLineComponent";
  10. import { AxesViewerComponent } from "./axesViewerComponent";
  11. import { FloatLineComponent } from "../../../lines/floatLineComponent";
  12. import { LockObject } from "../lockObject";
  13. interface IMeshPropertyGridComponentProps {
  14. mesh: Mesh,
  15. lockObject: LockObject,
  16. onSelectionChangedObservable?: Observable<any>,
  17. onPropertyChangedObservable?: Observable<PropertyChangedEvent>
  18. }
  19. export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGridComponentProps, { displayNormals: boolean, renderNormalVectors: boolean }> {
  20. constructor(props: IMeshPropertyGridComponentProps) {
  21. super(props);
  22. const mesh = this.props.mesh;
  23. this.state = { displayNormals: false, renderNormalVectors: mesh.reservedDataStore && mesh.reservedDataStore.normalLines }
  24. }
  25. renderNormalVectors() {
  26. const mesh = this.props.mesh;
  27. const scene = mesh.getScene();
  28. if (mesh.reservedDataStore && mesh.reservedDataStore.normalLines) {
  29. mesh.reservedDataStore.normalLines.dispose();
  30. mesh.reservedDataStore.normalLines = null;
  31. this.setState({ renderNormalVectors: false });
  32. return;
  33. }
  34. var normals = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  35. var positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  36. const color = BABYLON.Color3.White();
  37. const size = mesh.getBoundingInfo().diagonalLength * 0.05;
  38. var lines = [];
  39. for (var i = 0; i < normals!.length; i += 3) {
  40. var v1 = BABYLON.Vector3.FromArray(positions!, i);
  41. var v2 = v1.add(BABYLON.Vector3.FromArray(normals!, i).scaleInPlace(size));
  42. lines.push([v1, v2]);
  43. }
  44. var normalLines = BABYLON.MeshBuilder.CreateLineSystem("normalLines", { lines: lines }, scene);
  45. normalLines.color = color;
  46. normalLines.parent = mesh;
  47. if (!mesh.reservedDataStore) {
  48. mesh.reservedDataStore = {};
  49. }
  50. mesh.reservedDataStore.normalLines = normalLines;
  51. this.setState({ renderNormalVectors: true });
  52. }
  53. displayNormals() {
  54. const mesh = this.props.mesh;
  55. const scene = mesh.getScene();
  56. if (!mesh.material) {
  57. return;
  58. }
  59. if (mesh.material.getClassName() === "NormalMaterial") {
  60. mesh.material.dispose();
  61. mesh.material = mesh.reservedDataStore.originalMaterial;
  62. mesh.reservedDataStore.originalMaterial = null;
  63. this.setState({ displayNormals: false });
  64. } else {
  65. if (!(BABYLON as any).NormalMaterial) {
  66. this.setState({ displayNormals: true });
  67. BABYLON.Tools.LoadScript("https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js", () => {
  68. this.displayNormals();
  69. });
  70. return;
  71. }
  72. if (!mesh.reservedDataStore) {
  73. mesh.reservedDataStore = {};
  74. }
  75. mesh.reservedDataStore.originalMaterial = mesh.material;
  76. const normalMaterial = new (BABYLON as any).NormalMaterial("normalMaterial", scene);
  77. normalMaterial.disableLighting = true;
  78. normalMaterial.sideOrientation = mesh.material.sideOrientation;
  79. normalMaterial.reservedDataStore = { hidden: true };
  80. mesh.material = normalMaterial;
  81. this.setState({ displayNormals: true });
  82. }
  83. }
  84. onMaterialLink() {
  85. if (!this.props.onSelectionChangedObservable) {
  86. return;
  87. }
  88. const mesh = this.props.mesh;
  89. this.props.onSelectionChangedObservable.notifyObservers(mesh.material)
  90. }
  91. convertPhysicsTypeToString(): string {
  92. const mesh = this.props.mesh;
  93. switch (mesh.physicsImpostor!.type) {
  94. case BABYLON.PhysicsImpostor.NoImpostor:
  95. return "No impostor";
  96. case BABYLON.PhysicsImpostor.SphereImpostor:
  97. return "Sphere";
  98. case BABYLON.PhysicsImpostor.BoxImpostor:
  99. return "Box";
  100. case BABYLON.PhysicsImpostor.PlaneImpostor:
  101. return "Plane";
  102. case BABYLON.PhysicsImpostor.MeshImpostor:
  103. return "Mesh";
  104. case BABYLON.PhysicsImpostor.CylinderImpostor:
  105. return "Cylinder";
  106. case BABYLON.PhysicsImpostor.ParticleImpostor:
  107. return "Particle";
  108. case BABYLON.PhysicsImpostor.HeightmapImpostor:
  109. return "Heightmap";
  110. }
  111. return "Unknown";
  112. }
  113. render() {
  114. const mesh = this.props.mesh;
  115. const scene = mesh.getScene();
  116. const displayNormals = mesh.material != null && mesh.material.getClassName() === "NormalMaterial";
  117. const renderNormalVectors = (mesh.reservedDataStore && mesh.reservedDataStore.normalLines) ? true : false;
  118. return (
  119. <div className="pane">
  120. <LineContainerComponent title="GENERAL">
  121. <TextLineComponent label="ID" value={mesh.id} />
  122. <TextLineComponent label="Unique ID" value={mesh.uniqueId.toString()} />
  123. <TextLineComponent label="Class" value={mesh.getClassName()} />
  124. <TextLineComponent label="Vertices" value={mesh.getTotalVertices().toString()} />
  125. <TextLineComponent label="Faces" value={(mesh.getTotalIndices() / 3).toFixed(0)} />
  126. <TextLineComponent label="Sub-meshes" value={mesh.subMeshes ? mesh.subMeshes.length.toString() : "0"} />
  127. <TextLineComponent label="Has skeleton" value={mesh.skeleton ? "Yes" : "No"} />
  128. <CheckBoxLineComponent label="IsEnabled" isSelected={() => mesh.isEnabled()} onSelect={(value) => mesh.setEnabled(value)} />
  129. <CheckBoxLineComponent label="IsPickable" target={mesh} propertyName="isPickable" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  130. {
  131. mesh.material &&
  132. <TextLineComponent label="Material" value={mesh.material.name} onLink={() => this.onMaterialLink()} />
  133. }
  134. </LineContainerComponent>
  135. <LineContainerComponent title="TRANSFORMS">
  136. <Vector3LineComponent label="Position" target={mesh} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  137. {
  138. !mesh.rotationQuaternion &&
  139. <Vector3LineComponent label="Rotation" target={mesh} propertyName="rotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  140. }
  141. {
  142. mesh.rotationQuaternion &&
  143. <QuaternionLineComponent label="Rotation" target={mesh} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  144. }
  145. <Vector3LineComponent label="Scaling" target={mesh} propertyName="scaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  146. </LineContainerComponent>
  147. <LineContainerComponent title="DISPLAY" closed={true}>
  148. <SliderLineComponent label="Visibility" target={mesh} propertyName="visibility" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  149. <FloatLineComponent lockObject={this.props.lockObject} label="Alpha index" target={mesh} propertyName="alphaIndex" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  150. <CheckBoxLineComponent label="Receive shadows" target={mesh} propertyName="receiveShadows" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  151. {
  152. mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind) &&
  153. <CheckBoxLineComponent label="Use vertex colors" target={mesh} propertyName="useVertexColors" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  154. }
  155. {
  156. scene.fogMode !== BABYLON.Scene.FOGMODE_NONE &&
  157. <CheckBoxLineComponent label="Apply fog" target={mesh} propertyName="applyFog" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  158. }
  159. {
  160. !mesh.parent &&
  161. <CheckBoxLineComponent label="Infinite distance" target={mesh} propertyName="infiniteDistance" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  162. }
  163. </LineContainerComponent>
  164. <LineContainerComponent title="ADVANCED" closed={true}>
  165. {
  166. mesh.useBones &&
  167. <CheckBoxLineComponent label="Compute bones using shaders" target={mesh} propertyName="computeBonesUsingShaders" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  168. }
  169. <CheckBoxLineComponent label="Collisions" target={mesh} propertyName="checkCollisions" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  170. <TextLineComponent label="Has normals" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind) ? "Yes" : "No"} />
  171. <TextLineComponent label="Has vertex colors" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind) ? "Yes" : "No"} />
  172. <TextLineComponent label="has UV set 0" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind) ? "Yes" : "No"} />
  173. <TextLineComponent label="has UV set 1" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind) ? "Yes" : "No"} />
  174. <TextLineComponent label="has UV set 2" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV3Kind) ? "Yes" : "No"} />
  175. <TextLineComponent label="has UV set 3" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV4Kind) ? "Yes" : "No"} />
  176. <TextLineComponent label="has tangents" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind) ? "Yes" : "No"} />
  177. <TextLineComponent label="has matrix weights" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind) ? "Yes" : "No"} />
  178. <TextLineComponent label="has matrix indices" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) ? "Yes" : "No"} />
  179. </LineContainerComponent>
  180. {
  181. mesh.physicsImpostor != null &&
  182. <LineContainerComponent title="PHYSICS" closed={true}>
  183. <FloatLineComponent lockObject={this.props.lockObject} label="Mass" target={mesh.physicsImpostor} propertyName="mass" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  184. <FloatLineComponent lockObject={this.props.lockObject} label="Friction" target={mesh.physicsImpostor} propertyName="friction" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  185. <FloatLineComponent lockObject={this.props.lockObject} label="Restitution" target={mesh.physicsImpostor} propertyName="restitution" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  186. <TextLineComponent label="Type" value={this.convertPhysicsTypeToString()} />
  187. </LineContainerComponent>
  188. }
  189. <LineContainerComponent title="DEBUG" closed={true}>
  190. <CheckBoxLineComponent label="Show bounding box" target={mesh} propertyName="showBoundingBox" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  191. {
  192. mesh.material &&
  193. <CheckBoxLineComponent label="Display normals" isSelected={() => displayNormals} onSelect={() => this.displayNormals()} />
  194. }
  195. {
  196. mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind) &&
  197. <CheckBoxLineComponent label="Render vertex normals" isSelected={() => renderNormalVectors} onSelect={() => this.renderNormalVectors()} />
  198. }
  199. <AxesViewerComponent node={mesh} />
  200. </LineContainerComponent>
  201. </div>
  202. );
  203. }
  204. }