private void openToolStripMenuItem_Click(object sender, EventArgs e) { robotViewer1 = new RobotViewer(); FolderBrowserDialog browser = new FolderBrowserDialog(); if (browser.ShowDialog() == DialogResult.OK && browser.SelectedPath != null) { RigidNode_Base node = BXDJSkeleton.ReadSkeleton(browser.SelectedPath + @"\skeleton.bxdj"); List <RigidNode_Base> nodes = node.ListAllNodes(); List <BXDAMesh> meshes = new List <BXDAMesh>(); foreach (RigidNode_Base n in nodes) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(browser.SelectedPath + "\\" + n.ModelFileName); if (!n.GUID.Equals(mesh.GUID)) { MessageBox.Show(n.ModelFileName + " has been modified.", "Could not load mesh."); } meshes.Add(mesh); } robotViewer1.LoadModel(node, meshes); robotViewer1.FixLimits(); robotViewer1.HighlightAll(); Text = "Robot Viewer: " + browser.SelectedPath.Split(new char[] { '\\' }, System.StringSplitOptions.RemoveEmptyEntries)[browser.SelectedPath.Split(new char[] { '\\' }, System.StringSplitOptions.RemoveEmptyEntries).Length - 1]; } }
/// <summary> /// Creates a Soft body from a .bxda file [NOT YET PROPERLY IMPLEMENTED?] /// </summary> /// <param name="filePath"></param> /// <param name="worldInfo"></param> public void CreateSoftBody(string filePath, SoftBodyWorldInfo worldInfo) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath); List <Vector3> verts = new List <Vector3>(); //Soft body construction verts = mesh.AllColliderVertices().ToList(); SoftBody temp = SoftBodyHelpers.CreateFromConvexHull(worldInfo, verts.ToArray()); //BulletObject = temp; }
/// <summary> /// Open a previously exported robot. /// </summary> /// <param name="validate">If it is not null, this will validate the open inventor assembly.</param> public void OpenExisting() { if (SkeletonBase != null && !WarnUnsaved()) { return; } string dirPath = OpenFolderPath(); if (dirPath == null) { return; } try { List <RigidNode_Base> nodes = new List <RigidNode_Base>(); SkeletonBase = BXDJSkeleton.ReadSkeleton(dirPath + "\\skeleton.bxdj"); SkeletonBase.ListAllNodes(nodes); Meshes = new List <BXDAMesh>(); foreach (RigidNode_Base n in nodes) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(dirPath + "\\" + n.ModelFileName); if (!n.GUID.Equals(mesh.GUID)) { MessageBox.Show(n.ModelFileName + " has been modified.", "Could not load mesh."); return; } Meshes.Add(mesh); } for (int i = 0; i < Meshes.Count; i++) { ((OGL_RigidNode)nodes[i]).loadMeshes(Meshes[i]); } } catch (Exception e) { MessageBox.Show(e.ToString()); } ReloadPanels(); }
private void StandaloneViewerForm_Shown(object sender, EventArgs e) { RigidNode_Base node = BXDJSkeleton.ReadSkeleton(LaunchParams.Path + @"\skeleton.bxdj"); List <RigidNode_Base> nodes = node.ListAllNodes(); List <BXDAMesh> meshes = new List <BXDAMesh>(); foreach (RigidNode_Base n in nodes) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(LaunchParams.Path + "\\" + n.ModelFileName); if (!n.GUID.Equals(mesh.GUID)) { MessageBox.Show(n.ModelFileName + " has been modified.", "Could not load mesh."); } meshes.Add(mesh); } robotViewer1.LoadModel(node, meshes); robotViewer1.FixLimits(); robotViewer1.HighlightAll(); }
/// <summary> /// Open a previously exported robot. /// </summary> /// <param name="validate">If it is not null, this will validate the open inventor assembly.</param> public bool OpenExisting(ValidationAction validate, bool warnUnsaved = false) { if (SkeletonBase != null && warnUnsaved && !WarnUnsaved()) { return(false); } string dirPath = OpenFolderPath(); if (dirPath == null) { return(false); } try { List <RigidNode_Base> nodes = new List <RigidNode_Base>(); SkeletonBase = BXDJSkeleton.ReadSkeleton(dirPath + "\\skeleton.bxdj"); if (validate != null) { if (!validate(SkeletonBase, out string message)) { while (true) { DialogResult result = MessageBox.Show(message, "Assembly Validation", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); if (result == DialogResult.Retry) { continue; } if (result == DialogResult.Abort) { return(false); } break; } } #region DEBUG #if DEBUG else { MessageBox.Show(message); } #endif #endregion } SkeletonBase.ListAllNodes(nodes); Meshes = new List <BXDAMesh>(); foreach (RigidNode_Base n in nodes) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(dirPath + "\\" + n.ModelFileName); if (!n.GUID.Equals(mesh.GUID)) { MessageBox.Show(n.ModelFileName + " has been modified.", "Could not load mesh."); return(false); } Meshes.Add(mesh); } } catch (Exception e) { MessageBox.Show(e.ToString()); } RMeta.UseSettingsDir = false; RMeta.ActiveDir = dirPath; RMeta.ActiveRobotName = dirPath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Last(); ReloadPanels(); return(true); }
public bool CreateMesh(string filePath) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath, null); if (!mesh.GUID.Equals(GUID)) { return(false); } List <FieldNode> remainingNodes = new List <FieldNode>(NodeGroup.EnumerateAllLeafFieldNodes()); List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > submeshes = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >(); List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > colliders = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >(); // Create all submesh objects AuxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { submeshes.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu)); }); // Create all collider objects AuxFunctions.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { colliders.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu)); }); foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes()) { GameObject subObject = new GameObject(node.NodeID); subObject.transform.parent = unityObject.transform; GameObject meshObject = new GameObject(node.NodeID + "-mesh"); if (node.SubMeshID != -1) { KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = submeshes[node.SubMeshID]; BXDAMesh.BXDASubMesh sub = currentSubMesh.Key; Mesh meshu = currentSubMesh.Value; meshObject.AddComponent <MeshFilter>().mesh = meshu; meshObject.AddComponent <MeshRenderer>(); Material[] matls = new Material[meshu.subMeshCount]; for (int i = 0; i < matls.Length; i++) { matls[i] = sub.surfaces[i].AsMaterial(); } meshObject.GetComponent <MeshRenderer>().materials = matls; } // Invert the x-axis to compensate for Unity's inverted coordinate system. meshObject.transform.localScale = new Vector3(-1f, 1f, 1f); // Set the rotation of the object (the x and w properties are inverted to once again compensate for Unity's differences). meshObject.transform.localRotation = new Quaternion(-node.Rotation.X, node.Rotation.Y, node.Rotation.Z, -node.Rotation.W); // Set the position of the object (scaled by 1/100 to match Unity's scaling correctly). meshObject.transform.position = new Vector3(-node.Position.x * 0.01f, node.Position.y * 0.01f, node.Position.z * 0.01f); if (GetPropertySets().ContainsKey(node.PropertySetID)) { PropertySet currentPropertySet = GetPropertySets()[node.PropertySetID]; PropertySet.PropertySetCollider psCollider = currentPropertySet.Collider; switch (psCollider.CollisionType) { case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX: PropertySet.BoxCollider psBoxCollider = (PropertySet.BoxCollider)psCollider; BoxCollider dummyBoxCollider = meshObject.AddComponent <BoxCollider>(); subObject.transform.localRotation = meshObject.transform.localRotation; subObject.transform.position = meshObject.transform.TransformPoint(dummyBoxCollider.center); BBoxShape boxShape = subObject.AddComponent <BBoxShape>(); boxShape.Extents = new Vector3( dummyBoxCollider.size.x * 0.5f * psBoxCollider.Scale.x, dummyBoxCollider.size.y * 0.5f * psBoxCollider.Scale.y, dummyBoxCollider.size.z * 0.5f * psBoxCollider.Scale.z); //meshObject.AddComponent<MouseListener>(); UnityEngine.Object.Destroy(dummyBoxCollider); break; case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE: PropertySet.SphereCollider psSphereCollider = (PropertySet.SphereCollider)psCollider; SphereCollider dummySphereCollider = meshObject.AddComponent <SphereCollider>(); subObject.transform.position = meshObject.transform.TransformPoint(dummySphereCollider.center); BSphereShape sphereShape = subObject.AddComponent <BSphereShape>(); sphereShape.Radius = dummySphereCollider.radius * psSphereCollider.Scale; //meshObject.AddComponent<MouseListener>(); UnityEngine.Object.Destroy(dummySphereCollider); break; case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH: PropertySet.MeshCollider psMeshCollider = (PropertySet.MeshCollider)psCollider; if (psMeshCollider.Convex || currentPropertySet.Mass != 0) { MeshCollider dummyMeshCollider = subObject.AddComponent <MeshCollider>(); dummyMeshCollider.sharedMesh = meshObject.GetComponent <MeshFilter>().mesh; subObject.transform.position = meshObject.transform.TransformPoint(dummyMeshCollider.bounds.center); subObject.transform.rotation = meshObject.transform.rotation; BConvexHullShape hullshape = subObject.AddComponent <BConvexHullShape>(); hullshape.HullMesh = AuxFunctions.GenerateCollisionMesh(meshObject.GetComponent <MeshFilter>().mesh, dummyMeshCollider.sharedMesh.bounds.center); hullshape.GetCollisionShape().Margin = 0f; //subObject.AddComponent<MouseListener>(); UnityEngine.Object.Destroy(dummyMeshCollider); } else { subObject.transform.position = meshObject.transform.position; subObject.transform.rotation = meshObject.transform.rotation; BBvhTriangleMeshShape meshShape = subObject.AddComponent <BBvhTriangleMeshShape>(); meshShape.HullMesh = meshObject.GetComponent <MeshFilter>().mesh.GetScaledCopy(-1f, 1f, 1f); meshShape.GetCollisionShape().Margin = 0f; } // TODO: Find a way to implement embedded margins. See https://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=2358 break; } BRigidBody rb = subObject.AddComponent <BRigidBody>(); rb.friction = currentPropertySet.Friction * FRICTION_SCALE; rb.mass = currentPropertySet.Mass; if (currentPropertySet.Mass == 0) { rb.collisionFlags = BulletSharp.CollisionFlags.StaticObject; } else { subObject.AddComponent <Tracker>(); } meshObject.transform.parent = subObject.transform; } else { meshObject.transform.parent = unityObject.transform; } } #region Free mesh foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return(true); }
private void CreateMesh(string filePath) { Bodies = new List <RigidBody>(); VisualMeshes = new List <Mesh>(); BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath); foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes()) { if (!GetPropertySets().ContainsKey(node.PropertySetID)) { return; } PropertySet current = GetPropertySets()[node.PropertySetID]; CollisionShape subShape = null; switch (current.Collider.CollisionType) { case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX: { //Create a box shape //This is a mess, though I was told that this is how it works Vector3[] vertices = MeshUtilities.DataToVector(mesh.meshes[node.SubMeshID].verts); StridingMeshInterface temp = MeshUtilities.BulletShapeFromSubMesh(mesh.meshes[node.SubMeshID]); Vector3 min, max; temp.CalculateAabbBruteForce(out min, out max); PropertySet.BoxCollider colliderInfo = (PropertySet.BoxCollider)current.Collider; subShape = new BoxShape((max - min) * colliderInfo.Scale.Convert() * 0.5f); if (debug) { Console.WriteLine("Created Box"); } break; } case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE: { //Create a sphere shape PropertySet.SphereCollider colliderInfo = (PropertySet.SphereCollider)current.Collider; subShape = new SphereShape(colliderInfo.Scale); if (debug) { Console.WriteLine("Created Sphere"); } break; } case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH: { //Create a mesh shape if (node.CollisionMeshID == -1) { break; } PropertySet.MeshCollider colliderInfo = (PropertySet.MeshCollider)current.Collider; Vector3[] vertices = MeshUtilities.DataToVector(mesh.colliders[node.CollisionMeshID].verts); if (colliderInfo.Convex) { subShape = new ConvexHullShape(vertices); if (debug) { Console.WriteLine("Created Convex Mesh"); } } else { StridingMeshInterface sMesh = MeshUtilities.BulletShapeFromSubMesh(mesh.colliders[node.CollisionMeshID]); subShape = new ConvexTriangleMeshShape(sMesh, true); //still not really concave if (debug) { Console.WriteLine("Created Concave Mesh"); } } break; } } if (null == subShape) { return; } //set sub shape local position/rotation and add it to the compound shape Vector3 Translation = node.Position.Convert(); Quaternion rotation = node.Rotation.Convert(); DefaultMotionState motion = new DefaultMotionState(Matrix4.CreateFromQuaternion(rotation) * Matrix4.CreateTranslation(Translation)); motion.CenterOfMassOffset = Matrix4.CreateTranslation(mesh.physics.centerOfMass.Convert()); RigidBodyConstructionInfo info = new RigidBodyConstructionInfo(current.Mass, motion, subShape, subShape.CalculateLocalInertia(current.Mass)); info.Friction = current.Friction; Bodies.Add(new RigidBody(info)); VisualMeshes.Add(new Mesh(mesh.meshes[node.SubMeshID], Translation)); if (debug) { Console.WriteLine("Created " + node.PropertySetID); } } }
/* * public RigidNode(RigidNode_Base parent) : base(parent){ * * } */ public bool CreateMesh(string filePath, bool isMixAndMatch = false, float wheelMass = 1.0f) { //Debug.Log(filePath); BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath); //if (!mesh.GUID.Equals(GUID)) //{ // Debug.Log("Returning false"); // return false; //} List <GameObject> meshObjects = new List <GameObject>(); Auxiliary.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { GameObject meshObject = new GameObject(MainObject.name + "_mesh"); meshObjects.Add(meshObject); meshObject.AddComponent <MeshFilter>().mesh = meshu; meshObject.AddComponent <MeshRenderer>(); Material[] materials = new Material[meshu.subMeshCount]; for (int i = 0; i < materials.Length; i++) { materials[i] = sub.surfaces[i].AsMaterial(true); } meshObject.GetComponent <MeshRenderer>().materials = materials; meshObject.transform.position = root.position; meshObject.transform.rotation = root.rotation; }, true); Vector3 com = mesh.physics.centerOfMass.AsV3(); ComOffset = com; Mesh[] colliders = new Mesh[mesh.colliders.Count]; Auxiliary.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { colliders[id] = meshu; }, true); MainObject.transform.position = root.position + ComOffset; MainObject.transform.rotation = root.rotation; foreach (GameObject meshObject in meshObjects) { meshObject.transform.parent = MainObject.transform; } if (!this.HasDriverMeta <WheelDriverMeta>() || this.GetDriverMeta <WheelDriverMeta>().type == WheelType.NOT_A_WHEEL) { BMultiShape hullShape = MainObject.AddComponent <BMultiShape>(); foreach (Mesh collider in colliders) { //Mesh m = AuxFunctions.GenerateCollisionMesh(collider, Vector3.zero, 0f/*CollisionMargin*/); //ConvexHullShape hull = new ConvexHullShape(Array.ConvertAll(m.vertices, x => x.ToBullet()), m.vertices.Length); //hull.Margin = CollisionMargin; //hullShape.AddHullShape(hull, BulletSharp.Math.Matrix.Translation(-ComOffset.ToBullet())); MainObject.AddComponent <Wireframe>().Init(collider, ComOffset); ConvexHullShape hull = new ConvexHullShape(Array.ConvertAll(collider.vertices, x => x.ToBullet()), collider.vertices.Length); hull.Margin = CollisionMargin; hullShape.AddShape(hull, BulletSharp.Math.Matrix.Translation(-ComOffset.ToBullet())); } MainObject.AddComponent <MeshRenderer>(); PhysicalProperties = mesh.physics; //Debug.Log(PhysicalProperties.centerOfMass); BRigidBody rigidBody = MainObject.AddComponent <BRigidBody>(); string jsonFile = Directory.GetParent(filePath).FullName + Path.DirectorySeparatorChar + "skeleton.json"; bool useJsonWeight = false; if (File.Exists(jsonFile)) { useJsonWeight = true; } float weight = mesh.physics.mass; if (useJsonWeight) { try { weight = (float)GetSkeletalJoint().weight; } catch (Exception e) { weight = mesh.physics.mass; } } rigidBody.mass = weight; rigidBody.friction = 0.25f; rigidBody.linearSleepingThreshold = LinearSleepingThreshold; rigidBody.angularSleepingThreshold = AngularSleepingThreshold; rigidBody.RemoveOnCollisionCallbackEventHandler(); foreach (BRigidBody rb in MainObject.transform.parent.GetComponentsInChildren <BRigidBody>()) { rigidBody.GetCollisionObject().SetIgnoreCollisionCheck(rb.GetCollisionObject(), true); } MainState mainState = StateMachine.SceneGlobal.FindState <MainState>(); if (mainState != null) { MainObject.AddComponent <BMultiCallbacks>().AddCallback(mainState.CollisionTracker); } } if (this.HasDriverMeta <WheelDriverMeta>() && this.GetDriverMeta <WheelDriverMeta>().type != WheelType.NOT_A_WHEEL && GetParent() == null) { BRigidBody rigidBody = MainObject.GetComponent <BRigidBody>(); if (isMixAndMatch) { rigidBody.mass += wheelMass; } rigidBody.GetCollisionObject().CollisionShape.CalculateLocalInertia(rigidBody.mass); } #region Free mesh foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return(true); }
/// <summary> /// Initializes physical robot based off of robot directory. /// </summary> /// <param name="directory">folder directory of robot</param> /// <returns></returns> public bool InitializeRobot(string directory, MainState source) { #region Robot Initialization RobotDirectory = directory; //Deletes all nodes if any exist, take the old node transforms out from the robot object int childCount = transform.childCount; for (int i = childCount - 1; i >= 0; i--) { Transform child = transform.GetChild(i); //If this isn't done, the game object is destroyed but the parent-child transform relationship remains! child.parent = null; Destroy(child.gameObject); } //Detach and destroy all sensors on the original robot SensorManager sensorManager = GameObject.Find("SensorManager").GetComponent <SensorManager>(); sensorManager.ResetSensorLists(); //Removes Driver Practice component if it exists if (dpmRobot != null) { Destroy(dpmRobot); } mainState = source; //stores the main state object transform.position = robotStartPosition; //Sets the position of the object to the set spawn point if (!File.Exists(directory + "\\skeleton.bxdj")) { return(false); } //Loads the node and skeleton data RigidNode_Base.NODE_FACTORY = delegate(Guid guid) { return(new RigidNode(guid)); }; List <RigidNode_Base> nodes = new List <RigidNode_Base>(); rootNode = BXDJSkeleton.ReadSkeleton(directory + "\\skeleton.bxdj"); rootNode.ListAllNodes(nodes); //Initializes the wheel variables int numWheels = nodes.Count(x => x.HasDriverMeta <WheelDriverMeta>() && x.GetDriverMeta <WheelDriverMeta>().type != WheelType.NOT_A_WHEEL); float collectiveMass = 0f; int isMixAndMatch = PlayerPrefs.GetInt("mixAndMatch"); if (isMixAndMatch == 1 && !MixAndMatchMode.isMecanum) { //Load Node_0 RigidNode node = (RigidNode)nodes[0]; node.CreateTransform(transform); if (!node.CreateMesh(directory + "\\" + node.ModelFileName)) { Debug.Log("Robot not loaded!"); return(false); } node.CreateJoint(numWheels); if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } //Load the other nodes (wheels) string wheelDirectory = PlayerPrefs.GetString("simSelectedWheel"); BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(wheelDirectory + "\\node_0.bxda"); List <Mesh> meshList = new List <Mesh>(); List <Material[]> materialList = new List <Material[]>(); RigidNode wheelNode = (RigidNode)BXDJSkeleton.ReadSkeleton(wheelDirectory + "\\skeleton.bxdj"); Material[] materials = new Material[0]; AuxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { meshList.Add(meshu); materials = new Material[meshu.subMeshCount]; for (int i = 0; i < materials.Length; i++) { materials[i] = sub.surfaces[i].AsMaterial(true); } materialList.Add(materials); //meshObject.GetComponent<MeshRenderer>().materials = materials; }, true); for (int i = 1; i < nodes.Count; i++) { node = (RigidNode)nodes[i]; node.CreateTransform(transform); if (!node.CreateMesh(directory + "\\" + node.ModelFileName)) { Debug.Log("Robot not loaded!"); return(false); } if (node.HasDriverMeta <WheelDriverMeta>()) { int chldCount = node.MainObject.transform.childCount; for (int j = 0; j < chldCount; j++) { Destroy(node.MainObject.transform.GetChild(j).gameObject); } int k = 0; foreach (Mesh meshObject in meshList) { Debug.Log("Mesh Object" + meshObject); GameObject meshObj = new GameObject(node.MainObject.name + "_mesh"); meshObj.transform.parent = node.MainObject.transform; meshObj.AddComponent <MeshFilter>().mesh = meshObject; meshObj.transform.localPosition = -meshObject.bounds.center; //Take out this line if you want some snazzy pink wheels meshObj.AddComponent <MeshRenderer>().materials = materialList[k]; k++; } node.MainObject.GetComponentInChildren <MeshRenderer>().materials = materials; } //node.MainObject.transform.GetChild(0).localPosition = -node.MainObject.GetComponentInChildren<MeshFilter>().mesh.bounds.center;// -node.MainObject.transform.localPosition; //Bounds b = node.MainObject.GetComponentInChildren<MeshFilter>().mesh.bounds; // Debug.Log(b.center); //b.center = node.MainObject.transform.position; //node.MainObject.GetComponentInChildren<MeshFilter>().mesh.bounds = b; node.CreateJoint(numWheels); if (node.HasDriverMeta <WheelDriverMeta>()) { float radius = PlayerPrefs.GetFloat("wheelRadius"); node.MainObject.GetComponent <BRaycastWheel>().Radius = radius; } if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } } } else { //Initializes the nodes foreach (RigidNode_Base n in nodes) { RigidNode node = (RigidNode)n; node.CreateTransform(transform); if (!node.CreateMesh(directory + "\\" + node.ModelFileName)) { Debug.Log("Robot not loaded!"); return(false); } node.CreateJoint(numWheels); if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } } } #endregion //Get the offset from the first node to the robot for new robot start position calculation //This line is CRITICAL to new reset position accuracy! DON'T DELETE IT! nodeToRobotOffset = gameObject.transform.GetChild(0).localPosition - robotStartPosition; foreach (BRaycastRobot r in GetComponentsInChildren <BRaycastRobot>()) { r.RaycastRobot.OverrideMass = collectiveMass; r.RaycastRobot.RootRigidBody = (RigidBody)((RigidNode)nodes[0]).MainObject.GetComponent <BRigidBody>().GetCollisionObject(); } RotateRobot(robotStartOrientation); RobotName = new DirectoryInfo(directory).Name; isInitialized = true; //Initializes Driver Practice component dpmRobot = gameObject.AddComponent <DriverPracticeRobot>(); dpmRobot.Initialize(directory); //Initializing robot cameras bool hasRobotCamera = false; //If you are getting an error referencing this line, it is likely that the Game Object "RobotCameraList" in Scene.unity does not have the RobotCameraManager script attached to it. robotCameraManager = GameObject.Find("RobotCameraList").GetComponent <RobotCameraManager>(); //Loop through robotCameraList and check if any existing camera should attach to this robot foreach (GameObject robotCamera in robotCameraManager.GetRobotCameraList()) { if (robotCamera.GetComponent <RobotCamera>().robot.Equals(this)) { //Recover the robot camera configurations robotCamera.GetComponent <RobotCamera>().RecoverConfiguration(); hasRobotCamera = true; } } //Add new cameras to the robot if there is none robot camera belong to the current robot (which means it is a new robot) if (!hasRobotCamera) { //Attached to the main frame and face the front robotCameraManager.AddCamera(this, transform.GetChild(0).transform); //Attached to the first node and face the front if (transform.childCount > 1) { robotCameraManager.AddCamera(this, transform.GetChild(1).transform); } ////Attached to main frame and face the back robotCameraManager.AddCamera(this, transform.GetChild(0).transform, new Vector3(0, 0, 0), new Vector3(0, 180, 0)); } return(true); }
public bool CreateMesh(string filePath) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath); if (!mesh.GUID.Equals(GUID)) return false; List<GameObject> meshObjects = new List<GameObject>(); AuxFunctions.ReadMeshSet(mesh.meshes, delegate (int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { GameObject meshObject = new GameObject(MainObject.name + "_mesh"); meshObjects.Add(meshObject); meshObject.AddComponent<MeshFilter>().mesh = meshu; meshObject.AddComponent<MeshRenderer>(); Material[] materials = new Material[meshu.subMeshCount]; for (int i = 0; i < materials.Length; i++) materials[i] = sub.surfaces[i].AsMaterial(true); meshObject.GetComponent<MeshRenderer>().materials = materials; meshObject.transform.position = root.position; meshObject.transform.rotation = root.rotation; ComOffset = meshObject.transform.GetComponent<MeshFilter>().mesh.bounds.center; }); Mesh[] colliders = new Mesh[mesh.colliders.Count]; AuxFunctions.ReadMeshSet(mesh.colliders, delegate (int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { colliders[id] = meshu; }); MainObject.transform.position = root.position + ComOffset; MainObject.transform.rotation = root.rotation; foreach (GameObject meshObject in meshObjects) meshObject.transform.parent = MainObject.transform; if (this.HasDriverMeta<WheelDriverMeta>()) { CreateWheel(); } else { BMultiHullShape hullShape = MainObject.AddComponent<BMultiHullShape>(); foreach (Mesh collider in colliders) { ConvexHullShape hull = new ConvexHullShape(Array.ConvertAll(collider.vertices, x => x.ToBullet()), collider.vertices.Length); hull.Margin = 0f; hullShape.AddHullShape(hull, BulletSharp.Math.Matrix.Translation(-ComOffset.ToBullet())); } } physicalProperties = mesh.physics; BRigidBody rigidBody = MainObject.AddComponent<BRigidBody>(); rigidBody.mass = mesh.physics.mass; rigidBody.friction = 1f; if (this.HasDriverMeta<WheelDriverMeta>()) UpdateWheelRigidBody(); foreach (BRigidBody rb in MainObject.transform.parent.GetComponentsInChildren<BRigidBody>()) { rigidBody.GetCollisionObject().SetIgnoreCollisionCheck(rb.GetCollisionObject(), true); } if (this.HasDriverMeta<WheelDriverMeta>()) UpdateWheelMass(); // 'tis a wheel, so needs more mass for joints to work correctly. #region Free mesh foreach (var list in new List<BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return true; }
/// <summary> /// Initializes physical robot based off of robot directory. /// </summary> /// <param name="directory">folder directory of robot</param> /// <returns></returns> public bool InitializeRobot(string directory, MainState source) { RobotIsMecanum = false; if (RobotIsMixAndMatch) { wheelPath = RobotTypeManager.WheelPath; wheelFriction = RobotTypeManager.WheelFriction; wheelLateralFriction = RobotTypeManager.WheelLateralFriction; wheelRadius = RobotTypeManager.WheelRadius; wheelMass = RobotTypeManager.WheelMass; RobotIsMecanum = RobotTypeManager.IsMecanum; } #region Robot Initialization RobotDirectory = directory; //Deletes all nodes if any exist, take the old node transforms out from the robot object int childCount = transform.childCount; for (int i = childCount - 1; i >= 0; i--) { Transform child = transform.GetChild(i); //If this isn't done, the game object is destroyed but the parent-child transform relationship remains! child.parent = null; Destroy(child.gameObject); } //Detach and destroy all sensors on the original robot SensorManager sensorManager = GameObject.Find("SensorManager").GetComponent <SensorManager>(); sensorManager.ResetSensorLists(); //Removes Driver Practice component if it exists if (dpmRobot != null) { Destroy(dpmRobot); } mainState = source; //stores the main state object transform.position = robotStartPosition; //Sets the position of the object to the set spawn point if (!File.Exists(directory + "\\skeleton.bxdj")) { return(false); } //Loads the node and skeleton data RigidNode_Base.NODE_FACTORY = delegate(Guid guid) { return(new RigidNode(guid)); }; List <RigidNode_Base> nodes = new List <RigidNode_Base>(); rootNode = BXDJSkeleton.ReadSkeleton(directory + "\\skeleton.bxdj"); rootNode.ListAllNodes(nodes); //Initializes the wheel variables int numWheels = nodes.Count(x => x.HasDriverMeta <WheelDriverMeta>() && x.GetDriverMeta <WheelDriverMeta>().type != WheelType.NOT_A_WHEEL); float collectiveMass = 0f; //Initializes the nodes and creates joints for the robot if (RobotIsMixAndMatch && !RobotIsMecanum) //If the user is in MaM and the robot they select is not mecanum, create the nodes and replace the wheel meshes to match those selected { //Load Node_0, the base of the robot RigidNode node = (RigidNode)nodes[0]; node.CreateTransform(transform); if (!node.CreateMesh(directory + "\\" + node.ModelFileName, true, wheelMass)) { Debug.Log("Robot not loaded!"); return(false); } node.CreateJoint(numWheels, RobotIsMixAndMatch); if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } //Get the wheel mesh data from the file they are stored in. They are stored as .bxda files. This may need to update if exporters/file types change. BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(wheelPath + "\\node_0.bxda"); List <Mesh> meshList = new List <Mesh>(); List <Material[]> materialList = new List <Material[]>(); RigidNode wheelNode = (RigidNode)BXDJSkeleton.ReadSkeleton(wheelPath + "\\skeleton.bxdj"); Material[] materials = new Material[0]; AuxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { meshList.Add(meshu); materials = new Material[meshu.subMeshCount]; for (int i = 0; i < materials.Length; i++) { materials[i] = sub.surfaces[i].AsMaterial(true); } materialList.Add(materials); }, true); //Loads the other nodes from the original robot for (int i = 1; i < nodes.Count; i++) { node = (RigidNode)nodes[i]; node.CreateTransform(transform); if (!node.CreateMesh(directory + "\\" + node.ModelFileName, true, wheelMass)) { Debug.Log("Robot not loaded!"); return(false); } //If the node is a wheel, destroy the original wheel mesh and replace it with the wheels selected in MaM if (node.HasDriverMeta <WheelDriverMeta>()) { int chldCount = node.MainObject.transform.childCount; for (int j = 0; j < chldCount; j++) { Destroy(node.MainObject.transform.GetChild(j).gameObject); } int k = 0; Vector3?offset = null; foreach (Mesh meshObject in meshList) { GameObject meshObj = new GameObject(node.MainObject.name + "_mesh"); meshObj.transform.parent = node.MainObject.transform; meshObj.AddComponent <MeshFilter>().mesh = meshObject; if (!offset.HasValue) { offset = meshObject.bounds.center; } meshObj.transform.localPosition = -offset.Value; //Take out this line if you want some snazzy pink wheels meshObj.AddComponent <MeshRenderer>().materials = materialList[k]; k++; } node.MainObject.GetComponentInChildren <MeshRenderer>().materials = materials; } //Create the joints that interact with physics node.CreateJoint(numWheels, RobotIsMixAndMatch, wheelFriction, wheelLateralFriction); if (node.HasDriverMeta <WheelDriverMeta>()) { node.MainObject.GetComponent <BRaycastWheel>().Radius = wheelRadius; } if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } } } else //Initialize the robot as normal { //Initializes the nodes foreach (RigidNode_Base n in nodes) { RigidNode node = (RigidNode)n; node.CreateTransform(transform); if (!node.CreateMesh(directory + "\\" + node.ModelFileName)) { Debug.Log("Robot not loaded!"); return(false); } node.CreateJoint(numWheels, RobotIsMixAndMatch); if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } } } #endregion //Get the offset from the first node to the robot for new robot start position calculation //This line is CRITICAL to new reset position accuracy! DON'T DELETE IT! nodeToRobotOffset = gameObject.transform.GetChild(0).localPosition - robotStartPosition; foreach (BRaycastRobot r in GetComponentsInChildren <BRaycastRobot>()) { r.RaycastRobot.OverrideMass = collectiveMass; r.RaycastRobot.RootRigidBody = (RigidBody)((RigidNode)nodes[0]).MainObject.GetComponent <BRigidBody>().GetCollisionObject(); } RotateRobot(robotStartOrientation); RobotName = new DirectoryInfo(directory).Name; isInitialized = true; //Initializes Driver Practice component dpmRobot = gameObject.AddComponent <DriverPracticeRobot>(); dpmRobot.Initialize(directory); //Initializing robot cameras bool hasRobotCamera = false; //If you are getting an error referencing this line, it is likely that the Game Object "RobotCameraList" in Scene.unity does not have the RobotCameraManager script attached to it. robotCameraManager = GameObject.Find("RobotCameraList").GetComponent <RobotCameraManager>(); //Loop through robotCameraList and check if any existing camera should attach to this robot foreach (GameObject robotCamera in robotCameraManager.GetRobotCameraList()) { if (robotCamera.GetComponent <RobotCamera>().robot.Equals(this)) { //Recover the robot camera configurations robotCamera.GetComponent <RobotCamera>().RecoverConfiguration(); hasRobotCamera = true; } } //Add new cameras to the robot if there is none robot camera belong to the current robot (which means it is a new robot) if (!hasRobotCamera) { //Attached to the main frame and face the front robotCameraManager.AddCamera(this, transform.GetChild(0).transform, new Vector3(0, 0.5f, 0), new Vector3(0, 0, 0)); ////Attached to main frame and face the back robotCameraManager.AddCamera(this, transform.GetChild(0).transform, new Vector3(0, 0.5f, 0), new Vector3(0, 180, 0)); robotCameraManager.AddCamera(this, transform.GetChild(0).transform); } //Reads the offset position for the manipulator if (RobotIsMixAndMatch) { offset = Vector3.zero; try { using (TextReader reader = File.OpenText(directory + "\\position.txt")) { offset.x = float.Parse(reader.ReadLine()); offset.y = float.Parse(reader.ReadLine()); offset.z = float.Parse(reader.ReadLine()); } } catch { offset = Vector3.zero; } } return(true); }
/// <summary> /// Creates a Rigid Body from a .bxda file /// </summary> /// <param name="FilePath"></param> public void CreateRigidBody(string FilePath) { CollisionShape shape; WheelDriverMeta wheel = null; DefaultMotionState motion; BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(FilePath); Vector3 loc; Quaternion rot = Quaternion.Identity; //Is it a wheel? if ((wheel = GetSkeletalJoint()?.cDriver?.GetInfo <WheelDriverMeta>()) != null && true) { //Align the cylinders Vector3 min, max; GetShape(mesh).GetAabb(Matrix4.Identity, out min, out max); Vector3 extents = max - min; //Find the thinnest dimension, that is probably wheat the cylinder should be aligned to if (extents.X < extents.Y) //X or Z { if (extents.X < extents.Z) { shape = new CylinderShapeX(wheel.width, wheel.radius, wheel.radius); //X } else { shape = new CylinderShapeZ(wheel.radius, wheel.radius, wheel.width); //Z } } else //Y or Z { if (extents.Y < extents.Z) { shape = new CylinderShape(wheel.radius, wheel.width, wheel.radius); //Y } else { shape = new CylinderShapeZ(wheel.radius, wheel.radius, wheel.width); //Z } } loc = MeshUtilities.MeshCenter(mesh); } //Rigid Body Construction else { shape = GetShape(mesh); loc = MeshUtilities.MeshCenter(mesh); } if (debug) { Console.WriteLine("Rotation is " + rot); } motion = new DefaultMotionState(Matrix4.CreateTranslation(loc + new Vector3(0, 100, 0))); RigidBodyConstructionInfo info = new RigidBodyConstructionInfo(mesh.physics.mass, motion, shape, shape.CalculateLocalInertia(mesh.physics.mass)); //Temp? info.Friction = 100; info.RollingFriction = 100; //info.AngularDamping = 0f; //info.LinearDamping = 0.5f; BulletObject = new RigidBody(info); }
/// <summary> /// Generates the robot from the list of <see cref="RigidNode_Base"/>s and the /// number of wheels, and updates the collective mass. /// </summary> /// <param name="nodes"></param> /// <param name="numWheels"></param> /// <param name="collectiveMass"></param> /// <returns></returns> protected override bool ConstructRobot(List <RigidNode_Base> nodes, ref float collectiveMass) { if (IsMecanum()) { return(base.ConstructRobot(nodes, ref collectiveMass)); } //Load Node_0, the base of the robot RigidNode node = (RigidNode)nodes[0]; node.CreateTransform(transform); if (!node.CreateMesh(RobotDirectory + "\\" + node.ModelFileName, true, wheelMass)) { return(false); } node.CreateJoint(this); if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } //Get the wheel mesh data from the file they are stored in. They are stored as .bxda files. This may need to update if exporters/file types change. BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(wheelPath + "\\node_0.bxda"); List <Mesh> meshList = new List <Mesh>(); List <Material[]> materialList = new List <Material[]>(); RigidNode wheelNode = (RigidNode)BXDJSkeleton.ReadSkeleton(wheelPath + "\\skeleton.bxdj"); Material[] materials = new Material[0]; Auxiliary.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { meshList.Add(meshu); materials = new Material[meshu.subMeshCount]; for (int i = 0; i < materials.Length; i++) { materials[i] = sub.surfaces[i].AsMaterial(true); } materialList.Add(materials); }, true); //Loads the other nodes from the original robot for (int i = 1; i < nodes.Count; i++) { node = (RigidNode)nodes[i]; node.CreateTransform(transform); if (!node.CreateMesh(RobotDirectory + "\\" + node.ModelFileName, true, wheelMass)) { return(false); } //If the node is a wheel, destroy the original wheel mesh and replace it with the wheels selected in MaM if (node.HasDriverMeta <WheelDriverMeta>()) { int chldCount = node.MainObject.transform.childCount; for (int j = 0; j < chldCount; j++) { Destroy(node.MainObject.transform.GetChild(j).gameObject); } int k = 0; Vector3?offset = null; foreach (Mesh meshObject in meshList) { GameObject meshObj = new GameObject(node.MainObject.name + "_mesh"); meshObj.transform.parent = node.MainObject.transform; meshObj.AddComponent <MeshFilter>().mesh = meshObject; if (!offset.HasValue) { offset = meshObject.bounds.center; } meshObj.transform.localPosition = -offset.Value; //Take out this line if you want some snazzy pink wheels meshObj.AddComponent <MeshRenderer>().materials = materialList[k]; k++; } node.MainObject.GetComponentInChildren <MeshRenderer>().materials = materials; } } RootNode.GenerateWheelInfo(); //Create the joints that interact with physics for (int i = 1; i < nodes.Count; i++) { node = (RigidNode)nodes[i]; node.CreateJoint(this, wheelFriction, wheelLateralFriction); if (node.HasDriverMeta <WheelDriverMeta>()) { node.MainObject.GetComponent <BRaycastWheel>().Radius = wheelRadius; } if (node.PhysicalProperties != null) { collectiveMass += node.PhysicalProperties.mass; } if (node.MainObject.GetComponent <BRigidBody>() != null) { node.MainObject.AddComponent <Tracker>().Trace = true; } } return(true); }
public bool CreateMesh(string filePath) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath, null); if (!mesh.GUID.Equals(GUID)) { return(false); } List <FieldNode> remainingNodes = new List <FieldNode>(NodeGroup.EnumerateAllLeafFieldNodes()); List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > submeshes = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >(); List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > colliders = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >(); // Create all submesh objects auxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { submeshes.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu)); }); // Create all collider objects auxFunctions.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { colliders.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu)); }); foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes()) { GameObject subObject = new GameObject(node.NodeID); //subObject.transform.parent = unityObject.transform; if (node.SubMeshID != -1) { KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = submeshes[node.SubMeshID]; BXDAMesh.BXDASubMesh sub = currentSubMesh.Key; Mesh meshu = currentSubMesh.Value; subObject.AddComponent <MeshFilter>().mesh = meshu; subObject.AddComponent <MeshRenderer>(); Material[] matls = new Material[meshu.subMeshCount]; for (int i = 0; i < matls.Length; i++) { matls[i] = sub.surfaces[i].AsMaterial(); } subObject.GetComponent <MeshRenderer>().materials = matls; } if (GetPropertySets().ContainsKey(node.PropertySetID)) { PropertySet currentPropertySet = GetPropertySets()[node.PropertySetID]; PropertySet.PropertySetCollider psCollider = currentPropertySet.Collider; Collider unityCollider = null; Debug.Log(psCollider == null); switch (psCollider.CollisionType) { case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX: PropertySet.BoxCollider psBoxCollider = (PropertySet.BoxCollider)psCollider; BoxCollider unityBoxCollider = subObject.AddComponent <BoxCollider>(); //unityBoxCollider.size.Scale(new Vector3(psBoxCollider.Scale.x, psBoxCollider.Scale.y, psBoxCollider.Scale.z)); unityBoxCollider.size = new Vector3( unityBoxCollider.size.x * psBoxCollider.Scale.x, unityBoxCollider.size.y * psBoxCollider.Scale.y, unityBoxCollider.size.z * psBoxCollider.Scale.z); unityCollider = unityBoxCollider; break; case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE: PropertySet.SphereCollider psSphereCollider = (PropertySet.SphereCollider)psCollider; SphereCollider unitySphereCollider = subObject.AddComponent <SphereCollider>(); unitySphereCollider.radius *= psSphereCollider.Scale; unityCollider = unitySphereCollider; break; case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH: if (node.CollisionMeshID != -1) { KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = colliders[node.CollisionMeshID]; BXDAMesh.BXDASubMesh sub = currentSubMesh.Key; Mesh meshu = currentSubMesh.Value; MeshCollider unityMeshCollider = subObject.AddComponent <MeshCollider>(); unityMeshCollider.sharedMesh = meshu; unityMeshCollider.convex = true; unityCollider = unityMeshCollider; } break; } if (unityCollider != null) { unityCollider.material.dynamicFriction = unityCollider.material.staticFriction = currentPropertySet.Friction / 100f; unityCollider.material.frictionCombine = PhysicMaterialCombine.Minimum; Rigidbody rb = unityCollider.gameObject.AddComponent <Rigidbody>(); if (currentPropertySet.Mass > 0) { rb.mass = (float)currentPropertySet.Mass * Init.PHYSICS_MASS_MULTIPLIER; } else { rb.constraints = RigidbodyConstraints.FreezeAll; rb.isKinematic = true; } } } // Invert the x-axis to compensate for Unity's inverted coordinate system. subObject.transform.localScale = new Vector3(-1f, 1f, 1f); // Set the position of the object (scaled by 1/100 to match Unity's scaling correctly). subObject.transform.position = new Vector3(-node.Position.x * 0.01f, node.Position.y * 0.01f, node.Position.z * 0.01f); // Set the rotation of the object (the x and w properties are inverted to once again compensate for Unity's differences). subObject.transform.rotation = new Quaternion(-node.Rotation.X, node.Rotation.Y, node.Rotation.Z, -node.Rotation.W); } #region Free mesh foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return(true); }
public bool CreateMesh(string filePath) { Debug.Log(filePath); BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath); //if (!mesh.GUID.Equals(GUID)) //{ // Debug.Log("Returning false"); // return false; //} List <GameObject> meshObjects = new List <GameObject>(); AuxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { GameObject meshObject = new GameObject(MainObject.name + "_mesh"); meshObjects.Add(meshObject); meshObject.AddComponent <MeshFilter>().mesh = meshu; meshObject.AddComponent <MeshRenderer>(); Material[] materials = new Material[meshu.subMeshCount]; for (int i = 0; i < materials.Length; i++) { materials[i] = sub.surfaces[i].AsMaterial(true); } meshObject.GetComponent <MeshRenderer>().materials = materials; meshObject.transform.position = root.position; meshObject.transform.rotation = root.rotation; Debug.Log("Mesh Objects count " + meshObjects.Count); }, true); Vector3 com = mesh.physics.centerOfMass.AsV3(); com.x *= -1; ComOffset = com; Mesh[] colliders = new Mesh[mesh.colliders.Count]; AuxFunctions.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { colliders[id] = meshu; }, true); MainObject.transform.position = root.position + ComOffset; MainObject.transform.rotation = root.rotation; foreach (GameObject meshObject in meshObjects) { meshObject.transform.parent = MainObject.transform; } if (!this.HasDriverMeta <WheelDriverMeta>() || this.GetDriverMeta <WheelDriverMeta>().type == WheelType.NOT_A_WHEEL) { BMultiHullShape hullShape = MainObject.AddComponent <BMultiHullShape>(); foreach (Mesh collider in colliders) { ConvexHullShape hull = new ConvexHullShape(Array.ConvertAll(collider.vertices, x => x.ToBullet()), collider.vertices.Length); hull.Margin = 0f; hullShape.AddHullShape(hull, BulletSharp.Math.Matrix.Translation(-ComOffset.ToBullet())); } MainObject.AddComponent <MeshRenderer>(); PhysicalProperties = mesh.physics; Debug.Log(PhysicalProperties.centerOfMass); BRigidBody rigidBody = MainObject.AddComponent <BRigidBody>(); rigidBody.mass = mesh.physics.mass; rigidBody.friction = 0.25f; rigidBody.RemoveOnCollisionCallbackEventHandler(); ((RigidBody)rigidBody.GetCollisionObject()).ActivationState = ActivationState.DisableDeactivation; foreach (BRigidBody rb in MainObject.transform.parent.GetComponentsInChildren <BRigidBody>()) { rigidBody.GetCollisionObject().SetIgnoreCollisionCheck(rb.GetCollisionObject(), true); } MainObject.AddComponent <BMultiCallbacks>().AddCallback((StateMachine.Instance.CurrentState as MainState).CollisionTracker); } if (this.HasDriverMeta <WheelDriverMeta>() && this.GetDriverMeta <WheelDriverMeta>().type != WheelType.NOT_A_WHEEL && GetParent() == null) { BRigidBody rigidBody = MainObject.GetComponent <BRigidBody>(); if (MixAndMatchMode.isMixAndMatchMode) { rigidBody.mass += PlayerPrefs.GetFloat("wheelMass", 1f); } rigidBody.GetCollisionObject().CollisionShape.CalculateLocalInertia(rigidBody.mass); } #region Free mesh foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return(true); }
public bool CreateMesh(string filePath, bool multiplayer = false, bool host = false) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath, null); if (!mesh.GUID.Equals(GUID)) { return(false); } List <FieldNode> remainingNodes = new List <FieldNode>(NodeGroup.EnumerateAllLeafFieldNodes()); List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > submeshes = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >(); List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > colliders = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >(); // Create all submesh objects Auxiliary.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { submeshes.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu)); }); // Create all collider objects Auxiliary.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { colliders.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu)); }); //Dictionary<string, NetworkElement> networkElements = new Dictionary<string, NetworkElement>(); //foreach (NetworkElement ne in Resources.FindObjectsOfTypeAll<NetworkElement>()) // networkElements[ne.NodeID] = ne; foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes()) { PropertySet?propertySet = null; if (GetPropertySets().ContainsKey(node.PropertySetID)) { propertySet = GetPropertySets()[node.PropertySetID]; } GameObject subObject; //if (multiplayer && propertySet.HasValue && propertySet.Value.Mass != 0) //{ // if (host) // { // subObject = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("prefabs/NetworkElement"), unityObject.transform); // subObject.GetComponent<NetworkElement>().NodeID = node.NodeID; // subObject.name = node.NodeID; // NetworkServer.Spawn(subObject); // } // else // { // subObject = networkElements[node.NodeID].gameObject; // subObject.name = node.NodeID; // } //} //else //{ // subObject = new GameObject(node.NodeID); //} subObject = new GameObject(node.NodeID); subObject.transform.parent = unityObject.transform; GameObject meshObject = new GameObject(node.NodeID + "-mesh"); if (node.SubMeshID != -1) { KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = submeshes[node.SubMeshID]; BXDAMesh.BXDASubMesh sub = currentSubMesh.Key; Mesh meshu = currentSubMesh.Value; meshObject.AddComponent <MeshFilter>().mesh = meshu; meshObject.AddComponent <MeshRenderer>(); Material[] matls = new Material[meshu.subMeshCount]; for (int i = 0; i < matls.Length; i++) { matls[i] = sub.surfaces[i].AsMaterial(); } meshObject.GetComponent <MeshRenderer>().materials = matls; } // Invert the x-axis to compensate for Unity's inverted coordinate system. meshObject.transform.localScale = new Vector3(-1f, 1f, 1f); // Set the rotation of the object (the x and w properties are inverted to once again compensate for Unity's differences). meshObject.transform.localRotation = new Quaternion(-node.Rotation.X, node.Rotation.Y, node.Rotation.Z, -node.Rotation.W); // Set the position of the object (scaled by 1/100 to match Unity's scaling correctly). meshObject.transform.position = new Vector3(-node.Position.x * 0.01f, node.Position.y * 0.01f, node.Position.z * 0.01f); if (GetPropertySets().ContainsKey(node.PropertySetID)) { PropertySet currentPropertySet = GetPropertySets()[node.PropertySetID]; PropertySet.PropertySetCollider psCollider = currentPropertySet.Collider; switch (psCollider.CollisionType) { case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX: PropertySet.BoxCollider psBoxCollider = (PropertySet.BoxCollider)psCollider; BoxCollider dummyBoxCollider = meshObject.AddComponent <BoxCollider>(); subObject.transform.localRotation = meshObject.transform.localRotation; subObject.transform.position = meshObject.transform.TransformPoint(dummyBoxCollider.center); BBoxShape boxShape = subObject.AddComponent <BBoxShape>(); boxShape.Extents = new Vector3( dummyBoxCollider.size.x * 0.5f * psBoxCollider.Scale.x, dummyBoxCollider.size.y * 0.5f * psBoxCollider.Scale.y, dummyBoxCollider.size.z * 0.5f * psBoxCollider.Scale.z); //meshObject.AddComponent<MouseListener>(); UnityEngine.Object.Destroy(dummyBoxCollider); break; case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE: PropertySet.SphereCollider psSphereCollider = (PropertySet.SphereCollider)psCollider; SphereCollider dummySphereCollider = meshObject.AddComponent <SphereCollider>(); subObject.transform.position = meshObject.transform.TransformPoint(dummySphereCollider.center); BSphereShape sphereShape = subObject.AddComponent <BSphereShape>(); sphereShape.Radius = dummySphereCollider.radius * psSphereCollider.Scale; //meshObject.AddComponent<MouseListener>(); UnityEngine.Object.Destroy(dummySphereCollider); break; case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH: PropertySet.MeshCollider psMeshCollider = (PropertySet.MeshCollider)psCollider; if (psMeshCollider.Convex || currentPropertySet.Mass != 0) { MeshCollider dummyMeshCollider = subObject.AddComponent <MeshCollider>(); dummyMeshCollider.sharedMesh = meshObject.GetComponent <MeshFilter>().mesh; subObject.transform.position = meshObject.transform.TransformPoint(dummyMeshCollider.bounds.center); subObject.transform.rotation = meshObject.transform.rotation; BConvexHullShape hullshape = subObject.AddComponent <BConvexHullShape>(); hullshape.HullMesh = Auxiliary.GenerateCollisionMesh(meshObject.GetComponent <MeshFilter>().mesh, dummyMeshCollider.sharedMesh.bounds.center, 0f /*CollisionMargin*/); hullshape.GetCollisionShape().Margin = CollisionMargin; //subObject.AddComponent<MouseListener>(); UnityEngine.Object.Destroy(dummyMeshCollider); } else { subObject.transform.position = meshObject.transform.position; subObject.transform.rotation = meshObject.transform.rotation; BBvhTriangleMeshShape meshShape = subObject.AddComponent <BBvhTriangleMeshShape>(); meshShape.HullMesh = meshObject.GetComponent <MeshFilter>().mesh.GetScaledCopy(-1f, 1f, 1f); meshShape.GetCollisionShape().Margin = CollisionMargin; } break; } BRigidBody rb = subObject.AddComponent <BRigidBody>(); rb.friction = currentPropertySet.Friction * FrictionScale; rb.rollingFriction = currentPropertySet.Friction * RollingFrictionScale; rb.mass = currentPropertySet.Mass; if (currentPropertySet.Mass == 0) { rb.collisionFlags = BulletSharp.CollisionFlags.StaticObject; } else { subObject.AddComponent <Tracker>(); subObject.name = currentPropertySet.PropertySetID; //sets game elements to the same name as the property set - used to identify proper colliders } meshObject.transform.parent = subObject.transform; } else { meshObject.transform.parent = unityObject.transform; } } //if (!host) // foreach (NetworkElement ne in networkElements.Values) // ne.gameObject.AddComponent<NetworkMesh>(); #region Free mesh foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return(true); }
/// <summary> /// Loads the mesh from the given path into this node's object. /// </summary> /// <param name="filePath">The file to open as a BXDA mesh</param> public bool CreateMesh(string filePath) { BXDAMesh mesh = new BXDAMesh(); mesh.ReadFromFile(filePath, null); if (!mesh.GUID.Equals(GUID)) { return(false); } // Create all submesh objects auxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu) { GameObject subObject = new GameObject(unityObject.name + " Subpart" + id); subObject.transform.parent = unityObject.transform; subObject.transform.position = new Vector3(0, 0, 0); subObject.AddComponent <MeshFilter>().mesh = meshu; subObject.AddComponent <MeshRenderer>(); Material[] matls = new Material[meshu.subMeshCount]; for (int i = 0; i < matls.Length; i++) { matls[i] = sub.surfaces[i].AsMaterial(); } subObject.GetComponent <MeshRenderer>().materials = matls; }); if (!unityObject.GetComponent <Rigidbody>()) { unityObject.AddComponent <Rigidbody>(); } // Read colliders auxFunctions.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh useless, Mesh meshu) { GameObject subCollider = new GameObject(unityObject.name + " Subcollider" + id); subCollider.transform.parent = unityObject.transform; subCollider.transform.position = new Vector3(0, 0, 0); // Special case where it is a box if (meshu.triangles.Length == 0 && meshu.vertices.Length == 2) { BoxCollider box = subCollider.AddComponent <BoxCollider>(); Vector3 center = (meshu.vertices[0] + meshu.vertices[1]) * 0.5f; box.center = center; box.size = meshu.vertices[1] - center; } else { subCollider.AddComponent <MeshCollider>().sharedMesh = meshu; subCollider.GetComponent <MeshCollider>().convex = true; } }); Rigidbody rigidB = unityObject.GetComponent <Rigidbody>(); rigidB.mass = mesh.physics.mass * Init.PHYSICS_MASS_MULTIPLIER; // Unity has magic mass units rigidB.centerOfMass = mesh.physics.centerOfMass.AsV3(); bxdPhysics = mesh.physics; #region Free mesh foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders }) { foreach (BXDAMesh.BXDASubMesh sub in list) { sub.verts = null; sub.norms = null; foreach (BXDAMesh.BXDASurface surf in sub.surfaces) { surf.indicies = null; } } for (int i = 0; i < list.Count; i++) { list[i] = null; } } mesh = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); #endregion return(true); }