actionsbuilder.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. module ActionsBuilder {
  2. /**
  3. * Defines static types
  4. */
  5. export class Type {
  6. private static _TRIGGER = 0;
  7. private static _ACTION = 1;
  8. private static _FLOW_CONTROL = 2;
  9. private static _OBJECT = 3;
  10. private static _SCENE = 4;
  11. public static get TRIGGER(): number {
  12. return Type._TRIGGER;
  13. }
  14. public static get ACTION(): number {
  15. return Type._ACTION;
  16. }
  17. public static get FLOW_CONTROL(): number {
  18. return Type._FLOW_CONTROL;
  19. }
  20. public static get OBJECT(): number {
  21. return Type._OBJECT;
  22. }
  23. public static get SCENE(): number {
  24. return Type._SCENE;
  25. }
  26. }
  27. /*
  28. * Defines the BABYLON.JS elements
  29. */
  30. export class SceneElements {
  31. /*
  32. * BabylonJS objects
  33. */
  34. private static _ENGINE: BABYLON.Engine = new BABYLON.Engine(<HTMLCanvasElement>document.getElementById("RenderCanvasID"));
  35. private static _SCENE: BABYLON.Scene = new BABYLON.Scene(SceneElements.ENGINE);
  36. private static _MESH: BABYLON.Mesh = new BABYLON.Mesh("mesh", SceneElements._SCENE);
  37. private static _LIGHT: BABYLON.Light = new BABYLON.Light("light", SceneElements._SCENE);
  38. private static _CAMERA: BABYLON.Camera = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
  39. public static get ENGINE(): BABYLON.Engine {
  40. return SceneElements._ENGINE;
  41. }
  42. public static get SCENE(): BABYLON.Scene {
  43. return SceneElements._SCENE;
  44. }
  45. public static get MESH(): BABYLON.Mesh {
  46. return SceneElements._MESH;
  47. }
  48. public static get LIGHT(): BABYLON.Light {
  49. return SceneElements._LIGHT;
  50. }
  51. public static get CAMERA(): BABYLON.Camera {
  52. return SceneElements._CAMERA;
  53. }
  54. /*
  55. * Objects names
  56. */
  57. private static _MESHES = new Array<string>();
  58. private static _LIGHTS = new Array<string>();
  59. private static _CAMERAS = new Array<string>();
  60. private static _SOUNDS = new Array<string>();
  61. public static get MESHES(): Array<string> {
  62. return SceneElements._MESHES;
  63. }
  64. public static get LIGHTS(): Array<string> {
  65. return SceneElements._LIGHTS;
  66. }
  67. public static get CAMERAS(): Array<string> {
  68. return SceneElements._CAMERAS;
  69. }
  70. public static get SOUNDS(): Array<string> {
  71. return SceneElements._SOUNDS;
  72. }
  73. /*
  74. * Properties
  75. */
  76. private static _MESH_PROPERTIES = new Array<string>();
  77. private static _LIGHT_PROPERTIES = new Array<string>();
  78. private static _CAMERA_PROPERTIES = new Array<string>();
  79. private static _SCENE_PROPERTIES = new Array<string>();
  80. public static get MESH_PROPERTIES(): Array<string> {
  81. return SceneElements._MESH_PROPERTIES;
  82. }
  83. public static get LIGHT_PROPERTIES(): Array<string> {
  84. return SceneElements._LIGHT_PROPERTIES;
  85. }
  86. public static get CAMERA_PROPERTIES(): Array<string> {
  87. return SceneElements._CAMERA_PROPERTIES;
  88. }
  89. public static get SCENE_PROPERTIES(): Array<string> {
  90. return SceneElements._SCENE_PROPERTIES;
  91. }
  92. /*
  93. * Types
  94. */
  95. private static _TYPES = new Array<string>();
  96. public static get TYPES(): Array<string> {
  97. return SceneElements._TYPES;
  98. }
  99. /*
  100. * Operators
  101. */
  102. private static _OPERATORS = new Array<string>();
  103. public static get OPERATORS(): Array<string> {
  104. return SceneElements._OPERATORS;
  105. }
  106. /*
  107. * Methods
  108. */
  109. public static GetInstanceOf(object: Object): string {
  110. if (object === null || object === undefined) {
  111. return "";
  112. }
  113. return object.constructor.toString().match(/function (\w*)/)[1];
  114. }
  115. public static TestInstanceOf (object: Object, propertyName: string): boolean {
  116. if (object === null || object.constructor === null) {
  117. return false;
  118. }
  119. if (propertyName.length > 0 && propertyName[0] === "_")
  120. return false;
  121. var name = SceneElements.GetInstanceOf(object);
  122. for (var i = 0; i < SceneElements.TYPES.length; i++) {
  123. if (name === SceneElements.TYPES[i]) {
  124. return true;
  125. }
  126. }
  127. return false;
  128. }
  129. }
  130. // Functions
  131. var specialTypes = [
  132. "StandardMaterial"
  133. ];
  134. SceneElements.MESH.material = new BABYLON.StandardMaterial("material", SceneElements.SCENE);
  135. var addSpecialType = (object: any, properties: Array<string>, thing: string) => {
  136. for (var specialThing in object[thing]) {
  137. if (object[thing].hasOwnProperty(specialThing) && SceneElements.TestInstanceOf(object[thing][specialThing], specialThing)) {
  138. properties.push(thing + "." + specialThing);
  139. }
  140. }
  141. };
  142. // Configure types
  143. SceneElements.TYPES.push("Color3");
  144. SceneElements.TYPES.push("Boolean");
  145. SceneElements.TYPES.push("Number");
  146. SceneElements.TYPES.push("Vector2");
  147. SceneElements.TYPES.push("Vector3");
  148. SceneElements.TYPES.push("String");
  149. // Configure operators
  150. SceneElements.OPERATORS.push("IsEqual");
  151. SceneElements.OPERATORS.push("IsDifferent");
  152. SceneElements.OPERATORS.push("IsGreater");
  153. SceneElements.OPERATORS.push("IsLesser");
  154. // Configure properties
  155. for (var thing in SceneElements.MESH) {
  156. var instance = SceneElements.GetInstanceOf(SceneElements.MESH[thing]);
  157. if (SceneElements.MESH.hasOwnProperty(thing)) {
  158. if (specialTypes.indexOf(instance) !== -1) {
  159. addSpecialType(SceneElements.MESH, SceneElements.MESH_PROPERTIES, thing);
  160. }
  161. else if (SceneElements.TestInstanceOf(SceneElements.MESH[thing], thing)) {
  162. SceneElements.MESH_PROPERTIES.push(thing);
  163. }
  164. }
  165. }
  166. for (var thing in SceneElements.LIGHT) {
  167. if (SceneElements.LIGHT.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.LIGHT[thing], thing)) {
  168. SceneElements.LIGHT_PROPERTIES.push(thing);
  169. }
  170. }
  171. for (var thing in SceneElements.CAMERA) {
  172. if (SceneElements.CAMERA.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.CAMERA[thing], thing)) {
  173. SceneElements.CAMERA_PROPERTIES.push(thing);
  174. }
  175. }
  176. for (var thing in SceneElements.SCENE) {
  177. if (SceneElements.SCENE.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.SCENE[thing], thing)) {
  178. SceneElements.SCENE_PROPERTIES.push(thing);
  179. }
  180. }
  181. /**
  182. * Defines an element property
  183. */
  184. export interface ElementProperty {
  185. targetType?: string;
  186. text: string;
  187. value: string;
  188. }
  189. /**
  190. * Defines an element property result
  191. */
  192. export interface ElementPropertyResult {
  193. targetType?: string;
  194. value: string;
  195. }
  196. /**
  197. * Generic element, has a name, a text to draw, a description
  198. * and a list of properties (ElementProperty)
  199. */
  200. export interface Element {
  201. name: string;
  202. text: string;
  203. properties: Array<ElementProperty>;
  204. description: string;
  205. }
  206. /**
  207. * Actions Builder elements (triggers, actions & flow controls) that are
  208. * arrays of Element
  209. */
  210. export class Elements {
  211. private static _TRIGGERS = new Array<Element>();
  212. private static _ACTIONS = new Array<Element>();
  213. private static _FLOW_CONTROLS = new Array<Element>();
  214. public static get TRIGGERS(): Array<Element> {
  215. return Elements._TRIGGERS;
  216. }
  217. public static get ACTIONS(): Array<Element> {
  218. return Elements._ACTIONS;
  219. }
  220. public static get FLOW_CONTROLS(): Array<Element> {
  221. return Elements._FLOW_CONTROLS;
  222. }
  223. public static GetElementFromName(name: string): Element {
  224. for (var i = 0; i < Elements.TRIGGERS.length; i++) {
  225. if (Elements.TRIGGERS[i].name === name) {
  226. return Elements._TRIGGERS[i];
  227. }
  228. }
  229. for (var i = 0; i < Elements.ACTIONS.length; i++) {
  230. if (Elements.ACTIONS[i].name === name) {
  231. return Elements._ACTIONS[i];
  232. }
  233. }
  234. for (var i = 0; i < Elements.FLOW_CONTROLS.length; i++) {
  235. if (Elements.FLOW_CONTROLS[i].name === name) {
  236. return Elements._FLOW_CONTROLS[i];
  237. }
  238. }
  239. return null;
  240. }
  241. }
  242. // Configure triggers
  243. Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
  244. Elements.TRIGGERS.push({ name: "OnLeftPickTrigger", text: "left pick", properties: [], description: "When the user picks the edited mesh using the left click" });
  245. Elements.TRIGGERS.push({ name: "OnRightPickTrigger", text: "right pick", properties: [], description: "When the user picks the edited mesh using the right click" });
  246. Elements.TRIGGERS.push({ name: "OnCenterPickTrigger", text: "center pick", properties: [], description: "When the user picks the edited mesh using the click of the mouse wheel" });
  247. Elements.TRIGGERS.push({ name: "OnPointerOverTrigger", text: "pointer over", properties: [], description: "When the user's mouse is over the edited mesh" });
  248. Elements.TRIGGERS.push({ name: "OnPointerOutTrigger", text: "pointer out", properties: [], description: "When the user's mouse is out of the edited mesh" });
  249. Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
  250. Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
  251. Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
  252. Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
  253. Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
  254. // Configure actions
  255. Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
  256. Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
  257. Elements.ACTIONS.push({ name: "SetValueAction", text: "set value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Sets a new value to the specified parameter of the target object (example: position.x to 0.0)" });
  258. Elements.ACTIONS.push({ name: "SetParentAction", text: "set parent", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "parent", value: "" }], description: "Sets the new parent of the target object (example: a mesh or a light)" });
  259. Elements.ACTIONS.push({ name: "IncrementValueAction", text: "increment value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Increments the value of the given parameter of the target object. The value can be negative. (example: increment position.x of 5.0)" });
  260. Elements.ACTIONS.push({ name: "PlayAnimationAction", text: "play animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "from", value: "0" }, { text: "to", value: "150" }, { text: "loop", value: "false" }], description: "Plays an animation of the target object. Specify the start frame, the end frame and if the animation should loop." });
  261. Elements.ACTIONS.push({ name: "StopAnimationAction", text: "stop animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }], description: "Stops the animations of the target object." });
  262. Elements.ACTIONS.push({ name: "DoNothingAction", text: "do nothing", properties: [], description: "Does nothing, can be used to balance/equilibrate the actions graph." });
  263. Elements.ACTIONS.push({ name: "InterpolateValueAction", text: "interpolate value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "0" }, { text: "duration", value: "1000" }, { text: "stopOtherAnimations", value: "false" }], description: "Creates an animation (key frames) that animates the target object by interpolating the given parameter of the target value." });
  264. Elements.ACTIONS.push({ name: "PlaySoundAction", text: "play sound", properties: [{ text: "sound", value: "" }], description: "Plays the specified sound." });
  265. Elements.ACTIONS.push({ name: "StopSoundAction", text: "stop sound", properties: [{ text: "sound", value: "" }], description: "Stops the specified sound." });
  266. Elements.ACTIONS.push({ name: "CombineAction", text: "combine", properties: [], description: "Special action that combines multiple actions. The combined actions are executed at the same time. Drag'n'drop the new actions inside to combine actions." });
  267. // Configure flow control
  268. Elements.FLOW_CONTROLS.push({ name: "ValueCondition", text: "value condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }, { text: "operator", value: SceneElements.OPERATORS[0] }], description: "A condition checking if a given value is equal, different, lesser or greater than the given parameter of the target object" });
  269. Elements.FLOW_CONTROLS.push({ name: "StateCondition", text: "state condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "A condition checking if the target object's state is equal to the given state. See \"set state\" action to set a state to an object." });
  270. Elements.FLOW_CONTROLS.push({ name: "Hub", text: "hub", properties: [], description: "The hub is internally used by the Combine Action. It allows to add children to the Combine Action" });
  271. }