public void ExportKeyFrames() { keyList.frameList = new List <WeldonKeyFrame>(); foreach (MyClass thing in MyList) { WeldonKeyFrame frame = new WeldonKeyFrame(); frame.time = thing.time; frame.posX = thing.position.x; frame.posY = thing.position.y; frame.posZ = thing.position.z; frame.rotX = thing.rotation.x; frame.rotY = thing.rotation.y; frame.rotZ = thing.rotation.z; frame.scalX = thing.scale.x; frame.scalY = thing.scale.y; frame.scalZ = thing.scale.z; keyList.frameList.Add(frame); } string filePath = Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/"; if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } string stringToWrite = JsonUtility.ToJson(keyList); File.WriteAllText(filePath + gameObject.name + "_" + gameObject.transform.GetSiblingIndex() + ".txt", stringToWrite); //fileExported = true; keyList = new KeyFrameList(); AssetDatabase.Refresh(); }
public void RecordPoint(float time) { WeldonKeyFrame frame = new WeldonKeyFrame(time, transform); MyList.Add(new MyClass(frame)); Debug.Log("Frame Added: " + frame.InformationString()); }
public MyClass(WeldonKeyFrame kFrame) { frame = kFrame; time = kFrame.time; position = new Vector3(kFrame.posX, kFrame.posY, kFrame.posZ); rotation = new Vector3(kFrame.rotX, kFrame.rotY, kFrame.rotZ); scale = new Vector3(kFrame.scalX, kFrame.scalY, kFrame.scalZ); }
public bool IsDifferentHeight(WeldonKeyFrame frame) { if (!scalY.Equals(frame.scalY)) { return(true); } else { return(false); } }
public bool IsDifferentWidth(WeldonKeyFrame frame) { if (!scalX.Equals(frame.scalX)) { return(true); } else { return(false); } }
public bool IsDifferentRotation(WeldonKeyFrame frame) { if (!rotX.Equals(frame.rotX) || !rotY.Equals(frame.rotY) || !rotZ.Equals(frame.rotZ)) { return(true); } else { return(false); } }
public bool IsDifferentPosition(WeldonKeyFrame frame) { if (!posX.Equals(frame.posX) || !posY.Equals(frame.posY) || !posZ.Equals(frame.posZ)) { return(true); } else { return(false); } }
public override string getKeyFramesString(KeyFrameList keyList) { StringBuilder sb = new StringBuilder(); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", scaleFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {prevFrame.posX*z_pos_offset} {prevFrame.posY*y_pos_offset} {prevFrame.posZ*z_pos_offset};"; rotFrom = $"from: {prevFrame.rotX*x_rot_offset} {prevFrame.rotY*y_rot_offset} {prevFrame.rotZ*z_rot_offset};"; scaleFrom = $"from: {prevFrame.scalX*x_scale_offset} {prevFrame.scalY*y_scale_offset} {prevFrame.scalZ*y_scale_offset};"; animTrigger = $"startEvents: animationcomplete__{objectId}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop)? $", animationcomplete__{objectId}_f{keyList.frameList.Count-1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {frame.posX*x_pos_offset} {frame.posY*y_pos_offset} {frame.posZ*z_pos_offset};", rotTo = $"to: {frame.rotX*x_rot_offset} {frame.rotY*y_rot_offset} {frame.rotZ*z_rot_offset};", scaleTo = $"to: {frame.scalX*x_scale_offset} {frame.scalY*y_scale_offset} {frame.scalZ*y_scale_offset};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{objectId}_f{index}=\" property: position; {posFrom} {posTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{objectId}_f{index}=\" property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if ((frame.IsDifferentWidth(prevFrame) || isFirstFrame)) { sb.AppendLine($"animation__{objectId}_f{index}=\" property: scale; {scaleFrom} {scaleTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } return(sb.ToString()); }
//This runs on each object when you hit the play button. It mimics the same animation that will get excecuted when you run the HTML in a browser. private void Update() { float currentTime = Time.time - startTime; float percent = 0; if (keyList != null && currentKeyFrameNumber < keyList.frameList.Count) { WeldonKeyFrame frame = keyList.frameList[currentKeyFrameNumber]; float timeToUse = frame.time; if (currentKeyFrameNumber > 0) { timeToUse = frame.time - keyList.frameList[currentKeyFrameNumber - 1].time; } if (currentTime <= timeToUse && !timeToUse.Equals(0.0f) && !currentTime.Equals(0.0f)) { percent = currentTime / timeToUse; //Debug.Log(currentTime + " percent: " + percent + " pos: " + transform.localPosition.x); Vector3 newPosition = new Vector3(oFrame.posX + (-oFrame.posX + frame.posX) * percent, oFrame.posY + (-oFrame.posY + frame.posY) * percent, oFrame.posZ + (-oFrame.posZ + frame.posZ) * percent); Vector3 newRotation = new Vector3(oFrame.rotX + (-oFrame.rotX + frame.rotX) * percent, oFrame.rotY + (-oFrame.rotY + frame.rotY) * percent, oFrame.rotZ + (-oFrame.rotZ + frame.rotZ) * percent); transform.localPosition = newPosition; transform.eulerAngles = newRotation; transform.localScale = new Vector3(oFrame.scalX + (-oFrame.scalX + frame.scalX) * percent, oFrame.scalY + (-oFrame.scalY + frame.scalY) * percent, oFrame.scalZ + (-oFrame.scalZ + frame.scalZ) * percent); } else { oFrame = keyList.frameList[currentKeyFrameNumber]; currentKeyFrameNumber++; startTime = Time.time; } } else if (loop) { startTime = Time.time; currentKeyFrameNumber = 0; Debug.Log(currentTime + " percent: " + percent + " pos: " + transform.localPosition.x); } }
public void RecordPoint() { if (keyList == null) { keyList = new KeyFrameList(); } transformToRecord = gameObject.transform; WeldonKeyFrame frame = new WeldonKeyFrame(timeOfPosition, transformToRecord); List <CustomList.MyClass> myClass = gameObject.GetComponent <CustomList>().MyList; myClass.Add(new CustomList.MyClass(frame)); keyList.frameList.Add(frame); Debug.Log("Frame Added: " + frame.InformationString()); }
private void Start() { keyList = new KeyFrameList(); string filePath = Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + gameObject.name + "_" + gameObject.transform.GetSiblingIndex() + ".txt"; if (File.Exists(filePath)) { string textFile = File.ReadAllText(filePath); keyList = JsonUtility.FromJson <KeyFrameList>(textFile); } else { keyList = null; } startTime = Time.time; oFrame = new WeldonKeyFrame(0, transform); }
public override void OnInspectorGUI() { //Update our list GetTarget.Update(); //Choose how to display the list<> Example purposes only EditorGUILayout.Space(); EditorGUILayout.Space(); //DisplayFieldType = (displayFieldType)EditorGUILayout.EnumPopup("", DisplayFieldType); //Resize our list //EditorGUILayout.Space(); //EditorGUILayout.Space(); //EditorGUILayout.LabelField("Define the list size with a number"); ListSize = ThisList.arraySize; //ListSize = EditorGUILayout.IntField("List Size", ListSize); if (ListSize != ThisList.arraySize) { while (ListSize > ThisList.arraySize) { ThisList.InsertArrayElementAtIndex(ThisList.arraySize); } while (ListSize < ThisList.arraySize) { ThisList.DeleteArrayElementAtIndex(ThisList.arraySize - 1); } } //EditorGUILayout.Space(); //EditorGUILayout.Space(); //EditorGUILayout.LabelField("Or"); //EditorGUILayout.Space(); //EditorGUILayout.Space(); //Or add a new item to the List<> with a button EditorGUILayout.LabelField("Edit the list of Key Frames for the Animation"); recordTime = EditorGUILayout.FloatField("FrameTime", recordTime); t.gameObject.transform.GetComponent <AnimationHelper>().loop = EditorGUILayout.Toggle("Loop Animation", t.gameObject.transform.GetComponent <AnimationHelper>().loop); t.gameObject.transform.GetComponent <AnimationHelper>().onClick = EditorGUILayout.Toggle("On Click", t.gameObject.transform.GetComponent <AnimationHelper>().onClick); if (GUILayout.Button("Record Point", GUILayout.MaxWidth(130), GUILayout.MaxHeight(20))) { //MyArray.InsertArrayElementAtIndex(MyArray.arraySize); //MyArray.GetArrayElementAtIndex(MyArray.arraySize - 1).intValue = 0; t.RecordPoint(recordTime); } if (GUILayout.Button("Export Animation", GUILayout.MaxWidth(130), GUILayout.MaxHeight(20))) { t.ExportKeyFrames(); } if (GUILayout.Button("Clear List", GUILayout.MaxWidth(130), GUILayout.MaxHeight(20))) { t.ClearPoints(); } EditorGUILayout.Space(); EditorGUILayout.Space(); //Display our list to the inspector window for (int i = 0; i < ThisList.arraySize; i++) { toggled.Add(false); // Initialliazed as false SerializedProperty MyListRef = ThisList.GetArrayElementAtIndex(i); //SerializedProperty MyInt = MyListRef.FindPropertyRelative("AnInt"); SerializedProperty MyFrame = MyListRef.FindPropertyRelative("frame"); SerializedProperty FrameTime = MyListRef.FindPropertyRelative("time"); SerializedProperty FramePosition = MyListRef.FindPropertyRelative("position"); SerializedProperty FrameRotation = MyListRef.FindPropertyRelative("rotation"); SerializedProperty FrameScale = MyListRef.FindPropertyRelative("scale"); //SerializedProperty MyFloat = MyListRef.FindPropertyRelative("AnFloat"); //SerializedProperty MyVect3 = MyListRef.FindPropertyRelative("AnVector3"); //SerializedProperty MyGO = MyListRef.FindPropertyRelative("AnGO"); SerializedProperty MyArray = MyListRef.FindPropertyRelative("AnIntArray"); WeldonKeyFrame frame = new WeldonKeyFrame(); frame.time = FrameTime.floatValue; frame.posX = FramePosition.vector3Value.x; frame.posY = FramePosition.vector3Value.y; frame.posZ = FramePosition.vector3Value.z; frame.rotX = FrameRotation.vector3Value.x; frame.rotY = FrameRotation.vector3Value.y; frame.rotZ = FrameRotation.vector3Value.z; frame.scalX = FrameScale.vector3Value.x; frame.scalY = FrameScale.vector3Value.y; frame.scalZ = FrameScale.vector3Value.z; CustomList.MyClass classThing = new CustomList.MyClass(frame); t.MyList[i] = classThing; //t.MyList[i].time = FrameTime.floatValue; //t.MyList[i].position = FramePosition.vector3Value; //t.MyList[i].rotation = FrameRotation.vector3Value; //t.MyList[i].scale = FrameScale.vector3Value; toggled[i] = EditorGUILayout.Foldout(toggled[i], "[i=" + i + ", t=" + (t.MyList.Count > i ? t.MyList[i].frame.time + "" : "?") + "]"); // Index Foldout // Display the property fields in two ways. if (toggled[i] == true) { if (true) {// Choose to display automatic or custom field types. This is only for example to help display automatic and custom fields. //1. Automatic, No customization <-- Choose me I'm automatic and easy to setup EditorGUILayout.LabelField("Automatic Field By Property Type"); //EditorGUILayout.PropertyField(MyGO); EditorGUILayout.PropertyField(FrameTime); EditorGUILayout.PropertyField(FramePosition); EditorGUILayout.PropertyField(FrameRotation); EditorGUILayout.PropertyField(FrameScale); //EditorGUILayout.PropertyField(MyInt); //EditorGUILayout.PropertyField(MyFloat); //EditorGUILayout.PropertyField(MyVect3); // Array fields with remove at index EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Array Fields"); if (GUILayout.Button("Update Transform", GUILayout.MaxWidth(150), GUILayout.MaxHeight(20))) { WeldonKeyFrame frame2 = new WeldonKeyFrame(); frame2.time = FrameTime.floatValue; frame2.posX = t.transform.localPosition.x; frame2.posY = t.transform.localPosition.y; frame2.posZ = t.transform.localPosition.z; frame2.rotX = t.transform.localEulerAngles.x; frame2.rotY = t.transform.localEulerAngles.y; frame2.rotZ = t.transform.localEulerAngles.z; frame2.scalX = t.transform.localScale.x; frame2.scalY = t.transform.localScale.y; frame2.scalZ = t.transform.localScale.z; CustomList.MyClass classThing2 = new CustomList.MyClass(frame2); t.MyList[i] = classThing2; } if (GUILayout.Button("Set Transform from Frame", GUILayout.MaxWidth(250), GUILayout.MaxHeight(20))) { WeldonKeyFrame frame2 = new WeldonKeyFrame(); frame2.time = FrameTime.floatValue; t.transform.localPosition = t.MyList[i].position; t.transform.localEulerAngles = t.MyList[i].rotation; t.transform.localScale = t.MyList[i].scale; } for (int a = 0; a < MyArray.arraySize; a++) { EditorGUILayout.PropertyField(MyArray.GetArrayElementAtIndex(a)); if (GUILayout.Button("Remove (" + a.ToString() + ")", GUILayout.MaxWidth(100), GUILayout.MaxHeight(15))) { MyArray.DeleteArrayElementAtIndex(a); } } } else { //Or //2 : Full custom GUI Layout <-- Choose me I can be fully customized with GUI options. EditorGUILayout.LabelField("Customizable Field With GUI"); FrameTime.floatValue = EditorGUILayout.FloatField("KeyFrame Time", FrameTime.floatValue); FramePosition.vector3Value = EditorGUILayout.Vector3Field("Position", FramePosition.vector3Value); FrameRotation.vector3Value = EditorGUILayout.Vector3Field("Rotation", FrameRotation.vector3Value); FrameScale.vector3Value = EditorGUILayout.Vector3Field("Scale", FrameScale.vector3Value); //MyGO.objectReferenceValue = EditorGUILayout.ObjectField("My Custom Go", MyGO.objectReferenceValue, typeof(GameObject), true); //MyInt.intValue = EditorGUILayout.IntField("My Custom Int", MyInt.intValue); //MyFloat.floatValue = EditorGUILayout.FloatField("My Custom Float", MyFloat.floatValue); //MyVect3.vector3Value = EditorGUILayout.Vector3Field("My Custom Vector 3", MyVect3.vector3Value); // Array fields with remove at index EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Array Fields"); if (GUILayout.Button("Add New Index", GUILayout.MaxWidth(130), GUILayout.MaxHeight(20))) { MyArray.InsertArrayElementAtIndex(MyArray.arraySize); MyArray.GetArrayElementAtIndex(MyArray.arraySize - 1).intValue = 0; } for (int a = 0; a < MyArray.arraySize; a++) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("My Custom Int (" + a.ToString() + ")", GUILayout.MaxWidth(120)); MyArray.GetArrayElementAtIndex(a).intValue = EditorGUILayout.IntField("", MyArray.GetArrayElementAtIndex(a).intValue, GUILayout.MaxWidth(100)); if (GUILayout.Button("-", GUILayout.MaxWidth(15), GUILayout.MaxHeight(15))) { MyArray.DeleteArrayElementAtIndex(a); } EditorGUILayout.EndHorizontal(); } } EditorGUILayout.Space(); //Remove this index from the List EditorGUILayout.LabelField("Remove an index from the List<> with a button"); if (GUILayout.Button("Remove This Index (" + i.ToString() + ")")) { ThisList.DeleteArrayElementAtIndex(i); } EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Space(); } } t.SortByTime(); //Apply the changes to our list GetTarget.ApplyModifiedProperties(); }
static void CompileFileHTML() { string folderPath = GameObject.FindWithTag("ImageTarget").GetComponent <ImageTarget>().destination; if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } if (!File.Exists("Assets/AR.js-master/aframe/fullscreen.png")) { File.Copy("Assets/ARjs_Unity/Icons/fullscreen.png", "Assets/AR.js-master/aframe/fullscreen.png"); } if (!File.Exists("Assets/AR.js-master/aframe/exit_fullscreen.png")) { File.Copy("Assets/ARjs_Unity/Icons/exit_fullscreen.png", "Assets/AR.js-master/aframe/exit_fullscreen.png"); } string fileName = "index.html"; bool hasVideo = false; #region HTML Strings string aframeString = "<script src=\"https://aframe.io/releases/0.9.2/aframe.min.js\"></script>"; string topHTML = $"<!DOCTYPE html>\n<!-- include aframe -->\n{aframeString}\n<!-- include ar.js -->\n<script src=\"https://cdn.rawgit.com/jeromeetienne/AR.js/1.7.2/aframe/build/aframe-ar.js\"></script>\n\n<!-- to load .ply model -->\n<script src=\"https://rawgit.com/donmccurdy/aframe-extras/v6.0.0/dist/aframe-extras.loaders.min.js\"></script>\n\n"; string bodyHtml = @"<body style='margin : 0px; overflow: hidden; font-family: Monospace;'>"; string middleHTML = @"<!-- <a-scene embedded arjs='debugUIEnabled: false; sourceType: video; sourceUrl:../../data/videos/headtracking.mp4;'> --> <a-scene embedded arjs='debugUIEnabled: false; sourceType: webcam' vr-mode-ui='enabled: false'> <a-entity id=""mouseCursor"" cursor=""rayOrigin: mouse"" raycaster=""objects: .intersectable; useWorldCoordinates: true;""></a-entity>"; string buttonHTML = "<div style='position: absolute; bottom: 10px; right: 30px; width:100%; text-align: center; z-index: 1;'>\n <button id=\"mutebutton\" style='position: absolute; bottom: 10px'>\n Unmute\n </button>\n </div>"; string fullscreenButtonHTML = "<div style='position: absolute; bottom: 5px; left: 30px; width:100%; text-align: right; z-index: 1;'>\n <input type=\"image\" id=\"fullscreen\" src=\"../fullscreen.png\" style='position: absolute; bottom: 0px; right: 35px;'>\n </input>\n </div>"; string fullscreenButtonActionHTML = "fullbutton.addEventListener(\"click\", function (evt) {\n if (fullscreen == 0) {\n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n } else if (elem.mozRequestFullScreen) {\n /* Firefox */\n elem.mozRequestFullScreen();\n } else if (elem.webkitRequestFullscreen) {\n /* Chrome, Safari and Opera */\n elem.webkitRequestFullscreen();\n } else if (elem.msRequestFullscreen) {\n /* IE/Edge */\n elem.msRequestFullscreen();\n }\n fullbutton.setAttribute(\"src\", \"../exit_fullscreen.png\");\n fullscreen = 1;\n } else {\n if (document.exitFullscreen) {\n document.exitFullscreen();\n } else if (document.webkitExitFullscreen) {\n document.webkitExitFullscreen();\n } else if (document.mozCancelFullScreen) {\n document.mozCancelFullScreen();\n } else if (document.msExitFullscreen) {\n document.msExitFullscreen();\n }\n fullbutton.setAttribute(\"src\", \"../fullscreen.png\");\n fullscreen = 0;\n }\n\n });"; string patternName = GameObject.FindWithTag("ImageTarget").GetComponent <ImageTarget>().patternName; string presetText = $"preset=\"hiro\" emitevents=\"true\" button"; if (patternName != "default") { presetText = $"type=\"pattern\" preset=\"custom\" src=\"{patternName}\" url=\"{patternName}\" emitevents=\"true\" button"; } string markerHTML = "<a-marker id=\"marker\" " + presetText + ">"; string bottomHTML = @"</a-marker> <a-entity camera></a-entity> </a-scene> </body> </html>"; #endregion StringBuilder sb = new StringBuilder(); #region Top HTML sb.AppendLine("<!-- BEGIN: Top HTML -->"); sb.Append(topHTML); sb.AppendLine("<!-- END: Top HTML -->"); #endregion Top HTML Transform imageTarget = GameObject.FindGameObjectWithTag("ImageTarget").transform; if (imageTarget == null) { Debug.Log("AR.js error: There is no Image Target to Compile"); return; } #region Unity Compiled Events //Adds in the actions of the children to javascript. sb.AppendLine("<!-- BEGIN: Unity Compiled Events -->"); sb.AppendLine("<script>"); //GLOBALS FOR ANIMATION UPDATE sb.AppendLine("var markerFound = 0;"); bool hasBezier = false; for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; for (int j = 0; j < childToAdd.transform.childCount; j++) { if (childToAdd.transform.GetChild(j).name.ToLower().Contains("bezier")) { hasBezier = true; } } } if (hasBezier) { //sb.AppendLine("var subtractTime = 0;"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string childID = childToAdd.name + "_" + i; Bezier bez = childToAdd.GetComponentInChildren <Bezier>(); if (bez != null) { sb.AppendLine("var " + childID + "_CurrentPoint = 0;"); sb.AppendLine("var " + childID + "_SubtractTime = 0;"); sb.AppendLine("var " + childID + "_PointsArray = " + bez.PointsListString() + ";"); } } } //END GLOBALS FOR ANIMATION UPDATE sb.AppendLine("AFRAME.registerComponent('button', {"); sb.AppendLine("init: function () {"); sb.AppendLine($"var elem = document.documentElement;"); sb.AppendLine($"var marker = document.querySelector(\"#marker\");"); sb.AppendLine($"var fullbutton = document.querySelector(\"#fullscreen\");"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; if (childToAdd.tag == "Video") { hasVideo = true; } } if (hasVideo) { sb.AppendLine($"var button = document.querySelector(\"#mutebutton\");"); } for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; if (childToAdd.GetComponent <ButtonHelper>() != null) { sb.AppendLine($"var {id} = document.querySelector(\"#{id}\");"); } if (childToAdd.tag == "Video") { hasVideo = true; sb.AppendLine($"var {id} = document.querySelector(\"#{childToAdd.name + "_Asset_" + i}\");"); } } //marker event listeners sb.AppendLine("marker.addEventListener(\"markerFound\", function (evt) {"); sb.AppendLine("markerFound = 1;"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; if (childToAdd.tag == "Video") { string lineToAppend = id + ".play();"; sb.AppendLine(lineToAppend); } } sb.AppendLine("});"); sb.AppendLine("marker.addEventListener(\"markerLost\", function (evt) {"); sb.AppendLine("markerFound = 0;"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; if (childToAdd.tag == "Video") { string lineToAppend = id + ".pause();"; sb.AppendLine(lineToAppend); } } sb.AppendLine("});"); //end marker event listeners for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; if (childToAdd.GetComponent <ButtonHelper>() != null) { sb.AppendLine(@"open(""" + childToAdd.GetComponent <ButtonHelper>().URL + @""");"); sb.AppendLine(id + @".addEventListener(""mousedown"", function(evt){"); sb.AppendLine("});"); } if (childToAdd.tag == "Video") { //string lineToAppend = "marker.addEventListener(\"markerFound\", function (evt) {\n" + //id + ".play();\n" + //"});\n" + //"marker.addEventListener(\"markerLost\", function (evt) {\n" + //id + ".pause();\n" + //"});"; string secondLine = "button.addEventListener(\"click\", function(evt){\n" + "console.log(\"button clicked\")\n" + "if(" + id + ".muted==true){\n" + "button.innerHTML=\"Mute\";\n" + id + ".muted=false;\n" + "}else{\n" + "button.innerHTML=\"Unmute\";\n" + id + ".muted=true;\n" + "}\n" + "});"; //sb.AppendLine(lineToAppend); sb.AppendLine(secondLine); } } //end marker event listeners sb.AppendLine(fullscreenButtonActionHTML); sb.AppendLine("},"); //BEGIN: Tick function for bezier animations sb.AppendLine("tick: function (totalTime, deltaTime) {"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; Bezier bez = childToAdd.GetComponentInChildren <Bezier>(); if (bez != null) { sb.AppendLine($"var {id} = document.querySelector(\"#{id}\");"); sb.AppendLine($"var {id}_Speed = {bez.speed/60};"); sb.AppendLine($"var {id}_Time = (totalTime - {id}_SubtractTime) / 1000;"); } } //sb.AppendLine("var time = (totalTime - subtractTime) / 1000;"); sb.AppendLine("var dTime = deltaTime / 1000;"); sb.AppendLine(""); sb.AppendLine("if (markerFound == 1) {"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; Bezier bez = childToAdd.GetComponentInChildren <Bezier>(); if (bez != null) { sb.AppendLine($"{id}_Update();"); } } sb.AppendLine("}"); sb.AppendLine(); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; string id = childToAdd.name + "_" + i; Bezier bez = childToAdd.GetComponentInChildren <Bezier>(); if (bez != null) { sb.AppendLine($"function {id}_Update()" + " {"); sb.AppendLine($"var newPosition = bezierPath({id}_PointsArray[{id}_CurrentPoint], {id}_PointsArray[{id}_CurrentPoint + 1], { id}_PointsArray[{ id}_CurrentPoint + 2], { id}_PointsArray[{ id}_CurrentPoint + 3], {id}_Time *{ id}_Speed);"); sb.AppendLine(); sb.AppendLine($"if ({id}_Time*{id}_Speed>1) " + "{"); sb.AppendLine($"{id}_CurrentPoint += 3;"); sb.AppendLine($"{id}_SubtractTime = totalTime;"); sb.AppendLine($"if ({id}_CurrentPoint >= {id}_PointsArray.length - 3) " + "{"); sb.AppendLine($"{id}_CurrentPoint = 0;"); sb.AppendLine("}"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine($"{id}.setAttribute('position', " + "{"); sb.AppendLine("x: newPosition.x,"); sb.AppendLine("y: newPosition.y,"); sb.AppendLine("z: newPosition.z,"); sb.AppendLine("});"); sb.AppendLine("}"); } } sb.AppendLine("function bezierEvaluate(p0, p1, p2, p3, t) {\n " + "var u = (1 - t);\n " + "var uu = u * u;\n " + "var uuu = u * u * u;\n " + "var tt = t * t;\n " + "var ttt = t * t * t;\n " + "//B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3 , 0 < t < 1\n " + "return (uuu * p0 + 3 * uu * t * p1 + 3 * u * tt * p2 + ttt * p3);\n\n " + "}\n " + "function bezierPath(p0, p1, p2, p3, t) {\n " + "return new THREE.Vector3(\n " + "bezierEvaluate(p0.x, p1.x, p2.x, p3.x, t),\n " + "bezierEvaluate(p0.y, p1.y, p2.y, p3.y, t),\n " + "bezierEvaluate(p0.z, p1.z, p2.z, p3.z, t)\n " + ");\n " + "}\n\n " + "}"); //END: Tick function for bezier animations sb.AppendLine("});"); sb.AppendLine("</script>"); sb.AppendLine("<!-- END: Unity Compiled Events -->"); sb.AppendLine(""); #endregion Unity Compiled Events //MiddleHTML sb.AppendLine("<!-- BEGIN: Middle HTML -->"); sb.AppendLine(bodyHtml); if (hasVideo) { sb.AppendLine(buttonHTML); } sb.AppendLine(fullscreenButtonHTML); sb.AppendLine(middleHTML); sb.AppendLine("<!-- END: Middle HTML -->"); sb.AppendLine(""); #region Unity Compiled Assets sb.AppendLine("<!-- BEGIN: Unity Compiled Assets -->"); sb.AppendLine("<a-assets>"); for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; if (childToAdd.tag == "Video") { VideoPlayer player = childToAdd.GetComponentInChildren <VideoPlayer>(); string location = player.clip.originalPath; string[] splitName = location.Split('/'); string videoName = splitName[splitName.Length - 1]; string destination = folderPath + "videos/" + videoName; if (!Directory.Exists(folderPath + "videos/")) { Directory.CreateDirectory(folderPath + "videos/"); } if (File.Exists(destination)) { File.Delete(destination); } File.Copy(location, destination); sb.AppendLine($"<video id=\"{childToAdd.name + "_Asset_" + i}\" autoplay=\"false\" loop crossorigin=\"anonymous\" src=\"videos/{videoName}\" webkit-playsinline playsinline controls muted></video>"); } if (childToAdd.tag == "Model") { if (!Directory.Exists(folderPath + "models/")) { Directory.CreateDirectory(folderPath + "models/"); } CustomModelHelper modelHelper = childToAdd.GetComponent <CustomModelHelper>(); if (File.Exists(folderPath + "models/" + modelHelper.objName)) { sb.AppendLine($"<a-asset-item id=\"{childToAdd.name + "_Asset_obj_" + i}\" src=\"models/{modelHelper.objName}\"></a-asset-item>"); } else { Debug.LogError($"The model file {modelHelper.objName} doesn't seem to exist in the proper location."); } if (File.Exists(folderPath + "models/" + modelHelper.mtlName)) { sb.AppendLine($"<a-asset-item id=\"{childToAdd.name + "_Asset_mtl_" + i}\" src=\"models/{modelHelper.mtlName}\"></a-asset-item>"); } else { Debug.LogWarning("The object doesn't have a material."); } } } sb.AppendLine("</a-assets>"); sb.AppendLine("<!-- END: Unity Compiled Assets -->"); #endregion Unity Compiled Assets sb.AppendLine("<!-- BEGIN: Add Image Target (marker) -->"); sb.AppendLine(markerHTML); sb.AppendLine("<!-- END: Add Image Target (marker) -->"); sb.AppendLine(""); #region Unity Compiled Objects sb.AppendLine("<!-- BEGIN: Unity Compiled Objects -->"); //Adds in the physical object for each child of the ImageTarget for (int i = 0; i < imageTarget.childCount; i++) { GameObject childToAdd = imageTarget.GetChild(i).gameObject; Texture2D objectTexture = (Texture2D)childToAdd.GetComponentInChildren <MeshRenderer>().sharedMaterial.mainTexture; string textureName = null; bool transparency = false; if (objectTexture != null && childToAdd.tag != "Model") { textureName = objectTexture.name; byte[] bytes = objectTexture.EncodeToPNG(); if (!Directory.Exists(folderPath + "textures/")) { Directory.CreateDirectory(folderPath + "textures/"); } File.WriteAllBytes(folderPath + "textures/" + textureName + ".png", bytes); transparency = true; } switch (childToAdd.tag) { case "Plane": var Plane = (width : childToAdd.transform.localScale.x, height : childToAdd.transform.localScale.y, position : -childToAdd.transform.localPosition.x / 10 + " " + childToAdd.transform.localPosition.y / 10 + " " + childToAdd.transform.localPosition.z / 10, rotation : childToAdd.transform.localEulerAngles.x + " " + -childToAdd.transform.localEulerAngles.y + " " + -childToAdd.transform.localEulerAngles.z, color : "#" + ColorUtility.ToHtmlStringRGB(childToAdd.GetComponentInChildren <MeshRenderer>().sharedMaterial.color), src : textureName != null ? "textures/" + textureName + ".png" : ""); sb.AppendLine($"<a-plane src=\"{Plane.src}\" id=\"{childToAdd.name + "_" + i}\" class=\"intersectable\" width=\"{Plane.width}\" height=\"{Plane.height}\" position=\"{Plane.position}\" rotation=\"{Plane.rotation}\" color=\"{Plane.color}\" transparent={transparency}"); string planeID = childToAdd.name.ToLower() + "_" + i; if (childToAdd.GetComponent <AnimationHelper>() != null) { string animationFile = File.ReadAllText(Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + planeID + ".txt"); KeyFrameList keyList = JsonUtility.FromJson <KeyFrameList>(animationFile); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", widthFrom = "", heightFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {-prevFrame.posX / 10} {prevFrame.posY / 10} {prevFrame.posZ / 10};"; rotFrom = $"from: {prevFrame.rotX} {-prevFrame.rotY} {-prevFrame.rotZ};"; widthFrom = $"from: {prevFrame.scalX};"; heightFrom = $"from: {prevFrame.scalY};"; animTrigger = $"startEvents: animationcomplete__{planeID}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop)? $", animationcomplete__{planeID}_f{keyList.frameList.Count-1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {-frame.posX / 10} {frame.posY / 10} {frame.posZ / 10};", rotTo = $"to: {frame.rotX} {-frame.rotY} {-frame.rotZ};", widthTo = $"to: {frame.scalX};", heightTo = $"to: {frame.scalY};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{planeID}_f{index}=\" property: position; {posFrom} {posTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{planeID}_f{index}=\" property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentWidth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{planeID}_f{index}=\" property: width; {widthFrom} {widthTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentHeight(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{planeID}_f{index}=\" property: height; {heightFrom} {heightTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } } sb.AppendLine("></a-plane>"); break; case "Video": string videoID = childToAdd.name.ToLower() + "_" + i; var Video = (width: childToAdd.transform.localScale.x, height : childToAdd.transform.localScale.y, position : -childToAdd.transform.localPosition.x / 10 + " " + childToAdd.transform.localPosition.y / 10 + " " + childToAdd.transform.localPosition.z / 10, rotation : childToAdd.transform.localEulerAngles.x + " " + -childToAdd.transform.localEulerAngles.y + " " + -childToAdd.transform.localEulerAngles.z, color : "#" + ColorUtility.ToHtmlStringRGB(childToAdd.GetComponentInChildren <MeshRenderer>().sharedMaterial.color), src : "#" + childToAdd.name + "_Asset_" + i); sb.AppendLine($"<a-video src=\"{Video.src}\" id=\"{childToAdd.name + "_" + i}\" class=\"intersectable\" width=\"{Video.width}\" height=\"{Video.height}\" position=\"{Video.position}\" rotation=\"{Video.rotation}\" color=\"{Video.color}\" transparent={transparency}"); if (childToAdd.GetComponent <AnimationHelper>() != null) { string animationFile = File.ReadAllText(Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + videoID + ".txt"); KeyFrameList keyList = JsonUtility.FromJson <KeyFrameList>(animationFile); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", widthFrom = "", heightFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {-prevFrame.posX / 10} {prevFrame.posY / 10} {prevFrame.posZ / 10};"; rotFrom = $"from: {prevFrame.rotX} {-prevFrame.rotY} {-prevFrame.rotZ};"; widthFrom = $"from: {prevFrame.scalX};"; heightFrom = $"from: {prevFrame.scalY};"; animTrigger = $"startEvents: animationcomplete__{videoID}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop) ? $", animationcomplete__{videoID}_f{keyList.frameList.Count - 1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {-frame.posX / 10} {frame.posY / 10} {frame.posZ / 10};", rotTo = $"to: {frame.rotX} {-frame.rotY} {-frame.rotZ};", widthTo = $"to: {frame.scalX};", heightTo = $"to: {frame.scalY};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{videoID}_f{index}=\" property: position; {posFrom} {posTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{videoID}_f{index}=\" property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentWidth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{videoID}_f{index}=\" property: width; {widthFrom} {widthTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentHeight(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{videoID}_f{index}=\" property: height; {heightFrom} {heightTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } } sb.AppendLine("></a-video>"); break; case "Cube": var Cube = (width : childToAdd.transform.localScale.x / 10, height : childToAdd.transform.localScale.y / 10, depth : childToAdd.transform.localScale.z / 10, position : -childToAdd.transform.localPosition.x / 10 + " " + childToAdd.transform.localPosition.y / 10 + " " + childToAdd.transform.localPosition.z / 10, rotation : childToAdd.transform.localEulerAngles.x + " " + -childToAdd.transform.localEulerAngles.y + " " + -childToAdd.transform.localEulerAngles.z, color : "#" + ColorUtility.ToHtmlStringRGB(childToAdd.GetComponent <MeshRenderer>().sharedMaterial.color), src : textureName != null?"textures/" + textureName + ".png" : ""); sb.AppendLine($"<a-box src=\"{Cube.src}\" id=\"{childToAdd.name + "_" + i}\" class=\"intersectable\" width=\"{Cube.width}\" height=\"{Cube.height}\" depth=\"{Cube.depth}\" position=\"{Cube.position}\" rotation=\"{Cube.rotation}\" color=\"{Cube.color}\" transparent={transparency}"); string cubeID = childToAdd.name.ToLower() + "_" + i; if (childToAdd.GetComponent <AnimationHelper>() != null) { string animationFile = File.ReadAllText(Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + cubeID + ".txt"); KeyFrameList keyList = JsonUtility.FromJson <KeyFrameList>(animationFile); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", widthFrom = "", heightFrom = "", depthFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {-prevFrame.posX / 10} {prevFrame.posY / 10} {prevFrame.posZ / 10};"; rotFrom = $"from: {prevFrame.rotX} {-prevFrame.rotY} {-prevFrame.rotZ};"; widthFrom = $"from: {prevFrame.scalX / 10};"; heightFrom = $"from: {prevFrame.scalY / 10};"; depthFrom = $"from: {prevFrame.scalZ / 10};"; animTrigger = $"startEvents: animationcomplete__{cubeID}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop) ? $", animationcomplete__{cubeID}_f{keyList.frameList.Count - 1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {-frame.posX / 10} {frame.posY / 10} {frame.posZ / 10};", rotTo = $"to: {frame.rotX} {-frame.rotY} {-frame.rotZ};", widthTo = $"to: {frame.scalX / 10};", heightTo = $"to: {frame.scalY / 10};", depthTo = $"to: {frame.scalZ / 10};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cubeID}_f{index}=\"property: position; {posFrom} {posTo} dur: {(frame.time-prevFrame.time)*1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cubeID}_f{index}=\"property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentWidth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cubeID}_f{index}=\"property: width; {widthFrom} {widthTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentHeight(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cubeID}_f{index}=\"property: height; {heightFrom} {heightTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentDepth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cubeID}_f{index}=\"property: depth; {depthFrom} {depthTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } } sb.AppendLine("></a-box>"); break; case "Model": string modelID = childToAdd.name.ToLower() + "_" + i; var Model = (width: childToAdd.transform.localScale.x / 10, height : childToAdd.transform.localScale.y / 10, depth : childToAdd.transform.localScale.z / 10, position : -childToAdd.transform.localPosition.x / 10 + " " + childToAdd.transform.localPosition.y / 10 + " " + childToAdd.transform.localPosition.z / 10, rotation : childToAdd.transform.localEulerAngles.x + " " + -childToAdd.transform.localEulerAngles.y + " " + -childToAdd.transform.localEulerAngles.z, color : "#ffffff", src : textureName != null ? "textures/" + textureName + ".png" : ""); sb.AppendLine($"<a-entity obj-model=\"obj: #{childToAdd.name + "_Asset_obj_" + i}; mtl: #{childToAdd.name + "_Asset_mtl_" + i}\" id=\"{childToAdd.name + "_" + i}\" class=\"intersectable\" scale=\"{Model.width} {Model.height} {Model.depth}\" position=\"{Model.position}\" rotation=\"{Model.rotation}\" color=\"{Model.color}\" transparent={transparency}"); if (childToAdd.GetComponent <AnimationHelper>() != null) { string animationFile = File.ReadAllText(Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + modelID + ".txt"); KeyFrameList keyList = JsonUtility.FromJson <KeyFrameList>(animationFile); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", scaleFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {-prevFrame.posX / 10} {prevFrame.posY / 10} {prevFrame.posZ / 10};"; rotFrom = $"from: {prevFrame.rotX} {-prevFrame.rotY} {-prevFrame.rotZ};"; scaleFrom = $"from: {prevFrame.scalX / 10} {prevFrame.scalY / 10} {prevFrame.scalZ / 10};"; animTrigger = $"startEvents: animationcomplete__{modelID}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop) ? $", animationcomplete__{modelID}_f{keyList.frameList.Count - 1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {-frame.posX / 10} {frame.posY / 10} {frame.posZ / 10};", rotTo = $"to: {frame.rotX} {-frame.rotY} {-frame.rotZ};", scaleTo = $"to: {frame.scalX / 10} {frame.scalY / 10} {frame.scalZ / 10};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{modelID}_f{index}=\" property: position; {posFrom} {posTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{modelID}_f{index}=\" property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentWidth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{modelID}_f{index}=\" property: scale; {scaleFrom} {scaleTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } } sb.AppendLine("></a-entity>"); break; case "Sphere": var Sphere = (radius: childToAdd.transform.localScale.x / 20, position : -childToAdd.transform.localPosition.x / 10 + " " + childToAdd.transform.localPosition.y / 10 + " " + childToAdd.transform.localPosition.z / 10, rotation : childToAdd.transform.localEulerAngles.x + " " + -childToAdd.transform.localEulerAngles.y + " " + -childToAdd.transform.localEulerAngles.z, color : "#" + ColorUtility.ToHtmlStringRGB(childToAdd.GetComponent <MeshRenderer>().sharedMaterial.color), src : textureName != null ? "textures/" + textureName + ".png" : ""); Debug.Log(Sphere.src); sb.AppendLine($"<a-sphere src=\"{Sphere.src}\" id=\"{childToAdd.name + "_" + i}\" class=\"intersectable\" radius=\"{Sphere.radius}\" position=\"{Sphere.position}\" rotation=\"{Sphere.rotation}\" color=\"{Sphere.color}\" transparent={transparency}"); string shpereID = childToAdd.name.ToLower() + "_" + i; if (childToAdd.GetComponent <AnimationHelper>() != null) { string animationFile = File.ReadAllText(Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + shpereID + ".txt"); KeyFrameList keyList = JsonUtility.FromJson <KeyFrameList>(animationFile); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", radiusFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {-prevFrame.posX / 10} {prevFrame.posY / 10} {prevFrame.posZ / 10};"; rotFrom = $"from: {prevFrame.rotX} {-prevFrame.rotY} {-prevFrame.rotZ};"; radiusFrom = $"from: {prevFrame.scalX / 20};"; animTrigger = $"startEvents: animationcomplete__{shpereID}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop) ? $", animationcomplete__{shpereID}_f{keyList.frameList.Count - 1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {-frame.posX / 10} {frame.posY / 10} {frame.posZ / 10};", rotTo = $"to: {frame.rotX} {-frame.rotY} {-frame.rotZ};", radiusTo = $"to: {frame.scalX / 20};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{shpereID}_f{index}= \"property: position; {posFrom} {posTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{shpereID}_f{index}= \"property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentWidth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{shpereID}_f{index}= \"property: radius; {radiusFrom} {radiusTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } } sb.AppendLine("></a-sphere>"); break; case "Cylinder": var Cylinder = (radius: (childToAdd.transform.localScale.x + childToAdd.transform.localScale.z) / 40, height : childToAdd.transform.localScale.y / 5, position : -childToAdd.transform.localPosition.x / 10 + " " + childToAdd.transform.localPosition.y / 10 + " " + childToAdd.transform.localPosition.z / 10, rotation : childToAdd.transform.localEulerAngles.x + " " + -childToAdd.transform.localEulerAngles.y + " " + -childToAdd.transform.localEulerAngles.z, color : "#" + ColorUtility.ToHtmlStringRGB(childToAdd.GetComponent <MeshRenderer>().sharedMaterial.color), src : textureName != null ? "textures/" + textureName + ".png" : ""); Debug.Log(Cylinder.src); sb.AppendLine($"<a-cylinder src=\"{Cylinder.src}\" id=\"{childToAdd.name + "_" + i}\" class=\"intersectable\" radius=\"{Cylinder.radius}\" height=\"{Cylinder.height}\" position=\"{Cylinder.position}\" rotation=\"{Cylinder.rotation}\" color=\"{Cylinder.color}\" transparent={transparency}"); string cylinderID = childToAdd.name.ToLower() + "_" + i; if (childToAdd.GetComponent <AnimationHelper>() != null) { string animationFile = File.ReadAllText(Application.dataPath + "/Animations/JsonExports/" + SceneManager.GetActiveScene().name + "/" + cylinderID + ".txt"); KeyFrameList keyList = JsonUtility.FromJson <KeyFrameList>(animationFile); foreach (WeldonKeyFrame frame in keyList.frameList) { int index = keyList.frameList.FindIndex(obj => obj == frame); string loopTrueString = ""; string animTrigger = ""; string posFrom = "", rotFrom = "", radiusFrom = "", heightFrom = ""; WeldonKeyFrame prevFrame = new WeldonKeyFrame(); if (index > 0) { prevFrame = keyList.frameList[index - 1]; posFrom = $"from: {-prevFrame.posX / 10} {prevFrame.posY / 10} {prevFrame.posZ / 10};"; rotFrom = $"from: {prevFrame.rotX} {-prevFrame.rotY} {-prevFrame.rotZ};"; radiusFrom = $"from: {(prevFrame.scalX + prevFrame.scalZ) / 40};"; heightFrom = $"from: {prevFrame.scalY / 5};"; animTrigger = $"startEvents: animationcomplete__{cylinderID}_f{index-1}" + ((index == 1 && childToAdd.GetComponent <AnimationHelper>().loop) ? $", animationcomplete__{cylinderID}_f{keyList.frameList.Count - 1};" : ";"); } else { if (childToAdd.GetComponent <AnimationHelper>().onClick) { animTrigger = $"startEvents: mousedown;"; } } string posTo = $"to: {-frame.posX / 10} {frame.posY / 10} {frame.posZ / 10};", rotTo = $"to: {frame.rotX} {-frame.rotY} {-frame.rotZ};", radiusTo = $"to: {(frame.scalX + frame.scalZ) / 40};", heightTo = $"to: {frame.scalY / 5};"; //if (childToAdd.GetComponent<AnimationHelper>().loop) loopTrueString = $"repeat = \"indefinite\""; bool isFirstFrame = prevFrame.time.Equals(-1) ? true : false; if (isFirstFrame) { prevFrame.time = 0; } if (frame.IsDifferentPosition(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cylinderID}_f{index}=\" property: position; {posFrom} {posTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentRotation(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cylinderID}_f{index}=\" property: rotation; {rotFrom} {rotTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentWidth(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cylinderID}_f{index}=\" property: radius; {radiusFrom} {radiusTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } if (frame.IsDifferentHeight(prevFrame) || isFirstFrame) { sb.AppendLine($"animation__{cylinderID}_f{index}=\" property: height; {heightFrom} {heightTo} dur: {(frame.time - prevFrame.time) * 1000}; easing: linear; {animTrigger}\""); } } } sb.AppendLine("></a-cylinder>"); break; default: break; } } sb.AppendLine("<!-- END: Unity Compiled Objects -->"); #endregion Unity Compiled Objects sb.AppendLine(""); sb.AppendLine("<!-- BEGIN: Bottom HTML -->"); sb.Append(bottomHTML); sb.AppendLine("<!-- END: Bottom HTML -->"); File.WriteAllText(folderPath + fileName, sb.ToString()); Debug.Log("index file successfully created"); AssetDatabase.Refresh(); }