private void On_WorldRootBAnchor_BAnchorMovedToTracker(BAnchor bAnchor, string trackerName) { if (ARE_EQUAL(bAnchor, worldRootBAnchor)) { BEventsCollection.AR_WorldBAnchorSet.Invoke(new BEHandle <BAnchorInformation>(bAnchor.GetBAnchorInformation())); } }
private void On_WorldRootBAnchorCursorPlacer_EndedPlacing(BAnchor bAnchor) { if (ARE_EQUAL(bAnchor, worldRootBAnchor)) { BEventsCollection.AR_WorldBAnchorSet.Invoke(new BEHandle <BAnchorInformation>(bAnchor.GetBAnchorInformation())); } }
/// <summary> /// Called from BAnchorCursorPlacer to start placing a new BAnchor /// </summary> /// <param name="bAnchorToBePlaced"></param> /// <param name="bAnchorCursorPlacer"></param> /// <returns></returns> public bool OnStartPlacingBAnchor(BAnchorCursorPlacer bAnchorCursorPlacer, BAnchor bAnchorToBePlaced) { if (IS_NOT_NULL(bAnchorCursorPlacer) && IS_NOT_NULL(bAnchorToBePlaced)) { if (IsCurrenltyPlacingBAnchor == false) { CurrentBAnchorBeingPlaced = bAnchorToBePlaced; return(true); } else { LogConsoleWarning("Trying to select a new BAnchor for placement but one is already slected!"); } } return(false); }
private void On_AR_BAnchorSpawned(BEHandle <BAnchorInformation, string> handle) { BAnchorInformation bAnchorInformation = handle.Arg1; string bAnchorID = handle.Arg2; BAnchor bAnchorPrefab = GetBAnchorPrefab(bAnchorID); if (handle.InvokingNetworkID != BEventManager.Instance.LocalNetworkID && IS_NOT_NULL(bAnchorPrefab) && IS_NOT_NULL(bAnchorInformation)) { BAnchor spawnedBAnchor = Instantiate(bAnchorPrefab, Vector3.zero, Quaternion.identity); spawnedBAnchor.SetTransformedPosition(bAnchorInformation.TransformedPosition); spawnedBAnchor.SetTransformedRotation(bAnchorInformation.TransformedRotation); spawnedBAnchor.Owner = handle.InvokingNetworkID; BEventsCollection.AR_BAnchorSpawned.Invoke(new BEHandle <BAnchorInformation, string>(bAnchorInformation, bAnchorID), BEventReplicationType.LOCAL, true); } }
public BAnchor SpawnBAnchorAtCursorPosition(BAnchor bAnchorPrefab, bool replicateSpawnToOthers = false) { if (IS_NOT_NULL(ARCursor.Instance) && IS_NOT_NULL(bAnchorPrefab)) { BAnchor spawnedBAnchor = Instantiate(bAnchorPrefab, ARCursor.Instance.GetCursorPosition(), ARCursor.Instance.GetCursorRotation()); spawnedBAnchor.Owner = BEventManager.Instance.LocalNetworkID; // Trigger event BEventReplicationType bEventReplicationType = BEventReplicationType.LOCAL; if (replicateSpawnToOthers) { bEventReplicationType = BEventReplicationType.TO_ALL_OTHERS; } BEventsCollection.AR_BAnchorSpawned.Invoke(new BEHandle <BAnchorInformation, string>(spawnedBAnchor.GetBAnchorInformation(), spawnedBAnchor.BAnchorID), bEventReplicationType, true); return(spawnedBAnchor); } return(null); }
/// <summary> /// Called from BAnchorCursorPlacer to stop placing a new BAnchor /// </summary> /// <param name="bAnchorToBePlaced"></param> /// <param name="bAnchorCursorPlacer"></param> /// <returns></returns> public bool OnStopPlacingBAnchor(BAnchorCursorPlacer bAnchorCursorPlacer, BAnchor bAnchorToBePlaced) { if (IS_NOT_NULL(bAnchorCursorPlacer) && IS_NOT_NULL(bAnchorToBePlaced)) { if (IsCurrenltyPlacingBAnchor == true) { if (CurrentBAnchorBeingPlaced == bAnchorToBePlaced) { CurrentBAnchorBeingPlaced = null; return(true); } else { LogConsoleWarning("Trying to unselected a BAnchor for placement but another one was found already active!"); } } else { LogConsoleWarning("Trying to unselected a BAnchor for placement but no BAnchor placement is currently active!"); } } return(false); }
internal override bool _BuildCollisionObject() { if (World == null) { return(false); } if (transform.localScale != Vector3.one) { Debug.LogError("The scale must be 1,1,1"); } if (bone2idxMap == null || bone2idxMap.Length == 0) { Debug.LogError("No bones have been mapped to soft body nodes for object " + name); } for (int i = 0; i < anchors.Length; i++) { if (anchors[i].anchorRigidBody == null) { Debug.LogError("No anchor rigid body has been set for anchor " + i); } if (anchors[i].anchorNodeIndexes == null || anchors[i].anchorNodeIndexes.Count == 0) { Debug.LogError("No nodes have been identified as anchors. Soft body will not be attached to RigidBody anchor " + anchors[i].anchorRigidBody); } } if (physicsSimMesh == null) { physicsSimMesh = GetComponent <MeshFilter>(); } Mesh mesh = physicsSimMesh.sharedMesh; //convert the mesh data to Bullet data and create DoftBody //todo should these be in world coordinates BulletSharp.Math.Vector3[] bVerts = new BulletSharp.Math.Vector3[mesh.vertexCount]; Vector3[] verts = mesh.vertices; for (int i = 0; i < mesh.vertexCount; i++) { bVerts[i] = verts[i].ToBullet(); } SoftBody m_BSoftBody = SoftBodyHelpers.CreateFromTriMesh(World.WorldInfo, bVerts, mesh.triangles); m_collisionObject = m_BSoftBody; SoftBodySettings.ConfigureSoftBody(m_BSoftBody); //Set SB settings //Set SB position to GO position m_BSoftBody.Rotate(physicsSimMesh.transform.rotation.ToBullet()); m_BSoftBody.Translate(physicsSimMesh.transform.position.ToBullet()); m_BSoftBody.Scale(physicsSimMesh.transform.localScale.ToBullet()); for (int i = 0; i < anchors.Length; i++) { BAnchor a = anchors[i]; for (int j = 0; j < a.anchorNodeIndexes.Count; j++) { m_BSoftBody.AppendAnchor(a.anchorNodeIndexes[j], (RigidBody)a.anchorRigidBody.GetCollisionObject(), false, a.anchorNodeStrength[j]); } } MeshRenderer mr = physicsSimMesh.GetComponent <MeshRenderer>(); if (mr != null) { if (debugDisplaySimulatedMesh) { mr.enabled = true; } else { mr.enabled = false; } } if (norms.Length == 0 || norms.Length != verts.Length) { norms = new Vector3[m_BSoftBody.Nodes.Count]; verts = new Vector3[m_BSoftBody.Nodes.Count]; } for (int i = 0; i < m_BSoftBody.Nodes.Count; i++) { norms[i] = m_BSoftBody.Nodes[i].Normal.ToUnity(); verts[i] = m_BSoftBody.Nodes[i].Position.ToUnity(); } for (int i = 0; i < bone2idxMap.Length; i++) { bone2idxMap[i].bindNormal = norms[bone2idxMap[i].nodeIdx]; bone2idxMap[i].bindBoneRotation = bone2idxMap[i].bone.rotation; for (int j = 0; j < bone2idxMap[i].edges.Length; j++) { bone2idxMap[i].edges[j].bindEdgeXnorm = Vector3.Cross(verts[bone2idxMap[i].edges[j].nodeIdx] - verts[bone2idxMap[i].nodeIdx], norms[bone2idxMap[i].nodeIdx]).normalized; } } return(true); }
// Use this for initialization public void BindBonesToSoftBodyAndNodesToAnchors() { if (transform.localScale != Vector3.one) { Debug.LogError("The scale must be 1,1,1"); return; } if (skinnedMesh == null) { Debug.LogError("The Skinned Mesh field has not been assigned."); return; } physicsSimMesh = GetComponent <MeshFilter>(); if (physicsSimMesh == null) { Debug.LogError("Must be attached to an object with a MeshRenderer"); return; } if (physicsSimMesh == null) { Debug.LogError("must add the physics sim mesh bone"); return; } for (int i = 0; i < anchors.Length; i++) { BAnchor a = anchors[i]; if (a.colRangeTo <= a.colRangeFrom) { Debug.LogError("Error with Anchor row " + i + " ColRangeTo must be greater than colRangeFrom."); } for (int j = i + 1; j < anchors.Length; j++) { BAnchor b = anchors[j]; if (b.colRangeFrom >= a.colRangeTo && b.colRangeTo >= a.colRangeTo) { //good } else if (b.colRangeFrom <= a.colRangeFrom && b.colRangeTo <= a.colRangeFrom) { //good } else { Debug.LogErrorFormat("The color ranges of Anchors {0} and {1} overlap", i, j); } } } //get bones and mesh verts //compare these in world space to see which ones line up //TODO why does other mesh shape work better than this one. Transform[] bones = skinnedMesh.bones; Mesh m = physicsSimMesh.sharedMesh; Vector3[] verts = m.vertices; Vector3[] norms = m.normals; Color[] cols = m.colors; int[] triangles = m.triangles; if (cols.Length != verts.Length) { Debug.LogError("The physics sim mesh had no colors. Colors are needed to identify the anchor bones."); } //check for duplicate verts int numDuplicated = 0; for (int i = 0; i < verts.Length; i++) { for (int j = i + 1; j < verts.Length; j++) { if (verts[i] == verts[j]) { numDuplicated++; } } } if (numDuplicated > 0) { Debug.LogError("The physics sim mesh has " + numDuplicated + " duplicated vertices. Check that the mesh does not have hard edges and that there are no UVs."); } List <BoneAndNode> foundMatches = new List <BoneAndNode>(); for (int i = 0; i < verts.Length; i++) { for (int j = 0; j < bones.Length; j++) { Vector3 worldSpaceVert = physicsSimMesh.transform.TransformPoint(verts[i]); Vector3 worldSpaceBone = bones[j].position; if (Vector3.Distance(worldSpaceBone, worldSpaceVert) < radius) { //Debug.Log("found a bone that is aligned with a vertex " + bones[j]); BoneAndNode ban = new BoneAndNode(); ban.bone = bones[j]; ban.nodeIdx = i; foundMatches.Add(ban); } } } bone2idxMap = foundMatches.ToArray(); for (int i = 0; i < bone2idxMap.Length; i++) { int idx = bone2idxMap[i].nodeIdx; List <Edge> edges = new List <Edge>(); for (int j = 0; j < triangles.Length; j += 3) { if (triangles[j] == idx) { _addEdges(idx, triangles[j + 1], triangles[j + 2], edges, norms, verts); } else if (triangles[j + 1] == idx) { _addEdges(idx, triangles[j], triangles[j + 2], edges, norms, verts); } else if (triangles[j + 2] == idx) { _addEdges(idx, triangles[j], triangles[j + 1], edges, norms, verts); } } edges.Sort(); bone2idxMap[i].edges = edges.ToArray(); } // clear old values for (int j = 0; j < anchors.Length; j++) { anchors[j].anchorNodeIndexes.Clear(); anchors[j].anchorNodeStrength.Clear(); anchors[j].anchorPosition.Clear(); } int numAnchorNodes = 0; for (int i = 0; i < cols.Length; i++) { for (int j = 0; j < anchors.Length; j++) { if (cols[i].g > anchors[j].colRangeFrom && cols[i].g < anchors[j].colRangeTo) { anchors[j].anchorNodeIndexes.Add(i); anchors[j].anchorNodeStrength.Add(cols[i].r); anchors[j].anchorPosition.Add(verts[i]); numAnchorNodes++; } } } SoftBody sb = (SoftBody)m_collisionObject; Debug.LogFormat("Done binding bones to nodes and nodes to anchors. Found: {0} bones and {1} anchor nodes.", bone2idxMap.Length, numAnchorNodes); }