void OnMeshGenerated(MeshGenerationResult result) { if (result.Status == MeshGenerationStatus.Success) { // The mesh may have been removed by external code MeshInfo meshInfo; if (!m_MeshesBeingGenerated.TryGetValue(result.MeshId, out meshInfo)) { return; } m_MeshesBeingGenerated.Remove(result.MeshId); switch (meshInfo.ChangeState) { case MeshChangeState.Added: RaiseMeshAdded(result.MeshId); break; case MeshChangeState.Updated: RaiseMeshUpdated(result.MeshId); break; // Removed/unchanged meshes don't get generated. default: break; } } else { m_MeshesBeingGenerated.Remove(result.MeshId); } }
private void AddQuad(MeshGenerationResult result, Vector3 lowerLeft, Vector3 upperRight, Tile tile, Vector3 pos, Vector3 normal) { TerrainQuad quad = new TerrainQuad(result.tris, result.vertices, result.uvs, lowerLeft, upperRight, tile, tileset, pos, normal); if (!result.quads.ContainsKey(pos)) { result.quads[pos] = new Dictionary <Vector3, TerrainQuad>(); } result.quads[pos][normal] = quad; }
void OnMeshGenerated(MeshGenerationResult result) { if (result.Status != MeshGenerationStatus.Success) { GameObject meshGameObject; if (meshIdToGameObjectMap.TryGetValue(result.MeshId, out meshGameObject)) { Destroy(meshGameObject); meshIdToGameObjectMap.Remove(result.MeshId); } } m_MeshesBeingGenerated.Remove(result.MeshId); }
void OnMeshGenerated(MeshGenerationResult result) { if (result.Status == MeshGenerationStatus.Success) { // The mesh may have been removed by external code MeshInfo meshInfo; if (!m_MeshesBeingGenerated.TryGetValue(result.MeshId, out meshInfo)) { return; } m_MeshesBeingGenerated.Remove(result.MeshId); switch (meshInfo.ChangeState) { case MeshChangeState.Added: RaiseMeshAdded(result.MeshId); break; case MeshChangeState.Updated: RaiseMeshUpdated(result.MeshId); break; // Removed/unchanged meshes don't get generated. default: break; } GameObject meshGameObject = null; if (meshIdToGameObjectMap.TryGetValue(result.MeshId, out meshGameObject)) { // Disable the collision mesh if we're in point cloud mode var meshCollider = meshGameObject.GetComponent <MeshCollider>(); if (meshCollider != null) { meshCollider.enabled = (meshType != MeshType.PointCloud); } } } else { m_MeshesBeingGenerated.Remove(result.MeshId); } }
private void Rebuild(bool regenMesh) { TacticsTerrainMesh terrain = (TacticsTerrainMesh)target; PrefabStage prefabStage = PrefabStageUtility.GetPrefabStage(terrain.gameObject); if (prefabStage != null) { EditorSceneManager.MarkSceneDirty(prefabStage.scene); } MeshGenerationResult result = terrain.Rebuild(regenMesh); quads = result.quads; tris = result.tris; uvs = result.uvs; vertices = result.vertices; if (regenMesh) { selectedQuads.Clear(); } }
void OnMeshGenerated(MeshGenerationResult result) { if (!m_Generating.TryGetValue(result.MeshId, out MeshInfo meshInfo)) { return; } m_Generating.Remove(result.MeshId); if (result.Status != MeshGenerationStatus.Success) { return; } if (!m_Meshes.TryGetValue(GetTrackableId(result.MeshId), out MeshFilter meshFilter) || (meshFilter == null)) { return; } meshFilter.gameObject.SetActive(true); switch (meshInfo.ChangeState) { case MeshChangeState.Added: m_Added.Add(meshFilter); break; case MeshChangeState.Updated: m_Updated.Add(meshFilter); break; // Removed/unchanged meshes don't get generated. default: break; } }
private void MeshGenerationAction(MeshGenerationResult meshGenerationResult) { if (!IsRunning) { return; } using (MeshGenerationActionPerfMarker.Auto()) { if (outstandingMeshObject == null) { Debug.LogWarning($"MeshGenerationAction called for mesh id {meshGenerationResult.MeshId} while no request was outstanding."); return; } switch (meshGenerationResult.Status) { case MeshGenerationStatus.InvalidMeshId: case MeshGenerationStatus.Canceled: case MeshGenerationStatus.UnknownError: outstandingMeshObject = null; break; case MeshGenerationStatus.Success: // Since there is only one outstanding mesh object, update the id to match // the one received after baking. SpatialAwarenessMeshObject meshObject = outstandingMeshObject; meshObject.Id = meshGenerationResult.MeshId.GetHashCode(); outstandingMeshObject = null; // Apply the appropriate material to the mesh. SpatialAwarenessMeshDisplayOptions displayOption = DisplayOption; if (displayOption != SpatialAwarenessMeshDisplayOptions.None) { meshObject.Renderer.enabled = true; meshObject.Renderer.sharedMaterial = (displayOption == SpatialAwarenessMeshDisplayOptions.Visible) ? VisibleMaterial : OcclusionMaterial; meshObject.Collider.material = PhysicsMaterial; } else { meshObject.Renderer.enabled = false; } // Recalculate the mesh normals if requested. if (RecalculateNormals) { meshObject.Filter.sharedMesh.RecalculateNormals(); } // Add / update the mesh to our collection bool sendUpdatedEvent = false; if (meshes.ContainsKey(meshObject.Id)) { // Reclaim the old mesh object for future use. ReclaimMeshObject(meshes[meshObject.Id]); meshes.Remove(meshObject.Id); sendUpdatedEvent = true; } meshes.Add(meshObject.Id, meshObject); meshObject.GameObject.transform.parent = (ObservedObjectParent.transform != null) ? ObservedObjectParent.transform : null; meshEventData.Initialize(this, meshObject.Id, meshObject); if (sendUpdatedEvent) { SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshUpdated); } else { SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded); } break; } } }
private void MeshGenerationAction(MeshGenerationResult meshGenerationResult) { if (!IsRunning) { return; } using (MeshGenerationActionPerfMarker.Auto()) { if (outstandingMeshObject == null) { Debug.LogWarning($"MeshGenerationAction called for mesh id {meshGenerationResult.MeshId} while no request was outstanding."); return; } switch (meshGenerationResult.Status) { case MeshGenerationStatus.InvalidMeshId: case MeshGenerationStatus.Canceled: case MeshGenerationStatus.UnknownError: outstandingMeshObject = null; break; case MeshGenerationStatus.Success: // Since there is only one outstanding mesh object, update the id to match // the one received after baking. SpatialAwarenessMeshObject meshObject = outstandingMeshObject; meshObject.Id = meshGenerationResult.MeshId.GetHashCode(); outstandingMeshObject = null; // Check to see if this is a new or updated mesh. bool isMeshUpdate = meshes.ContainsKey(meshObject.Id); // We presume that if the display option is not occlusion, that we should // default to the visible material. // Note: We check explicitly for a display option of none later in this method. Material material = (DisplayOption == SpatialAwarenessMeshDisplayOptions.Occlusion) ? OcclusionMaterial : VisibleMaterial; // If this is a mesh update, we want to preserve the mesh's previous material. material = isMeshUpdate ? meshes[meshObject.Id].Renderer.sharedMaterial : material; // Apply the appropriate material. meshObject.Renderer.sharedMaterial = material; // Recalculate the mesh normals if requested. if (RecalculateNormals) { meshObject.Filter.sharedMesh.RecalculateNormals(); } // Check to see if the display option is set to none. If so, we disable // the renderer. meshObject.Renderer.enabled = (DisplayOption != SpatialAwarenessMeshDisplayOptions.None); // Set the physics material if (meshObject.Renderer.enabled) { meshObject.Collider.material = PhysicsMaterial; } // Add / update the mesh to our collection if (isMeshUpdate) { // Reclaim the old mesh object for future use. ReclaimMeshObject(meshes[meshObject.Id]); meshes.Remove(meshObject.Id); } meshes.Add(meshObject.Id, meshObject); meshObject.GameObject.transform.parent = (ObservedObjectParent.transform != null) ? ObservedObjectParent.transform : null; meshEventData.Initialize(this, meshObject.Id, meshObject); if (isMeshUpdate) { SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshUpdated); } else { SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded); } break; } } }
// === MESH GENERATION ========================================================================= public MeshGenerationResult Rebuild(bool regenMesh) { MeshFilter filter = GetComponent <MeshFilter>(); if (!Application.isPlaying) { //if (filter.sharedMesh == null) { // filter.sharedMesh = new Mesh(); // AssetDatabase.CreateAsset(filter.sharedMesh, // "Assets/Resources/TacticsMaps/Meshes/" + gameObject.name + ".asset"); //} } else { if (filter.mesh == null) { filter.mesh = new Mesh(); } } Mesh mesh; if (!Application.isPlaying) { mesh = filter.sharedMesh; } else { mesh = filter.mesh; } MeshGenerationResult result = new MeshGenerationResult(); result.quads = new Dictionary <Vector3, Dictionary <Vector3, TerrainQuad> >(); result.vertices = new List <Vector3>(); result.uvs = new List <Vector2>(); result.tris = new List <int>(); for (int z = 0; z < size.y; z += 1) { for (int x = 0; x < size.x; x += 1) { // top vertices float height = HeightAt(x, z); AddQuad(result, new Vector3(x, height, z), new Vector3(x + 1, height, z + 1), TileAt(x, z), new Vector3(x, height, z), new Vector3(0, 1, 0)); // side vertices foreach (OrthoDir dir in Enum.GetValues(typeof(OrthoDir))) { float currentHeight = HeightAt(x, z); float neighborHeight = HeightAt(x + dir.Px3DX(), z + dir.Px3DZ()); if (currentHeight > neighborHeight) { Vector2 off1 = Vector2.zero, off2 = Vector2.zero; switch (dir) { case OrthoDir.South: off1 = new Vector2(0, 0); off2 = new Vector2(1, 0); break; case OrthoDir.East: off1 = new Vector2(1, 1); off2 = new Vector2(1, 0); break; case OrthoDir.North: off1 = new Vector2(1, 1); off2 = new Vector2(0, 1); break; case OrthoDir.West: off1 = new Vector2(0, 0); off2 = new Vector2(0, 1); break; } for (float y = neighborHeight; y < currentHeight; y += 0.5f) { AddQuad(result, new Vector3(x + off1.x, y, z + off1.y), new Vector3(x + off2.x, y + 0.5f, z + off2.y), TileAt(x, z, y, dir), new Vector3(x, y + 0.5f, z), dir.Px3D()); } } } } } if (regenMesh) { mesh.Clear(); mesh.vertices = result.vertices.ToArray(); mesh.triangles = result.tris.ToArray(); mesh.uv = result.uvs.ToArray(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); } return(result); }
public RopeGenerationResult MakeOne() { var transform = _parrent.transform; SkinnedMeshRenderer rend = _parrent.AddComponent <SkinnedMeshRenderer>(); rend.updateWhenOffscreen = true; MeshGenerationResult result = _meshGenerator.Create(_colliderRadius, _length, _boneCount, _restrictFirstBone); if (result.materials != null) { rend.materials = result.materials; } Mesh mesh = result.mesh; // Create Bone Transforms and Bind poses // One bone at the bottom and one at the top GameObject[] bones = new GameObject[_boneCount]; Transform[] bonesT = new Transform[_boneCount]; Matrix4x4[] bindPoses = new Matrix4x4[_boneCount]; for (int i = 0; i < _boneCount; i++) { bones[i] = new GameObject("Bone_" + (i + 1).ToString()); } for (int i = 0; i < _boneCount; i++) { float r = (float)i / (_boneCount - 1); var boneT = bones[i].transform; bonesT[i] = boneT; boneT.parent = transform; // Set the position relative to the parent boneT.localRotation = Quaternion.identity; boneT.localPosition = new Vector3(r * _length, 0, 0); // The bind pose is bone's inverse transformation matrix // In this case the matrix we also make this matrix relative to the root // So that we can move the root game object around freely bindPoses[i] = boneT.worldToLocalMatrix * transform.localToWorldMatrix; } for (int i = 0; i < _boneCount; i++) { var bone = bones[i]; var rigid = bone.AddComponent <Rigidbody>(); rigid.mass = _massOfBone; if (i == 0) { rigid.isKinematic = true; } else { float unitHeight = _length / (_boneCount - 1); var collider = bone.AddComponent <CapsuleCollider>(); collider.radius = _colliderRadius; collider.height = unitHeight; collider.center = new Vector3(-unitHeight / 2, 0, 0); collider.direction = 0; var joint = bone.AddComponent <ConfigurableJoint>(); joint.connectedBody = bones[i - 1].GetComponent <Rigidbody>(); joint.projectionMode = JointProjectionMode.PositionAndRotation; joint.xMotion = ConfigurableJointMotion.Locked; joint.yMotion = ConfigurableJointMotion.Locked; joint.zMotion = ConfigurableJointMotion.Locked; bool firstBoneRistrict = i != 1 | _restrictFirstBone; if (firstBoneRistrict & _jointAngleLimit > 0f) { joint.angularYMotion = ConfigurableJointMotion.Limited; joint.angularZMotion = ConfigurableJointMotion.Limited; } else { joint.angularYMotion = ConfigurableJointMotion.Free; joint.angularZMotion = ConfigurableJointMotion.Free; } if (firstBoneRistrict & _rotateAngleLimit > 0f) { joint.angularXMotion = ConfigurableJointMotion.Limited; } else { joint.angularXMotion = ConfigurableJointMotion.Free; } joint.angularXLimitSpring = new SoftJointLimitSpring { spring = 1000f, damper = 100f, }; joint.autoConfigureConnectedAnchor = false; joint.connectedAnchor = new Vector3(0, 0, 0); joint.anchor = new Vector3(-unitHeight, 0, 0); var xLowLimits = joint.lowAngularXLimit; xLowLimits.limit = -_rotateAngleLimit; joint.lowAngularXLimit = xLowLimits; var xHighLimits = joint.highAngularXLimit; xHighLimits.limit = _rotateAngleLimit; joint.highAngularXLimit = xHighLimits; var zLimits = joint.angularZLimit; zLimits.limit = _jointAngleLimit; joint.angularZLimit = zLimits; var yLimits = joint.angularYLimit; yLimits.limit = _jointAngleLimit; joint.angularYLimit = yLimits; var angularDrive = new JointDrive(); float psr = (float)(i - 1) / (_boneCount - 2); angularDrive.positionSpring = Mathf.Lerp(_angularDriveSpringStart, _angularDriveSpringStop, psr); angularDrive.maximumForce = float.MaxValue; joint.slerpDrive = angularDrive; joint.rotationDriveMode = RotationDriveMode.Slerp; } } // assign the bindPoses array to the bindposes array which is part of the mesh. mesh.bindposes = bindPoses; // Assign bones and bind poses rend.bones = bonesT; rend.sharedMesh = mesh; return(new RopeGenerationResult { Mesh = mesh, Bones = bones, }); }