Ejemplo n.º 1
0
        /// <summary>
        /// Set the visuals of <pararef name="partObject"/> to use <paramref name="meshDetails"/>.
        /// </summary>
        /// <param name="partObject">The part object</param>
        /// <param name="meshDetails">The mesh details.</param>
        /// <remarks>
        /// Adds multiple children to <paramref name="partObject"/> when <paramref name="meshDetails"/>
        /// contains multiple mesh objects.
        /// </remarks>
        protected virtual void SetMesh(ShapeComponent partObject, MeshCache.MeshDetails meshDetails)
        {
            // Clear all children as a hard reset.
            foreach (Transform child in partObject.GetComponentsInChildren <Transform>())
            {
                if (child.gameObject != partObject.gameObject)
                {
                    child.parent = null;
                    GameObject.Destroy(child.gameObject);
                }
            }

            // Add children for each mesh sub-sub-part.
            int subPartNumber = 0;

            foreach (Mesh mesh in meshDetails.FinalMeshes)
            {
                GameObject partMesh = new GameObject();
                partMesh.name = string.Format("sub-part{0}", subPartNumber);
                partMesh.transform.localPosition = meshDetails.LocalPosition;
                partMesh.transform.localRotation = meshDetails.LocalRotation;
                partMesh.transform.localScale    = meshDetails.LocalScale;

                MeshFilter filter = partMesh.AddComponent <MeshFilter>();
                filter.sharedMesh = mesh;

                MeshRenderer renderer = partMesh.AddComponent <MeshRenderer>();
                renderer.material       = meshDetails.Material;
                renderer.material.color = partObject.Colour;
                partMesh.transform.SetParent(partObject.transform, false);

                ++subPartNumber;
            }
        }
Ejemplo n.º 2
0
        protected void RegisterForMesh(CreateMessage shape, PartSet partSet)
        {
            for (int i = 0; i < partSet.MeshIDs.Length; ++i)
            {
                List <PartSet> parts = null;
                if (!_registeredParts.TryGetValue(partSet.MeshIDs[i], out parts))
                {
                    // Add new list.
                    parts = new List <PartSet>();
                    _registeredParts.Add(partSet.MeshIDs[i], parts);
                }

                parts.Add(partSet);

                // Resolve the mesh.
                if (_meshCache != null)
                {
                    MeshCache.MeshDetails meshDetails = _meshCache.GetEntry(partSet.MeshIDs[i]);
                    UpdateMesh(partSet, i, meshDetails);
                    if (meshDetails != null && meshDetails.Finalised)
                    {
                        partSet.Meshes[i] = meshDetails;
                        BindMaterial(partSet, i);
                    }
                }
            }
        }
Ejemplo n.º 3
0
 protected void UpdateMesh(PartSet partSet, int index, MeshCache.MeshDetails meshDetails)
 {
     if (meshDetails != null && meshDetails.Finalised)
     {
         partSet.Meshes[index] = meshDetails;
         // Select a material override if required.
     }
     else
     {
         partSet.Meshes[index]            = null;
         partSet.MaterialOverrides[index] = null;
     }
 }
        /// <summary>
        /// Mesh resource removal notification.
        /// </summary>
        /// <param name="meshDetails">The mesh(es) being removed.</param>
        /// <remarks>
        /// Stops referencing the associated mesh objects.
        /// </remarks>
        protected virtual void OnMeshRemoved(MeshCache.MeshDetails meshDetails)
        {
            // Find objects using the removed mesh.
            List <PointsComponent> parts;

            if (!_registeredParts.TryGetValue(meshDetails.ID, out parts))
            {
                // Nothing using this mesh.
                return;
            }

            // Have things using this mesh. Clear them.
            foreach (PointsComponent part in parts)
            {
                part.Mesh = null;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Mesh resource completion notification.
        /// </summary>
        /// <param name="meshDetails">The mesh(es) finalised.</param>
        /// <remarks>
        /// Links objects waiting on <paramref name="meshDetails"/> to use the associated meshes.
        /// </remarks>
        protected virtual void OnMeshFinalised(MeshCache.MeshDetails meshDetails)
        {
            // Find any parts waiting on this mesh.
            List <PointsComponent> parts;

            if (!_registeredParts.TryGetValue(meshDetails.ID, out parts))
            {
                // Nothing waiting.
                return;
            }

            // Have parts to resolve.
            foreach (PointsComponent part in parts)
            {
                part.MeshDirty = true;
                _awaitingFinalisation.Add(part);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Mesh resource removal notification.
        /// </summary>
        /// <param name="meshDetails">The mesh(es) being removed.</param>
        /// <remarks>
        /// Stops referencing the associated mesh objects.
        /// </remarks>
        protected virtual void OnMeshRemoved(MeshCache.MeshDetails meshDetails)
        {
            // Find objects using the removed mesh.
            List <ShapeComponent> parts;

            if (!_registeredParts.TryGetValue(meshDetails.ID, out parts))
            {
                // Nothing using this mesh.
                return;
            }

            // Have things using this mesh. Clear them.
            foreach (ShapeComponent part in parts)
            {
                foreach (MeshFilter filter in part.GetComponentsInChildren <MeshFilter>())
                {
                    filter.sharedMesh = null;
                    filter.mesh       = null;
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Ensures mesh objects are finalised.
        /// </summary>
        public override void PreRender()
        {
            base.PreRender();
            // Ensure meshes are finalised.
            PointsComponent points;

            for (int i = 0; i < _awaitingFinalisation.Count; ++i)
            {
                points = _awaitingFinalisation[i];
                if (points.MeshDirty)
                {
                    MeshCache.MeshDetails meshDetails = _meshCache.GetEntry(points.MeshID);
                    if (meshDetails != null && meshDetails.FinalMeshes != null)
                    {
                        // Build the mesh parts.
                        SetMesh(points, meshDetails);
                    }
                    points.MeshDirty = false;
                }
            }

            _awaitingFinalisation.Clear();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Mesh resource removal notification.
        /// </summary>
        /// <param name="meshDetails">The mesh(es) being removed.</param>
        /// <remarks>
        /// Stops referencing the associated mesh objects.
        /// </remarks>
        protected virtual void OnMeshRemoved(MeshCache.MeshDetails meshDetails)
        {
            // Find objects using the removed mesh.
            List <PartSet> parts;

            if (!_registeredParts.TryGetValue(meshDetails.ID, out parts))
            {
                // Nothing using this mesh.
                return;
            }

            // Have things using this mesh. Clear them.
            foreach (PartSet partSet in parts)
            {
                for (int i = 0; i < partSet.MeshIDs.Length; ++i)
                {
                    if (partSet.MeshIDs[i] == meshDetails.ID)
                    {
                        partSet.Meshes[i] = null;
                    }
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Register <paramref name="points"/> for mesh resolving.
        /// </summary>
        /// <remarks>
        /// The mesh is either resolved now, or on mesh finalisation.
        /// Note that any limited indexing must be completed before calling
        /// this function. That is <see cref="PointsComponent.Indices"/>
        /// must have been resolved.
        /// </remarks>
        /// <param name="points">The points component.</param>
        protected void RegisterForMesh(PointsComponent points)
        {
            List <PointsComponent> parts = null;

            if (!_registeredParts.TryGetValue(points.MeshID, out parts))
            {
                // Add new list.
                parts = new List <PointsComponent>();
                _registeredParts.Add(points.MeshID, parts);
            }

            parts.Add(points);

            // Try resolve the mesh from the cache now.
            if (_meshCache != null)
            {
                MeshCache.MeshDetails meshDetails = _meshCache.GetEntry(points.MeshID);
                if (meshDetails != null && meshDetails.Finalised)
                {
                    points.MeshDirty = true;
                    _awaitingFinalisation.Add(points);
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Mesh resource completion notification.
        /// </summary>
        /// <param name="meshDetails">The mesh(es) finalised.</param>
        /// <remarks>
        /// Links objects waiting on <paramref name="meshDetails"/> to use the associated meshes.
        /// </remarks>
        protected virtual void OnMeshFinalised(MeshCache.MeshDetails meshDetails)
        {
            // Find any parts waiting on this mesh.
            List <PartSet> parts;

            if (!_registeredParts.TryGetValue(meshDetails.ID, out parts))
            {
                // Nothing waiting.
                return;
            }

            // Have parts to resolve.
            foreach (PartSet partSet in parts)
            {
                for (int i = 0; i < partSet.MeshIDs.Length; ++i)
                {
                    if (partSet.MeshIDs[i] == meshDetails.ID)
                    {
                        partSet.Meshes[i] = meshDetails;
                        BindMaterial(partSet, i);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Set the visuals of <pararef name="points"/> to use <paramref name="meshDetails"/>.
        /// </summary>
        /// <param name="points">The points object</param>
        /// <param name="meshDetails">The mesh details.</param>
        /// <remarks>
        /// Adds multiple children to <paramref name="points"/> when <paramref name="meshDetails"/>
        /// contains multiple mesh objects.
        /// </remarks>
        protected virtual void SetMesh(PointsComponent points, MeshCache.MeshDetails meshDetails)
        {
            ShapeComponent shape = points.GetComponent <ShapeComponent>();

            // Clear all children as a hard reset.
            foreach (Transform child in points.GetComponentsInChildren <Transform>())
            {
                if (child.gameObject != points.gameObject)
                {
                    child.parent = null;
                    GameObject.Destroy(child.gameObject);
                }
            }

            // Use shared resources if we have no limited indexing.
            if (points.IndexCount == 0)
            {
                // Add children for each mesh sub-sub-part.
                int partNumber = 0;
                foreach (Mesh mesh in meshDetails.FinalMeshes)
                {
                    GameObject partMesh = new GameObject(string.Format("cloud{0}", partNumber));
                    partMesh.transform.localPosition = meshDetails.LocalPosition;
                    partMesh.transform.localRotation = meshDetails.LocalRotation;
                    partMesh.transform.localScale    = meshDetails.LocalScale;
                    partMesh.AddComponent <MeshFilter>().sharedMesh = mesh;

                    MeshRenderer renderer = partMesh.AddComponent <MeshRenderer>();
                    if (meshDetails.Topology == MeshTopology.Points)
                    {
                        // Use mesh material as is.
                        renderer.material = meshDetails.Material;
                    }
                    else
                    {
                        // Rendering a mesh with non-point topology. Set tha points based material.
                        renderer.material = mesh.normals.Length > 0 ? _litMaterial : _unlitMaterial;
                    }
                    int pointSize = points.PointSize;
                    if (pointSize == 0 && Materials != null)
                    {
                        pointSize = Materials.DefaultPointSize;
                    }
                    renderer.material.SetInt("_PointSize", pointSize);
                    renderer.material.SetInt("_LeftHanded", ServerInfo.IsLeftHanded ? 1 : 0);
                    renderer.material.color = (shape != null) ? shape.Colour : new Color32(255, 255, 255, 255);
                    partMesh.transform.SetParent(points.transform, false);
                    ++partNumber;
                }
            }
            else
            {
                // We are going to need to remap the indexing. For this we'll
                // copy the required vertices from the MeshDetails and create new
                // meshes with new indices. We could potentially share vertex data,
                // but this is difficult with the Unity vertex count limit.
                Mesh[] meshes = meshDetails.Builder.GetReindexedMeshes(points.Indices, MeshTopology.Points);
                for (int i = 0; i < meshes.Length; ++i)
                {
                    // Create this mesh piece.
                    bool     defaultMaterial = meshDetails.Topology == MeshTopology.Points;
                    Material material        = (defaultMaterial) ? meshDetails.Material : _unlitMaterial;
                    if (!defaultMaterial && meshDetails.Builder.Normals.Length != 0)
                    {
                        material = _litMaterial;
                    }

                    GameObject child = new GameObject();
                    child.AddComponent <MeshFilter>().mesh = meshes[i];
                    material.SetInt("_PointSize", points.PointSize);
                    material.SetInt("_LeftHanded", ServerInfo.IsLeftHanded ? 1 : 0);
                    child.AddComponent <MeshRenderer>().material = material;
                    child.transform.SetParent(points.transform, false);
                }
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Overridden to read information about mesh parts.
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="packet"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        protected override Error HandleMessage(CreateMessage msg, PacketBuffer packet, BinaryReader reader)
        {
            GameObject obj = null;

            if (msg.ObjectID == 0)
            {
                // Transient object.
                obj = CreateTransient();
            }
            else
            {
                obj = CreateObject(msg.ObjectID);
                if (!obj)
                {
                    // Object already exists.
                    return(new Error(ErrorCode.DuplicateShape, msg.ObjectID));
                }
            }

            ShapeComponent shapeComp = obj.GetComponent <ShapeComponent>();

            if (shapeComp)
            {
                shapeComp.Category    = msg.Category;
                shapeComp.ObjectFlags = msg.Flags;
                shapeComp.Colour      = ShapeComponent.ConvertColour(msg.Attributes.Colour);
            }

            obj.transform.SetParent(Root.transform, false);
            DecodeTransform(msg.Attributes, obj.transform);

            // Read mesh parts.
            ushort meshPartCount = reader.ReadUInt16();

            // Read part IDs
            for (ushort i = 0; i < meshPartCount; ++i)
            {
                Error err = AddMeshPart(obj, reader, i);
                if (err.Failed)
                {
                    return(err);
                }
            }

            foreach (ShapeComponent part in obj.GetComponentsInChildren <ShapeComponent>())
            {
                if (part.gameObject != obj)
                {
                    List <ShapeComponent> parts = null;
                    if (!_registeredParts.TryGetValue(part.ObjectID, out parts))
                    {
                        // Add new list.
                        parts = new List <ShapeComponent>();
                        _registeredParts.Add(part.ObjectID, parts);
                    }

                    parts.Add(part);

                    // Try resolve the mesh part.
                    if (_meshCache != null)
                    {
                        MeshCache.MeshDetails meshDetails = _meshCache.GetEntry(part.ObjectID);
                        if (meshDetails != null && meshDetails.Finalised)
                        {
                            part.Dirty = true;
                            _awaitingFinalisation.Add(part);
                            //SetMesh(part, meshDetails);
                        }
                    }
                }
            }

            return(new Error());
        }