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);
            }
        }
Example #2
0
    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;
    }
Example #3
0
 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);
 }
Example #4
0
        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);
            }
        }
Example #5
0
    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();
        }
    }
Example #6
0
        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;
            }
        }
Example #7
0
        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;
                }
            }
        }
Example #8
0
        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;
                }
            }
        }
Example #9
0
    // === 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);
    }
Example #10
0
        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,
            });
        }