Esempio n. 1
0
        protected override void OnUpdate()
        {
            // UI text conversion
            Entities.ForEach((TextMeshProUGUI displayText) =>
            {
                // We are converting an entity (textEntity) and creating another (eSubText).
                // Why?
                // We want to use the Rectangle Transform system to also position text, rather
                // than introduce something special. So we need a parent element that is the frame
                // of the text (textEntity) and a child element that has a pivet on the text string
                // itself. Systems later will process the child element.

                var textEntity = GetPrimaryEntity(displayText);

                // Sub-text child transform
                SceneSection sceneSection = DstEntityManager.GetSharedComponentData <SceneSection>(textEntity);
                var eSubText = DstEntityManager.CreateEntity();
                DstEntityManager.AddSharedComponentData(eSubText, sceneSection);

                DstEntityManager.AddComponentData(eSubText, new Tiny.UI.RectTransform
                {
                    AnchorMin        = 0.5f,
                    AnchorMax        = 0.5f,
                    SizeDelta        = 1f,
                    AnchoredPosition = 0f,
                    Pivot            = 0.5f
                });

                DstEntityManager.AddComponentData(eSubText, new UIName()
                {
                    Name = displayText.name
                });

                DstEntityManager.AddComponentData(eSubText, new RectParent()
                {
                    Value = textEntity
                });

                DstEntityManager.AddComponentData(eSubText, new Unity.Tiny.Rendering.CameraMask
                {
                    mask = (ulong)(1 << displayText.gameObject.layer)
                });

                DstEntityManager.AddComponent <RectTransformResult>(eSubText);

                var fontAsset = GetPrimaryEntity(displayText.font);
                DstEntityManager.AddComponentData(eSubText, new Tiny.Text.TextRenderer
                {
                    FontMaterial        = fontAsset,
                    MeshColor           = displayText.color.linear.ToTiny(),
                    Size                = displayText.fontSize * 10,
                    HorizontalAlignment = ConvertHorizontalAlignment(displayText.alignment),
                    VerticalAlignment   = ConvertVerticalAlignment(displayText.alignment),
                });

                var text = displayText.text;
                DstEntityManager.AddBufferFromString <TextRendererString>(eSubText, text);
                DstEntityManager.AddComponent <LocalToWorld>(eSubText);
            });
        }
Esempio n. 2
0
    protected override void OnUpdate()
    {
        Entities.ForEach((ModifyJointLimitsAuthoring modifyJointLimits) =>
        {
            foreach (var jointAuthoringComponent in modifyJointLimits.GetComponents <Component>())
            {
                // apply modification to joints produced by legacy Joint and BaseJoint
                if (jointAuthoringComponent as LegacyJoint == null && jointAuthoringComponent as BaseJoint == null)
                {
                    continue;
                }

                var jointEntities = new NativeList <Entity>(16, Allocator.Temp);
                World.GetOrCreateSystem <EndJointConversionSystem>().GetJointEntities(jointAuthoringComponent, jointEntities);
                foreach (var jointEntity in jointEntities)
                {
                    var angularModification = new ParticleSystem.MinMaxCurve(
                        multiplier: math.radians(modifyJointLimits.AngularRangeScalar.curveMultiplier),
                        min: modifyJointLimits.AngularRangeScalar.curveMin,
                        max: modifyJointLimits.AngularRangeScalar.curveMax
                        );
                    DstEntityManager.AddSharedComponentData(jointEntity, new ModifyJointLimits
                    {
                        InitialValue       = DstEntityManager.GetComponentData <PhysicsJoint>(jointEntity),
                        AngularRangeScalar = angularModification,
                        LinearRangeScalar  = modifyJointLimits.LinearRangeScalar
                    });
                }
            }
        });
    }
        private void ConvertCanvas(Canvas canvas)
        {
            var             entity = GetPrimaryEntity(canvas);
            CanvasSortLayer image  = new CanvasSortLayer
            {
                Value = canvas.sortingOrder
            };

            DstEntityManager.AddComponentData(entity, image);
            DstEntityManager.AddComponent(entity, typeof(RebuildCanvasHierarchyFlag));
            DstEntityManager.AddBuffer <MeshVertex>(entity);
            DstEntityManager.AddBuffer <MeshVertexIndex>(entity);
            DstEntityManager.AddBuffer <SubMeshInfo>(entity);
            if (canvas.renderMode != RenderMode.ScreenSpaceCamera)
            {
                throw new InvalidOperationException($"Canvas ({canvas}) render mode ({canvas.renderMode}) is not supported yet");
            }
            if (canvas.worldCamera == null)
            {
                throw new InvalidOperationException($"Target camera is null or destroyed. Canvas {canvas}");
            }
            var proxy = canvas.worldCamera.GetComponent <CameraImageRenderProxy>();

            if (proxy == null)
            {
                proxy = canvas.worldCamera.gameObject.AddComponent <CameraImageRenderProxy>();
            }
            DstEntityManager.AddSharedComponentData(entity, new CanvasTargetCamera()
            {
                Target = proxy
            });
        }
Esempio n. 4
0
        protected override void OnUpdate()
        {
            Entities.ForEach((BoidAuthoring boidAuthoring) =>
            {
                var entity = GetPrimaryEntity(boidAuthoring);

                DstEntityManager.AddSharedComponentData(entity, new Boid
                {
                    CellRadius               = boidAuthoring.CellRadius,
                    SeparationWeight         = boidAuthoring.SeparationWeight,
                    AlignmentWeight          = boidAuthoring.AlignmentWeight,
                    TargetWeight             = boidAuthoring.TargetWeight,
                    ObstacleAversionDistance = boidAuthoring.ObstacleAversionDistance,
                    MoveSpeed = boidAuthoring.MoveSpeed
                });

                // Remove default transform system components
                DstEntityManager.RemoveComponent <Translation>(entity);
                DstEntityManager.RemoveComponent <Rotation>(entity);

                // Add world render bounds components so they do not need to be added at initialization time.
                DstEntityManager.AddComponent(entity, ComponentType.ChunkComponent <ChunkWorldRenderBounds>());
                DstEntityManager.AddComponent <WorldRenderBounds>(entity);
            });
        }
Esempio n. 5
0
        Entity ConstructScreenSpaceCamera(Entity e, UnityEngine.RectTransform urc)
        {
            SceneSection sceneSection = DstEntityManager.GetSharedComponentData <SceneSection>(e);
            Entity       eCam         = DstEntityManager.CreateEntity();

            DstEntityManager.AddSharedComponentData(eCam, sceneSection);

            var sizeDelta = urc.sizeDelta;

            var camera = new Unity.Tiny.Rendering.Camera
            {
                clearFlags      = Tiny.Rendering.CameraClearFlags.DepthOnly,
                backgroundColor = new Unity.Tiny.Color(0, 0, 0, 0),
                viewportRect    = new Tiny.Rect(0, 0, 1, 1),
                depth           = 0.0f,
                fov             = sizeDelta.y * 0.5f,
                mode            = ProjectionMode.Orthographic,
                clipZNear       = 0,
                clipZFar        = 102,
                aspect          = sizeDelta.x / sizeDelta.y
            };

            DstEntityManager.AddComponentData(eCam, camera);
            DstEntityManager.AddComponentData(eCam,
                                              new Unity.Tiny.Rendering.CameraMask {
                mask = (ulong)(1 << urc.gameObject.layer)
            });

            // For CameraSettings2D
            float3 customSortAxisSetting = new float3(0, 0, 1.0f);

            if (UnityEngine.Rendering.GraphicsSettings.transparencySortMode ==
                UnityEngine.TransparencySortMode.CustomAxis)
            {
                customSortAxisSetting = UnityEngine.Rendering.GraphicsSettings.transparencySortAxis;
            }
            DstEntityManager.AddComponentData(eCam, new Unity.Tiny.Rendering.CameraSettings2D
            {
                customSortAxis = customSortAxisSetting
            });

            // tag the camera as auto aspect
            DstEntityManager.AddComponentData(eCam, new CameraAutoAspectFromNode {
                Node = Entity.Null
            });

            DstEntityManager.AddComponentData(eCam, new LocalToWorld {
                Value = float4x4.identity
            });
            DstEntityManager.AddComponentData(eCam,
                                              new Translation {
                Value = new float3(sizeDelta.x / 2, sizeDelta.y / 2, -10)
            });
            DstEntityManager.AddComponentData(eCam, new Rotation {
                Value = quaternion.identity
            });
            DstEntityManager.AddComponent <UICamera>(eCam);
            return(eCam);
        }
Esempio n. 6
0
        private void ConvertSprite(Sprite sprite)
        {
            var assetEntity = GetPrimaryEntity(sprite);

            DstEntityManager.AddSharedComponentData(assetEntity, new SpriteAsset {
                Value = sprite
            });
            DstEntityManager.AddComponent <SpriteVertexData>(assetEntity);
        }
Esempio n. 7
0
 protected override void OnUpdate()
 {
     Entities.ForEach((UnityEngine.Sprite sprite) =>
     {
         var proxyEntity = GetPrimaryEntity(sprite);
         DstEntityManager.AddSharedComponentData(proxyEntity, new SpriteProxy
         {
             Sprite = sprite
         });
     });
 }
 protected override void OnUpdate()
 {
     Entities.ForEach((UnityEngine.Material uMaterial) =>
     {
         var proxyEntity = GetPrimaryEntity(uMaterial);
         DstEntityManager.AddSharedComponentData(proxyEntity, new Material2DProxy
         {
             Material = uMaterial
         });
     });
 }
    private void Convert(Camera cam)
    {
        var entity = GetPrimaryEntity(cam);

        AddHybridComponent(cam);

        DstEntityManager.AddSharedComponentData(entity, new HybridCamera
        {
            Camera = cam
        });
    }
Esempio n. 10
0
 protected override void OnUpdate()
 {
     Entities
     .ForEach((ColorSharedComponentTest c) =>
     {
         var e     = GetPrimaryEntity(c);
         var color = new float4(c.color.r, c.color.g, c.color.b, c.color.a);
         DstEntityManager.AddSharedComponentData(e, new ColorSharedComponent {
             Value = color
         });
     });
 }
        protected override void OnUpdate()
        {
            Entities.ForEach((Canvas canvas) => {
                var parent = canvas.transform.parent;
                if (parent != null)
                {
#if UNITY_EDITOR
                    UnityEditor.EditorGUIUtility.PingObject(canvas);
#endif
                    throw new NotSupportedException($"{canvas.name} is child of {parent.name}, this is not supported!");
                }

                var entity       = GetPrimaryEntity(canvas);
                var canvasScaler = canvas.GetComponent <CanvasScaler>();

                DstEntityManager.RemoveComponent <Anchor>(entity);
                DstEntityManager.AddSharedComponentData(entity, new CanvasSortOrder {
                    Value = canvas.sortingOrder
                });
                DstEntityManager.AddComponentData(entity, new DirtyTag {
                });

                if (!sortOrders.Contains(canvas.sortingOrder))
                {
                    sortOrders.Add(canvas.sortingOrder);
                }

                switch (canvasScaler.uiScaleMode)
                {
                case CanvasScaler.ScaleMode.ScaleWithScreenSize:
                    DstEntityManager.AddComponentData(entity, new ReferenceResolution {
                        Value = canvasScaler.referenceResolution
                    });

                    // TODO: Should figure out if I want to support shrinking and expanding only...
                    if (canvasScaler.screenMatchMode == CanvasScaler.ScreenMatchMode.MatchWidthOrHeight)
                    {
                        DstEntityManager.AddComponentData(entity, new WidthHeightRatio {
                            Value = canvasScaler.matchWidthOrHeight
                        });
                    }
                    else
                    {
                        throw new NotSupportedException($"{canvasScaler.screenMatchMode} is not supported!");
                    }
                    break;

                default:
                    throw new NotSupportedException($"{canvasScaler.uiScaleMode} is not supported!");
                }
            });
        }
Esempio n. 12
0
        protected override void OnUpdate()
        {
            ForEach((MeshRenderer meshRenderer, MeshFilter meshFilter) =>
            {
                var entity = GetPrimaryEntity(meshRenderer);

                var dst            = new RenderMesh();
                dst.mesh           = meshFilter.sharedMesh;
                dst.castShadows    = meshRenderer.shadowCastingMode;
                dst.receiveShadows = meshRenderer.receiveShadows;

                var materials = meshRenderer.sharedMaterials;

                if (materials.Length == 1 && AttachToPrimaryEntityForSingleMaterial)
                {
                    dst.material = materials[0];
                    dst.subMesh  = 0;

                    DstEntityManager.AddSharedComponentData(entity, dst);
                    DstEntityManager.AddComponentData(entity, new PerInstanceCullingTag());
                }
                else
                {
                    for (int m = 0; m != materials.Length; m++)
                    {
                        var meshEntity = CreateAdditionalEntity(meshRenderer);

                        dst.material = materials[m];
                        dst.subMesh  = m;

                        DstEntityManager.AddSharedComponentData(meshEntity, dst);
                        DstEntityManager.AddComponentData(meshEntity, new PerInstanceCullingTag());

                        //@TODO: Shouldn't be necessary to add Position Component, but looks like TransformSystem doesn't setup LocalToWorld otherwise...
                        DstEntityManager.AddComponentData(meshEntity, new Position());

                        // Parent it
                        var attach = CreateAdditionalEntity(meshRenderer);
                        DstEntityManager.AddComponentData(attach, new Attach {
                            Parent = entity, Child = meshEntity
                        });
                    }
                }


                //@TODO: Transform system should handle RenderMeshFlippedWindingTag
                // Flag this thing as positively or negatively scaled, so we can batch the renders correctly for the static case.
                //if (math.determinant(localToWorld) < 0.0)
                //    entityManager.AddComponent(meshEnt, ComponentType.Create<RenderMeshFlippedWindingTag>());
            });
        }
        protected override void OnUpdate()
        {
            Entities.ForEach((TextMeshPro textMesh, MeshFilter meshFilter) => {
                // We must disable the text mesh for it to be skipped by MeshRenderer conversion system
                meshFilter.mesh = null;
                var font        = textMesh.font;
                var entity      = GetPrimaryEntity(textMesh);
                if (!m_textFontAssets.TryGetValue(font, out var fontEntity))
                {
                    fontEntity = TextUtility.CreateTextFontAsset(DstEntityManager, font);
                    m_textFontAssets.Add(font, fontEntity);
                }

                DstEntityManager.AddSharedComponentData(entity, new FontMaterial {
                    Value = font.material
                });
                var materialId = DstEntityManager.GetSharedComponentDataIndex <FontMaterial>(entity);

                DstEntityManager.AddComponentData(entity, new TextRenderer()
                {
                    Font       = fontEntity,
                    MaterialId = materialId,
                    Size       = textMesh.fontSize,
                    Alignment  = textMesh.alignment,
                    Bold       = (textMesh.fontStyle & FontStyles.Bold) == FontStyles.Bold,
                    Italic     = (textMesh.fontStyle & FontStyles.Italic) == FontStyles.Italic
                });
                DstEntityManager.AddComponentData(entity, new TextData {
                    Value = textMesh.text
                });
                DstEntityManager.AddComponentData(entity, new VertexColor()
                {
                    Value = textMesh.color.ToFloat4()
                });
                DstEntityManager.AddComponentData(entity, new VertexColorMultiplier()
                {
                    Value = new float4(1.0f, 1.0f, 1.0f, 1.0f)
                });
                DstEntityManager.AddBuffer <Vertex>(entity);
                DstEntityManager.AddBuffer <VertexIndex>(entity);
                DstEntityManager.AddBuffer <TextLine>(entity);
                if (!DstEntityManager.HasComponent <RenderBounds>(entity))
                {
                    // RenderBounds will be calculated on TextMeshBuildSystem
                    DstEntityManager.AddComponentData(entity, default(RenderBounds));
                }
            });
        }
Esempio n. 14
0
        protected override void OnUpdate()
        {
            if (Settings == null)
            {
                return;
            }

            if (TryGetBuildConfigurationComponent <DotsRuntimeBuildProfile>(out var profile))
            {
                if (profile.UseNewPipeline)
                {
                    if (!IsExportingRootScene())
                    {
                        return;
                    }
                }
            }

            // Get render settings from the current active scene
            Entity e = DstEntityManager.CreateEntity();

            // Render settings should go into the main section of the subscene they are coming from
            DstEntityManager.AddSharedComponentData(e, new SceneSection()
            {
                SceneGUID = Settings.SceneGUID, Section = 0
            });

            // Ambient light
            DstEntityManager.AddComponentData <Unity.Tiny.Rendering.Light>(e, new Unity.Tiny.Rendering.Light()
            {
                color     = new float3(RenderSettings.ambientLight.r, RenderSettings.ambientLight.g, RenderSettings.ambientLight.b),
                intensity = 1.0f
            });
            DstEntityManager.AddComponent <Unity.Tiny.Rendering.AmbientLight>(e);

            // Fog
            var fogLinear = RenderSettings.fogColor.linear;

            DstEntityManager.AddComponentData <Unity.Tiny.Rendering.Fog>(e, new Unity.Tiny.Rendering.Fog()
            {
                mode          = RenderSettings.fogMode.ToTiny(RenderSettings.fog),
                color         = new float4(fogLinear.r, fogLinear.g, fogLinear.b, fogLinear.a),
                density       = RenderSettings.fogDensity,
                startDistance = RenderSettings.fogStartDistance,
                endDistance   = RenderSettings.fogEndDistance
            });
        }
Esempio n. 15
0
        protected override void OnUpdate()
        {
            Entities.ForEach((BoidAuthoring boidAuthoring) =>
            {
                var entity = GetPrimaryEntity(boidAuthoring);

                DstEntityManager.AddSharedComponentData(entity, new Boid
                {
                    CellRadius           = boidAuthoring.CellRadius,
                    SeparationWeight     = boidAuthoring.SeparationWeight,
                    AlignmentWeight      = boidAuthoring.AlignmentWeight,
                    TargetWeight         = boidAuthoring.TargetWeight,
                    OuterDetectionRadius = boidAuthoring.OuterDetectionRadius,
                    InnerDetectionRadius = boidAuthoring.InnerDetectionRadius,
                    MoveSpeed            = boidAuthoring.MoveSpeed,
                    WanderRadius         = boidAuthoring.WanderRadius,
                    WanderWeight         = boidAuthoring.WanderWeight,
                    VisionAngle          = boidAuthoring.VisionAngle,
                    NavigationRayCount   = boidAuthoring.NavigationRayCount,
                });
                DynamicBuffer <Float3BufferElement> buffer = DstEntityManager.AddBuffer <Float3BufferElement>(entity);
                DynamicBuffer <float3> floatBuffer         = buffer.Reinterpret <float3>();

                for (int i = 0; i < boidAuthoring.NavigationRayCount; i++)
                {
                    float turnFraction = 0.6180f;
                    float t            = i / (boidAuthoring.NavigationRayCount - 1f);
                    float phi          = math.acos(1f - 2f * t);
                    float theta        = 2 * math.PI * turnFraction * i;

                    float x  = math.sin(phi) * math.cos(theta);
                    float y  = math.sin(phi) * math.sin(theta);
                    float z  = math.cos(phi);
                    float3 p = new float3(x, y, z);
                    if (math.acos(math.dot(p, new float3(0, 0, 1))) < boidAuthoring.VisionAngle)
                    {
                        floatBuffer.Add(p);
                    }
                }

                // Remove default transform system components
                DstEntityManager.RemoveComponent <Translation>(entity);
                DstEntityManager.RemoveComponent <Rotation>(entity);
            });
        }
Esempio n. 16
0
        private void SetUpScreenSpaceCamera(Canvas canvas, Entity entity)
        {
            if (canvas.worldCamera == null)
            {
                throw new InvalidOperationException($"Target camera is null or destroyed. Canvas {canvas}");
            }
            var proxy = canvas.worldCamera.GetComponent <CameraImageRenderProxy>();

            if (proxy == null)
            {
                proxy = canvas.worldCamera.gameObject.AddComponent <CameraImageRenderProxy>();
            }
            DstEntityManager.AddSharedComponentData(entity, new CanvasTargetCamera()
            {
                Target = proxy
            });
            DstEntityManager.AddComponentData(entity, new CanvasScreenSize
            {
                Value = new int2(canvas.worldCamera.pixelWidth, canvas.worldCamera.pixelHeight)
            });
        }
Esempio n. 17
0
        protected override void OnUpdate()
        {
            Entities.ForEach((BoidAuthoring boidAuthoring) =>
            {
                var entity = GetPrimaryEntity(boidAuthoring);

                DstEntityManager.AddSharedComponentData(entity, new Boid
                {
                    CellRadius               = boidAuthoring.CellRadius,
                    SeparationWeight         = boidAuthoring.SeparationWeight,
                    AlignmentWeight          = boidAuthoring.AlignmentWeight,
                    TargetWeight             = boidAuthoring.TargetWeight,
                    ObstacleAversionDistance = boidAuthoring.ObstacleAversionDistance,
                    MoveSpeed = boidAuthoring.MoveSpeed
                });

                // Remove default transform system components
                DstEntityManager.RemoveComponent <Translation>(entity);
                DstEntityManager.RemoveComponent <Rotation>(entity);
            });
        }
Esempio n. 18
0
        protected unsafe override void OnUpdate()
        {
            var    contexts     = new NativeList <UIContextData>(8, Allocator.TempJob);
            var    graphData    = new NativeList <UIGraphData>(8, Allocator.TempJob);
            Entity schemaEntity = Entity.Null;
            int    nodeCount    = 0;

            meshes.Clear();
            Entities.ForEach((UIObject obj) =>
            {
                //TODO: Writes every conversion frame but will crash under certain conditions otherwise. Crashes observed involving opening and closing subscenes without modifying anything after script reload.

                var guid = obj.model?.GetOutputGuid();

                if (!string.IsNullOrEmpty(guid))
                {
                    IntPtr ptr;
                    long allocatedLength;
                    using (var fs = File.OpenRead(UnityEditor.AssetDatabase.GUIDToAssetPath(guid))) {
                        allocatedLength = math.ceilpow2(fs.Length);
                        ptr             = (IntPtr)UnsafeUtility.Malloc(allocatedLength, 0, Allocator.Persistent);
                        using (var us = new UnmanagedMemoryStream((byte *)ptr.ToPointer(), 0, fs.Length, FileAccess.Write)) {
                            fs.CopyTo(us);
                        }
                    }
                    var gd = new UIGraphData {
                        value = ptr, allocatedLength = allocatedLength
                    };
                    graphData.Add(gd);
                    nodeCount += gd.GetNodeCount();
                    contexts.Add(UIContextData.CreateContext(obj.camera));
                    meshes.Add(new Mesh());
                    if (schemaEntity == Entity.Null)
                    {
                        schemaEntity = CreateAdditionalEntity(obj);
                        DstEntityManager.SetName(schemaEntity, "UI Schema");
                        DstEntityManager.AddSharedComponentData(schemaEntity, new UISchemaData {
                            value = schema
                        });
                    }
                    DeclareAssetDependency(obj.gameObject, schema);
                }
                obj.cachedGuid = guid;
            });

            if (graphData.Length > 0)
            {
                var graphDataArray = graphData.AsArray();
                var meshData       = Mesh.AllocateWritableMeshData(graphData.Length);
                var submeshes      = new NativeArray <int>(graphData.Length, Allocator.TempJob);
                var stream         = new NativeStream(nodeCount, Allocator.TempJob);
                new UILayoutJob
                {
                    schema        = compiledSchema,
                    graphs        = graphDataArray,
                    contexts      = contexts,
                    meshDataArray = meshData
                }.Schedule(graphData.Length, 1).Complete();
                new UINodeDecompositionJob
                {
                    schema       = compiledSchema,
                    graphs       = graphDataArray,
                    nodes        = stream.AsWriter(),
                    submeshCount = submeshes
                }.Schedule(graphData.Length, 1).Complete();
                Mesh.ApplyAndDisposeWritableMeshData(meshData, meshes);
                var result = stream.ToNativeArray <DedicatedNodeInfo>(Allocator.Temp);
                var nodes  = new NativeMultiHashMap <int, DedicatedNodeInfo>(graphData.Length, Allocator.Temp);
                for (int i = 0; i < result.Length; i++)
                {
                    nodes.Add(result[i].graphIndex, result[i]);
                }
                stream.Dispose();
                submeshes.Dispose();
                int index        = 0;
                var nodeEntities = new NativeList <Entity>(Allocator.Temp);
                Entities.ForEach((UIObject obj) =>
                {
                    if (!string.IsNullOrEmpty(obj.cachedGuid))
                    {
                        var entity = GetPrimaryEntity(obj);
                        var gd     = graphDataArray[index];
                        DstEntityManager.AddComponentData(entity, new UIGraph {
                            value = new BlittableAssetReference(obj.cachedGuid)
                        });
                        DstEntityManager.AddSharedComponentData <UIDirtyState>(entity, false);
                        Material material;
                        if (gd.TryGetConfigBlock(0, UIConfigLayoutTable.MaterialConfig, out IntPtr result))
                        {
                            material = UnityEditor.AssetDatabase.LoadAssetAtPath <Material>(UnityEditor.AssetDatabase.GUIDToAssetPath(((MaterialConfig *)(result.ToPointer()))->material.ToHex()));
                        }
                        else
                        {
                            material = obj.model.GetMaterial();
                        }



                        DeclareAssetDependency(obj.gameObject, obj.model);


                        DeclareAssetDependency(obj.gameObject, material);

                        DstEntityManager.AddSharedComponentData(entity, new RenderMesh
                        {
                            mesh                 = meshes[index],
                            material             = material,
                            subMesh              = 0,
                            castShadows          = ShadowCastingMode.Off,
                            receiveShadows       = false,
                            needMotionVectorPass = false,
                            layer                = obj.gameObject.layer
                        });
                        DstEntityManager.AddComponentData(entity, new UIPixelScale {
                            value = obj.pixelScale
                        });
                        var bounds = meshes[index].GetSubMesh(0).bounds.ToAABB();
                        DstEntityManager.AddComponentData(entity, new RenderBounds {
                            Value = bounds
                        });

                        DstEntityManager.AddComponent <UIContext>(entity);

                        if (obj.camera != null)
                        {
                            DstEntityManager.AddComponentData(entity, new UIContextSource {
                                value = GetPrimaryEntity(obj.camera)
                            });
                            var ltc = new LocalToCamera
                            {
                                cameraLTW = obj.camera.transform.localToWorldMatrix,
                                clipPlane = new float2(obj.camera.nearClipPlane, obj.camera.farClipPlane),
                                alignment = obj.alignment,
                                offsetX   = obj.offsetX,
                                offsetY   = obj.offsetY
                            };
                            DstEntityManager.AddComponentData(entity, ltc);
                            var rotation  = quaternion.LookRotation(ltc.cameraLTW.c2.xyz, ltc.cameraLTW.c1.xyz);
                            var translate = ltc.cameraLTW.c3.xyz + new float3(ltc.alignment.GetOffset(bounds.Size.xy, new float2(Screen.currentResolution.height * obj.camera.aspect, Screen.currentResolution.height)), 0) + math.mul(rotation, math.forward() * ltc.clipPlane.x * 2f) + (math.mul(rotation, math.right()) * ltc.offsetX.Normalize(contexts[index])) + (math.mul(rotation, math.up()) * ltc.offsetY.Normalize(contexts[index]));
                            DstEntityManager.SetComponentData(entity, new LocalToWorld {
                                Value = float4x4.TRS(translate, rotation, obj.pixelScale)
                            });
                            DeclareDependency(obj, obj.camera);
                        }

                        DstEntityManager.AddComponent <PerInstanceCullingTag>(entity);

                        nodeEntities.Clear();
                        var nodeInfoIter = nodes.GetValuesForKey(index);
                        while (nodeInfoIter.MoveNext())
                        {
                            var nodeInfo   = nodeInfoIter.Current;
                            var nodeEntity = CreateAdditionalEntity(obj);
                            var name       = graphData[index].GetNodeName(nodeInfo.nodeIndex);
                            if (string.IsNullOrEmpty(name))
                            {
                                name = $"Node#{nodeInfo.nodeIndex}";
                            }
                            DstEntityManager.SetName(nodeEntity, $"{DstEntityManager.GetName(entity)}[{name}]");
                            DstEntityManager.AddComponentData(nodeEntity, new UINodeInfo {
                                index = nodeInfo.nodeIndex, submesh = nodeInfo.submesh
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new UIParent {
                                value = entity
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new Parent {
                                Value = entity
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new LocalToWorld {
                                Value = float4x4.identity
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new Rotation {
                                Value = quaternion.identity
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new Scale {
                                Value = 1f
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new LocalToParent {
                                Value = float4x4.identity
                            });
                            if (gd.TryGetConfigBlock(0, UIConfigLayoutTable.MaterialConfig, out result))
                            {
                                material = UnityEditor.AssetDatabase.LoadAssetAtPath <Material>(UnityEditor.AssetDatabase.GUIDToAssetPath(((MaterialConfig *)result.ToPointer())->material.ToHex()));
                            }
                            else
                            {
                                material = obj.model.GetMaterial();
                            }
                            DstEntityManager.AddSharedComponentData(nodeEntity, new RenderMesh
                            {
                                mesh                 = meshes[index],
                                material             = material,
                                subMesh              = nodeInfo.submesh,
                                castShadows          = ShadowCastingMode.Off,
                                receiveShadows       = false,
                                needMotionVectorPass = false,
                                layer                = obj.gameObject.layer
                            });
                            DstEntityManager.AddComponentData(nodeEntity, new RenderBounds {
                                Value = meshes[index].GetSubMesh(nodeInfo.submesh).bounds.ToAABB()
                            });
                            DstEntityManager.AddComponent <PerInstanceCullingTag>(nodeEntity);
                            nodeEntities.Add(nodeEntity);
                            ConfigureEditorRenderData(nodeEntity, obj.gameObject, true);
                        }
                        var buffer = DstEntityManager.AddBuffer <UINode>(entity);
                        buffer.AddRange(nodeEntities.AsArray().Reinterpret <UINode>());
                        UnsafeUtility.Free(graphData[index].value.ToPointer(), Allocator.TempJob);
                        index++;
                        ConfigureEditorRenderData(entity, obj.gameObject, true);
                    }
                });
            }

            contexts.Dispose();
            graphData.Dispose();
        }
Esempio n. 19
0
        protected override void OnUpdate()
        {
            if (Settings == null)
            {
                return;
            }

            if (TryGetBuildConfigurationComponent <DotsRuntimeBuildProfile>(out var profile))
            {
                if (!IsExportingRootScene())
                {
                    return;
                }
            }

            // Get render settings from the current active scene
            Entity e = DstEntityManager.CreateEntity();

            // Render settings should go into the main section of the subscene they are coming from
            DstEntityManager.AddSharedComponentData(e, new SceneSection()
            {
                SceneGUID = Settings.SceneGUID, Section = 0
            });

            // Ambient light
            {
                var ambientLight = new Unity.Tiny.Rendering.AmbientLight
                {
                    ambientSkyColor = ToFloat3(RenderSettings.ambientSkyColor), // used only for selection when multiple render settings are present.
                    intensity       = 1.0f,
                };

                if (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Flat)
                {
                    ambientLight.SetAmbientColor(ToFloat3(RenderSettings.ambientSkyColor.linear));
                }
                else if (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Trilight)
                {
                    ambientLight.SetAmbientColor(
                        ToFloat3(RenderSettings.ambientSkyColor.linear),
                        ToFloat3(RenderSettings.ambientEquatorColor.linear),
                        ToFloat3(RenderSettings.ambientGroundColor.linear)
                        );
                }
                else
                {
                    ambientLight.ambientProbe = ToSHCoefficients(RenderSettings.ambientProbe);
                }

                DstEntityManager.AddComponentData(e, ambientLight);
            }

            // Fog
            var fogLinear = RenderSettings.fogColor.linear;

            DstEntityManager.AddComponentData <Unity.Tiny.Rendering.Fog>(e, new Unity.Tiny.Rendering.Fog()
            {
                mode          = RenderSettings.fogMode.ToTiny(RenderSettings.fog),
                color         = new float4(fogLinear.r, fogLinear.g, fogLinear.b, fogLinear.a),
                density       = RenderSettings.fogDensity,
                startDistance = RenderSettings.fogStartDistance,
                endDistance   = RenderSettings.fogEndDistance
            });
        }
Esempio n. 20
0
        protected override void OnUpdate()
        {
            var sceneBounds = MinMaxAABB.Empty;

            var materials = new List <Material>(10);

            Entities.ForEach((MeshRenderer meshRenderer, MeshFilter meshFilter) =>
            {
                var entity = GetPrimaryEntity(meshRenderer);

                var mesh = meshFilter.sharedMesh;
                meshRenderer.GetSharedMaterials(materials);
                var materialCount = materials.Count;

                // Don't add RenderMesh (and other required components) unless both mesh and material assigned.
                if ((mesh != null) && (materialCount > 0))
                {
                    var dst            = new RenderMesh();
                    dst.mesh           = mesh;
                    dst.castShadows    = meshRenderer.shadowCastingMode;
                    dst.receiveShadows = meshRenderer.receiveShadows;
                    dst.layer          = meshRenderer.gameObject.layer;

                    //@TODO: Transform system should handle RenderMeshFlippedWindingTag automatically. This should not be the responsibility of the conversion system.
                    float4x4 localToWorld = meshRenderer.transform.localToWorldMatrix;
                    var flipWinding       = math.determinant(localToWorld) < 0.0;

                    if (materialCount == 1 && AttachToPrimaryEntityForSingleMaterial)
                    {
                        dst.material = materials[0];
                        dst.subMesh  = 0;

                        DstEntityManager.AddSharedComponentData(entity, dst);
                        DstEntityManager.AddComponentData(entity, new PerInstanceCullingTag());
                        DstEntityManager.AddComponentData(entity, new RenderBounds {
                            Value = mesh.bounds.ToAABB()
                        });

                        if (flipWinding)
                        {
                            DstEntityManager.AddComponent(entity,
                                                          ComponentType.ReadWrite <RenderMeshFlippedWindingTag>());
                        }

                        ConfigureEditorRenderData(entity, meshRenderer.gameObject, true);
                    }
                    else
                    {
                        for (var m = 0; m != materialCount; m++)
                        {
                            var meshEntity = CreateAdditionalEntity(meshRenderer);

                            dst.material = materials[m];
                            dst.subMesh  = m;

                            DstEntityManager.AddSharedComponentData(meshEntity, dst);

                            DstEntityManager.AddComponentData(meshEntity, new PerInstanceCullingTag());
                            DstEntityManager.AddComponentData(meshEntity,
                                                              new RenderBounds {
                                Value = mesh.bounds.ToAABB()
                            });

                            DstEntityManager.AddComponentData(meshEntity, new LocalToWorld {
                                Value = localToWorld
                            });
                            if (!DstEntityManager.HasComponent <Static>(meshEntity))
                            {
                                DstEntityManager.AddComponentData(meshEntity, new Parent {
                                    Value = entity
                                });
                                DstEntityManager.AddComponentData(meshEntity,
                                                                  new LocalToParent {
                                    Value = float4x4.identity
                                });
                            }

                            if (flipWinding)
                            {
                                DstEntityManager.AddComponent(meshEntity,
                                                              ComponentType.ReadWrite <RenderMeshFlippedWindingTag>());
                            }

                            ConfigureEditorRenderData(meshEntity, meshRenderer.gameObject, true);
                        }
                    }

                    sceneBounds.Encapsulate(meshRenderer.bounds.ToAABB());
                }
            });
        }
Esempio n. 21
0
        protected override void OnUpdate()
        {
            using (var context = new BlobAssetComputationContext <int, GhostPrefabMetaData>(BlobAssetStore, 16, Allocator.Temp))
            {
                Entities.ForEach((GhostAuthoringComponent ghostAuthoring) =>
                {
                    bool isPrefab = !ghostAuthoring.gameObject.scene.IsValid() || ghostAuthoring.ForcePrefabConversion;
                    var target    = GetConversionTarget(this, isPrefab);
                    // Check if the ghost is valid before starting to process
                    if (String.IsNullOrEmpty(ghostAuthoring.prefabId))
                    {
                        throw new InvalidOperationException($"The ghost {ghostAuthoring.gameObject.name} is not a valid prefab, all ghosts must be the top-level GameObject in a prefab. Ghost instances in scenes must be instances of such prefabs and changes should be made on the prefab asset, not the prefab instance");
                    }

                    if (!isPrefab && ghostAuthoring.DefaultGhostMode == GhostAuthoringComponent.GhostMode.OwnerPredicted && target != NetcodeConversionTarget.Server)
                    {
                        throw new InvalidOperationException($"Cannot convert a owner predicted ghost {ghostAuthoring.Name} as a scene instance");
                    }

                    if (!isPrefab && DstEntityManager.World.GetExistingSystem <ClientSimulationSystemGroup>() != null)
                    {
                        throw new InvalidOperationException($"The ghost {ghostAuthoring.gameObject.name} cannot be created on the client, either put it in a sub-scene or spawn it on the server only");
                    }

                    if (ghostAuthoring.prefabId.Length != 32)
                    {
                        throw new InvalidOperationException("Invalid guid for ghost prefab type");
                    }

                    // All ghosts should have a linked entity group
                    DeclareLinkedEntityGroup(ghostAuthoring.gameObject);
                    var entity = GetPrimaryEntity(ghostAuthoring);

                    // Generate a ghost type component so the ghost can be identified by mathcing prefab asset guid
                    var ghostType   = new GhostTypeComponent();
                    ghostType.guid0 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(0, 8), 16);
                    ghostType.guid1 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(8, 8), 16);
                    ghostType.guid2 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(16, 8), 16);
                    ghostType.guid3 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(24, 8), 16);
                    DstEntityManager.AddComponentData(entity, ghostType);

                    // FIXME: maybe stripping should be individual systems running before this to make sure it can be changed in a way that always triggers a reconvert - and to avoid reflection
                    var components = DstEntityManager.GetComponentTypes(entity);
                    if (target != NetcodeConversionTarget.Client)
                    {
                        // If this ghost should be usable on a server we must add a shared ghost type to make sure different ghost types
                        // with the same archetype end up in different chunks. If conversion is client and server the client needs to remove
                        // this at runtime
                        DstEntityManager.AddSharedComponentData(entity, new SharedGhostTypeComponent {
                            SharedValue = ghostType
                        });
                    }
                    if (target != NetcodeConversionTarget.Server)
                    {
                        // Converting to client or client and server, if client and server this should be stripped from servers at runtime
                        DstEntityManager.AddComponentData(entity, new SnapshotData());
                        DstEntityManager.AddBuffer <SnapshotDataBuffer>(entity);
                    }
                    // All types have the ghost components
                    DstEntityManager.AddComponentData(entity, new GhostComponent());
                    // No need to add the predicted ghost component for interpolated only ghosts if the data is only used by the client
                    if (target != NetcodeConversionTarget.Client || ghostAuthoring.SupportedGhostModes != GhostAuthoringComponent.GhostModeMask.Interpolated)
                    {
                        DstEntityManager.AddComponentData(entity, new PredictedGhostComponent());
                    }
                    if (target == NetcodeConversionTarget.Server)
                    {
                        // If converting server-only data we can remove all components which are not used on the server
                        foreach (var comp in components)
                        {
                            var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>();
                            if (attr != null && (attr.PrefabType & GhostPrefabType.Server) == 0)
                            {
                                DstEntityManager.RemoveComponent(entity, comp);
                            }
                        }
                    }
                    else if (target == NetcodeConversionTarget.Client)
                    {
                        // If converting client-only data we can remove all components which are not used on the client
                        // If the ghost is interpolated only we can also remove all componens which are not used on interpolated clients,
                        // and if it is predicted only we can remove everything which is not used on predicted clients
                        foreach (var comp in components)
                        {
                            var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>();
                            if (attr == null)
                            {
                                continue;
                            }
                            if ((attr.PrefabType & GhostPrefabType.Client) == 0)
                            {
                                DstEntityManager.RemoveComponent(entity, comp);
                            }
                            else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated && (attr.PrefabType & GhostPrefabType.InterpolatedClient) == 0)
                            {
                                DstEntityManager.RemoveComponent(entity, comp);
                            }
                            else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted && (attr.PrefabType & GhostPrefabType.PredictedClient) == 0)
                            {
                                DstEntityManager.RemoveComponent(entity, comp);
                            }
                        }
                    }
                    // Even if converting for client and server we can remove components which are only for predicted clients when
                    // the ghost is always interpolated, or components which are only for interpolated clients if the ghost is always
                    // predicted
                    else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated)
                    {
                        foreach (var comp in components)
                        {
                            var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>();
                            if (attr != null && (attr.PrefabType & (GhostPrefabType.InterpolatedClient | GhostPrefabType.Server)) == 0)
                            {
                                DstEntityManager.RemoveComponent(entity, comp);
                            }
                        }
                    }
                    else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted)
                    {
                        foreach (var comp in components)
                        {
                            var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>();
                            if (attr != null && (attr.PrefabType & (GhostPrefabType.PredictedClient | GhostPrefabType.Server)) == 0)
                            {
                                DstEntityManager.RemoveComponent(entity, comp);
                            }
                        }
                    }

                    // This logic needs to match the logic creating LinkedEntityGroups, gather a list of all child entities
                    var linkedEntities  = new NativeList <Entity>(1, Allocator.Temp);
                    var selfAndChildren = ghostAuthoring.gameObject.GetComponentsInChildren <Transform>(true);
                    foreach (var transform in selfAndChildren)
                    {
                        foreach (var child in GetEntities(transform.gameObject))
                        {
                            if (DstEntityManager.Exists(child))
                            {
                                linkedEntities.Add(child);
                            }
                        }
                    }
                    // Mark all child entities as ghost children, entity 0 is the root and hsould not be marked
                    for (int i = 1; i < linkedEntities.Length; ++i)
                    {
                        DstEntityManager.AddComponentData(linkedEntities[i], default(GhostChildEntityComponent));
                    }

                    if (isPrefab)
                    {
                        var contentHash = TypeHash.FNV1A64(ghostAuthoring.Importance);
                        contentHash     = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)ghostAuthoring.SupportedGhostModes));
                        contentHash     = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)ghostAuthoring.DefaultGhostMode));
                        contentHash     = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)ghostAuthoring.OptimizationMode));
                        contentHash     = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64(ghostAuthoring.Name.ToString()));
                        foreach (var comp in components)
                        {
                            contentHash = TypeHash.CombineFNV1A64(contentHash, TypeManager.GetTypeInfo(comp.TypeIndex).StableTypeHash);
                            var attr    = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>();
                            if (attr != null)
                            {
                                contentHash = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)attr.PrefabType));
                            }
                        }
                        var blobHash = new Unity.Entities.Hash128(ghostType.guid0 ^ (uint)(contentHash >> 32), ghostType.guid1 ^ (uint)(contentHash), ghostType.guid2, ghostType.guid3);
                        context.AssociateBlobAssetWithUnityObject(blobHash, ghostAuthoring.gameObject);
                        if (context.NeedToComputeBlobAsset(blobHash))
                        {
                            var builder  = new BlobBuilder(Allocator.Temp);
                            ref var root = ref builder.ConstructRoot <GhostPrefabMetaData>();

                            // Store importance, supported modes, default mode and name in the meta data blob asset
                            root.Importance     = ghostAuthoring.Importance;
                            root.SupportedModes = GhostPrefabMetaData.GhostMode.Both;
                            root.DefaultMode    = GhostPrefabMetaData.GhostMode.Interpolated;
                            if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated)
                            {
                                root.SupportedModes = GhostPrefabMetaData.GhostMode.Interpolated;
                            }
                            else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted)
                            {
                                root.SupportedModes = GhostPrefabMetaData.GhostMode.Predicted;
                                root.DefaultMode    = GhostPrefabMetaData.GhostMode.Predicted;
                            }
                            else if (ghostAuthoring.DefaultGhostMode == GhostAuthoringComponent.GhostMode.OwnerPredicted)
                            {
                                if (!DstEntityManager.HasComponent <GhostOwnerComponent>(entity))
                                {
                                    throw new InvalidOperationException("OwnerPrediction mode can only be used on prefabs which have a GhostOwnerComponent");
                                }
                                root.DefaultMode = GhostPrefabMetaData.GhostMode.Both;
                            }
                            else if (ghostAuthoring.DefaultGhostMode == GhostAuthoringComponent.GhostMode.Predicted)
                            {
                                root.DefaultMode = GhostPrefabMetaData.GhostMode.Predicted;
                            }
                            root.StaticOptimization = (ghostAuthoring.OptimizationMode == GhostAuthoringComponent.GhostOptimizationMode.Static);
                            builder.AllocateString(ref root.Name, ghostAuthoring.Name);

                            var serverComponents      = new NativeList <ulong>(components.Length, Allocator.Temp);
                            var removeOnServer        = new NativeList <ulong>(components.Length, Allocator.Temp);
                            var removeOnClient        = new NativeList <ulong>(components.Length, Allocator.Temp);
                            var disableOnPredicted    = new NativeList <ulong>(components.Length, Allocator.Temp);
                            var disableOnInterpolated = new NativeList <ulong>(components.Length, Allocator.Temp);

                            // Snapshot data buffers should be removed from the server, and shared ghost type from the client
                            removeOnServer.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <SnapshotData>().TypeIndex).StableTypeHash);
                            removeOnServer.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <SnapshotDataBuffer>().TypeIndex).StableTypeHash);
                            removeOnClient.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <SharedGhostTypeComponent>().TypeIndex).StableTypeHash);

                            // If both interpolated and predicted clients are supported the interpolated client needs to disable the prediction component
                            // If the ghost is interpolated only the prediction component can be removed on clients
                            if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.All)
                            {
                                disableOnInterpolated.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <PredictedGhostComponent>().TypeIndex).StableTypeHash);
                            }
                            else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated)
                            {
                                removeOnClient.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <PredictedGhostComponent>().TypeIndex).StableTypeHash);
                            }

                            foreach (var comp in components)
                            {
                                var hash = TypeManager.GetTypeInfo(comp.TypeIndex).StableTypeHash;
                                var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>();
                                if (attr == null)
                                {
                                    serverComponents.Add(hash);
                                    continue;
                                }
                                if ((attr.PrefabType & GhostPrefabType.Server) == 0)
                                {
                                    removeOnServer.Add(hash);
                                }
                                else
                                {
                                    serverComponents.Add(hash);
                                }

                                // If something is not used on the client, remove it. Make sure to include things that is interpolated only if ghost
                                // is predicted only and the other way around
                                if ((attr.PrefabType & GhostPrefabType.Client) == 0)
                                {
                                    removeOnClient.Add(hash);
                                }
                                else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated &&
                                         (attr.PrefabType & GhostPrefabType.InterpolatedClient) == 0)
                                {
                                    removeOnClient.Add(hash);
                                }
                                else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted &&
                                         (attr.PrefabType & GhostPrefabType.PredictedClient) == 0)
                                {
                                    removeOnClient.Add(hash);
                                }

                                // If the prefab only supports a single mode on the client there is no need to enable / disable, if is handled by the
                                // previous loop removing components on the client instead
                                if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.All)
                                {
                                    // Components available on predicted but not interpolated should be disabled on interpolated clients
                                    if ((attr.PrefabType & GhostPrefabType.InterpolatedClient) == 0 && (attr.PrefabType & GhostPrefabType.PredictedClient) != 0)
                                    {
                                        disableOnInterpolated.Add(hash);
                                    }
                                    if ((attr.PrefabType & GhostPrefabType.InterpolatedClient) != 0 && (attr.PrefabType & GhostPrefabType.PredictedClient) == 0)
                                    {
                                        disableOnPredicted.Add(hash);
                                    }
                                }
                            }
                            var blobServerComponents = builder.Allocate(ref root.ServerComponentList, serverComponents.Length);
                            for (int i = 0; i < serverComponents.Length; ++i)
                            {
                                blobServerComponents[i] = serverComponents[i];
                            }

                            // A pre-spawned instance can be created in ClientServer even if the prefab is not, so anything which should
                            // be usable on the server needs to know what to remove from the server version
                            if (target != NetcodeConversionTarget.Client)
                            {
                                // Client only data never needs information about the server
                                var blobRemoveOnServer = builder.Allocate(ref root.RemoveOnServer, removeOnServer.Length);
                                for (int i = 0; i < removeOnServer.Length; ++i)
                                {
                                    blobRemoveOnServer[i] = removeOnServer[i];
                                }
                            }
                            else
                            {
                                builder.Allocate(ref root.RemoveOnServer, 0);
                            }
                            if (target != NetcodeConversionTarget.Server)
                            {
                                var blobRemoveOnClient = builder.Allocate(ref root.RemoveOnClient, removeOnClient.Length);
                                for (int i = 0; i < removeOnClient.Length; ++i)
                                {
                                    blobRemoveOnClient[i] = removeOnClient[i];
                                }
                            }
                            else
                            {
                                builder.Allocate(ref root.RemoveOnClient, 0);
                            }

                            if (target != NetcodeConversionTarget.Server)
                            {
                                // The data for interpolated / predicted diff is required unless this is server-only
                                var blobDisableOnPredicted = builder.Allocate(ref root.DisableOnPredictedClient, disableOnPredicted.Length);
                                for (int i = 0; i < disableOnPredicted.Length; ++i)
                                {
                                    blobDisableOnPredicted[i] = disableOnPredicted[i];
                                }
                                var blobDisableOnInterpolated = builder.Allocate(ref root.DisableOnInterpolatedClient, disableOnInterpolated.Length);
                                for (int i = 0; i < disableOnInterpolated.Length; ++i)
                                {
                                    blobDisableOnInterpolated[i] = disableOnInterpolated[i];
                                }
                            }
                            else
                            {
                                builder.Allocate(ref root.DisableOnPredictedClient, 0);
                                builder.Allocate(ref root.DisableOnInterpolatedClient, 0);
                            }

                            var blobAsset = builder.CreateBlobAssetReference <GhostPrefabMetaData>(Allocator.Persistent);
                            context.AddComputedBlobAsset(blobHash, blobAsset);
                        }
                        context.GetBlobAsset(blobHash, out var blob);
                        DstEntityManager.AddComponentData(entity, new GhostPrefabMetaDataComponent {
                            Value = blob
                        });
                    }
                });
Esempio n. 22
0
    protected override void OnUpdate()
    {
        var hashToEntity = new NativeHashMap <ulong, Entity>(128, Allocator.TempJob);

        // TODO: Check that the GhostAuthoringComponent is interpolated, as we don't support predicted atm
        Entities.ForEach((GhostAuthoringComponent ghostAuthoring) =>
        {
            var entity        = GetPrimaryEntity(ghostAuthoring);
            var isInSubscene  = DstEntityManager.HasComponent <SceneSection>(entity);
            bool isPrefab     = !ghostAuthoring.gameObject.scene.IsValid() || ghostAuthoring.ForcePrefabConversion;
            var activeInScene = ghostAuthoring.gameObject.activeInHierarchy;
            if (!isPrefab && isInSubscene && activeInScene)
            {
                var hashData       = new NativeList <ulong>(Allocator.TempJob);
                var componentTypes = DstEntityManager.GetComponentTypes(entity, Allocator.TempJob);
                // Hash all the data on the entity (first each component data then all together)
                for (int i = 0; i < componentTypes.Length; ++i)
                {
                    // Do not include components which might be included or not included depending on if you are a
                    // client or a server
                    // TODO: Check the interpolated/predicted/server bools instead
                    //       Only iterate ghostAuthoring.Components
                    //       Should skip PhysicsCollider, WorldRenderBounds, XXXSnapshotData, PredictedGhostComponent
                    if (componentTypes[i] == typeof(Translation) || componentTypes[i] == typeof(Rotation))
                    {
                        var componentDataHash = ComponentDataToHash(entity, componentTypes[i]);
                        hashData.Add(componentDataHash);
                    }
                }
                hashData.Sort();

                ulong combinedComponentHash;
                unsafe
                {
                    combinedComponentHash = Unity.Core.XXHash.Hash64((byte *)hashData.GetUnsafeReadOnlyPtr(), hashData.Length * sizeof(ulong));
                }

                // When duplicating a scene object it will have the same position/rotation as the original, so until that
                // changes there will always be a duplicate hash until it's moved to it's own location
                if (!hashToEntity.ContainsKey(combinedComponentHash))
                {
                    hashToEntity.Add(combinedComponentHash, entity);
                }

                componentTypes.Dispose();
                hashData.Dispose();
            }
        });

        if (hashToEntity.Count() > 0)
        {
            var keys = hashToEntity.GetKeyArray(Allocator.TempJob);
            keys.Sort();

            // Assign ghost IDs to the pre-spawned entities sorted by component data hash
            for (int i = 0; i < keys.Length; ++i)
            {
                DstEntityManager.AddComponentData(hashToEntity[keys[i]], new PreSpawnedGhostId {
                    Value = i + 1
                });
            }

            // Save the final subscene hash with all the pre-spawned ghosts
            unsafe
            {
                var hash = Unity.Core.XXHash.Hash64((byte *)keys.GetUnsafeReadOnlyPtr(), keys.Length * sizeof(ulong));

                for (int i = 0; i < keys.Length; ++i)
                {
                    // Track the subscene which is the parent of this entity
                    DstEntityManager.AddSharedComponentData(hashToEntity[keys[i]], new SubSceneGhostComponentHash {
                        Value = hash
                    });
                }
            }
            keys.Dispose();
        }
        hashToEntity.Dispose();
    }
Esempio n. 23
0
        protected override void OnUpdate()
        {
            var typeLookup = new Dictionary <string, Type>();
            var allTypes   = TypeManager.GetAllTypes();

            foreach (var compType in allTypes)
            {
                if (compType.Category == TypeManager.TypeCategory.BufferData &&
                    compType.Type != null && compType.Type.Name.EndsWith("SnapshotData"))
                {
                    if (typeLookup.ContainsKey(compType.Type.Name))
                    {
                        throw new InvalidOperationException(
                                  $"Found multiple snapshot data types named {compType.Type.Name}, namespaces are not fully supported for snapshot data");
                    }
                    typeLookup.Add(compType.Type.Name, compType.Type);
                }
            }

            Entities.ForEach((GhostAuthoringComponent ghostAuthoring) =>
            {
                if (String.IsNullOrEmpty(ghostAuthoring.prefabId))
                {
                    throw new InvalidOperationException($"The ghost {ghostAuthoring.gameObject.name} is not a valid prefab, all ghosts must be the top-level GameObject in a prefab. Ghost instances in scenes must be instances of such prefabs.");
                }
                DeclareLinkedEntityGroup(ghostAuthoring.gameObject);
                if (ghostAuthoring.doNotStrip)
                {
                    return;
                }
                var entity = GetPrimaryEntity(ghostAuthoring);

                var target = GetConversionTarget(this);

                // FIXME: A2 hack
                if (target == NetcodeConversionTarget.Undefined)
                {
                    //  throw new InvalidOperationException($"A ghost prefab can only be created in the client or server world, not {DstEntityManager.World.Name}");
                    Debug.LogWarning(
                        $"A ghost prefab can only be created in the client or server world, not {DstEntityManager.World.Name}.\nDefaulting to server conversion.");
                    target = NetcodeConversionTarget.Server;
                }

                if (ghostAuthoring.prefabId.Length != 32)
                {
                    throw new InvalidOperationException("Invalid guid for ghost prefab type");
                }
                var ghostType   = new GhostTypeComponent();
                ghostType.guid0 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(0, 8), 16);
                ghostType.guid1 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(8, 8), 16);
                ghostType.guid2 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(16, 8), 16);
                ghostType.guid3 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(24, 8), 16);
                DstEntityManager.AddComponentData(entity, ghostType);
                var toRemove = new HashSet <string>();
                if (target == NetcodeConversionTarget.Server)
                {
                    // Make sure different ghost types are in different chunks
                    DstEntityManager.AddSharedComponentData(entity, new SharedGhostTypeComponent {
                        SharedValue = ghostType
                    });
                    DstEntityManager.AddComponentData(entity, new GhostComponent());
                    DstEntityManager.AddComponentData(entity, new PredictedGhostComponent());
                    // Create server version of prefab
                    foreach (var comp in ghostAuthoring.Components)
                    {
                        if (!comp.server && comp.entityIndex == 0)
                        {
                            toRemove.Add(comp.name);
                        }
                    }
                }
                else if (target == NetcodeConversionTarget.Client)
                {
                    var snapshotTypeName = $"{ghostAuthoring.name}SnapshotData";
                    if (!typeLookup.TryGetValue(snapshotTypeName, out var snapshotType))
                    {
                        throw new InvalidOperationException(
                            $"Could not find snapshot data {snapshotTypeName}, did you generate the ghost code?");
                    }

                    DstEntityManager.AddComponent(entity, snapshotType);
                    DstEntityManager.AddComponentData(entity, new GhostComponent());
                    if (ghostAuthoring.DefaultClientInstantiationType ==
                        GhostAuthoringComponent.ClientInstantionType.Interpolated)
                    {
                        foreach (var comp in ghostAuthoring.Components)
                        {
                            if (!comp.interpolatedClient && comp.entityIndex == 0)
                            {
                                toRemove.Add(comp.name);
                            }
                        }
                    }
                    else
                    {
                        DstEntityManager.AddComponentData(entity, new PredictedGhostComponent());
                        foreach (var comp in ghostAuthoring.Components)
                        {
                            if (!comp.predictedClient && comp.entityIndex == 0)
                            {
                                toRemove.Add(comp.name);
                            }
                        }
                    }
                }

                // Add list of things to strip based on target world
                // Strip the things in GhostAuthoringConversion
                var components = DstEntityManager.GetComponentTypes(entity);
                foreach (var comp in components)
                {
                    if (toRemove.Contains(comp.GetManagedType().FullName))
                    {
                        DstEntityManager.RemoveComponent(entity, comp);
                    }
                }
            });
        }
Esempio n. 24
0
        protected override void OnUpdate()
        {
            var sceneBounds = MinMaxAABB.Empty;

            var materials = new List <Material>(10);

            Entities.ForEach((MeshRenderer meshRenderer, MeshFilter meshFilter) =>
            {
                var entity = GetPrimaryEntity(meshRenderer);

                var dst            = new RenderMesh();
                dst.mesh           = meshFilter.sharedMesh;
                dst.castShadows    = meshRenderer.shadowCastingMode;
                dst.receiveShadows = meshRenderer.receiveShadows;
                dst.layer          = meshRenderer.gameObject.layer;


                //@TODO: Transform system should handle RenderMeshFlippedWindingTag automatically. This should not be the responsibility of the conversion system.
                float4x4 localToWorld = meshRenderer.transform.localToWorldMatrix;
                var flipWinding       = math.determinant(localToWorld) < 0.0;

                meshRenderer.GetSharedMaterials(materials);
                var materialCount = materials.Count;

                if (materialCount == 1 && AttachToPrimaryEntityForSingleMaterial)
                {
                    dst.material = materials[0];
                    dst.subMesh  = 0;

                    DstEntityManager.AddSharedComponentData(entity, dst);
                    DstEntityManager.AddComponentData(entity, new PerInstanceCullingTag());

                    if (flipWinding)
                    {
                        DstEntityManager.AddComponent(entity, ComponentType.ReadWrite <RenderMeshFlippedWindingTag>());
                    }
                }
                else
                {
                    for (var m = 0; m != materialCount; m++)
                    {
                        var meshEntity = CreateAdditionalEntity(meshRenderer);

                        dst.material = materials[m];
                        dst.subMesh  = m;

                        DstEntityManager.AddSharedComponentData(meshEntity, dst);

                        DstEntityManager.AddComponentData(meshEntity, new PerInstanceCullingTag());

                        DstEntityManager.AddComponentData(meshEntity, new LocalToWorld {
                            Value = localToWorld
                        });
                        if (!DstEntityManager.HasComponent <Static>(meshEntity))
                        {
                            DstEntityManager.AddComponentData(meshEntity, new Parent {
                                Value = entity
                            });
                            DstEntityManager.AddComponentData(meshEntity, new LocalToParent {
                                Value = float4x4.identity
                            });
                        }

                        if (flipWinding)
                        {
                            DstEntityManager.AddComponent(meshEntity, ComponentType.ReadWrite <RenderMeshFlippedWindingTag>());
                        }
                    }
                }

                sceneBounds.Encapsulate(meshRenderer.bounds.ToAABB());
            });


            using (var boundingVolume = DstEntityManager.CreateEntityQuery(typeof(SceneBoundingVolume)))
            {
                if (!boundingVolume.IsEmptyIgnoreFilter)
                {
                    var bounds = boundingVolume.GetSingleton <SceneBoundingVolume>();
                    bounds.Value.Encapsulate(sceneBounds);
                    boundingVolume.SetSingleton(bounds);
                }
            }
        }
    void CreateWireEntities(Component rootComponent, Wire wirePrefab, Vector3 wireEndPos, params Gate[] inputNodes)
    {
        if (wirePrefab == null)
        {
            return;
        }
        var wireMeshFilter = wirePrefab.GetComponent <MeshFilter>();
        var wireTransform  = wirePrefab.GetComponent <Transform>();
        var wireMaterial   = wirePrefab.GetComponent <MeshRenderer>().sharedMaterial;

        // Copy & modify the gate's RenderMesh to reference the correct mesh/material.
        var gateEntity     = GetPrimaryEntity(rootComponent);
        var baseRenderMesh = DstEntityManager.GetSharedComponentData <RenderMesh>(gateEntity);

        baseRenderMesh.mesh     = wireMeshFilter.sharedMesh;
        baseRenderMesh.material = wireMaterial;

        foreach (var inputNode in inputNodes)
        {
            // Create a linked entity for the wires leading from the input to this gate
            var wireStartPos = inputNode.outputAttachTransform.position;
            // TODO(cort): conversionSystem.InstantiateAdditionalEntity() would be ideal here. Instead, copy what we need from the prefab.
            var wireEntity = CreateAdditionalEntity(rootComponent);
#if UNITY_EDITOR
            DstEntityManager.SetName(wireEntity, "Wire"); // TODO: make this call [Conditional]
#endif
            DstEntityManager.AddComponents(wireEntity, new ComponentTypes(new ComponentType[]
            {
                typeof(LocalToWorld),
                typeof(RenderBounds),
                typeof(Translation),
                typeof(Rotation),
                typeof(NonUniformScale),
                typeof(WireInput),
                typeof(WireState),
            }));

            DstEntityManager.AddSharedComponentData(wireEntity, baseRenderMesh);

            // TODO(https://github.com/cdwfs/RubyGates/issues/9): pre-bake the LocalToWorld and add the Static tag
            DstEntityManager.SetComponentData(wireEntity, new Translation
            {
                Value = wireStartPos,
            });

            var wireScale = wireTransform.localScale;
            wireScale.y = Vector3.Distance(wireStartPos, wireEndPos);
            DstEntityManager.SetComponentData(wireEntity, new NonUniformScale
            {
                Value = wireScale,
            });

            // We want to measure an angle relative to +Y while looking in -Z.
            float3 wireDir   = wireEndPos - wireStartPos;
            float  wireAngle = math.atan2(-wireDir.x, wireDir.y);
            DstEntityManager.SetComponentData(wireEntity, new Rotation
            {
                Value = quaternion.RotateZ(wireAngle),
            });

            DstEntityManager.SetComponentData(wireEntity, new WireInput
            {
                InputEntity = GetPrimaryEntity(inputNode.gameObject),
            });
        }
    }
Esempio n. 26
0
        protected override void OnUpdate()
        {
            Entities.ForEach((UnityEngine.Light unityLight) =>
            {
                var entity = GetPrimaryEntity(unityLight);

                LightComponent light;
                light.type                   = unityLight.type;
                light.color                  = unityLight.color;
                light.colorTemperature       = unityLight.colorTemperature;
                light.range                  = unityLight.range;
                light.intensity              = unityLight.intensity;
                light.cullingMask            = unityLight.cullingMask;
                light.renderingLayerMask     = unityLight.renderingLayerMask;
                light.spotAngle              = unityLight.spotAngle;
                light.innerSpotAngle         = unityLight.innerSpotAngle;
                light.shadows                = unityLight.shadows;
                light.shadowCustomResolution = unityLight.shadowCustomResolution;
                light.shadowNearPlane        = unityLight.shadowNearPlane;
                light.shadowBias             = unityLight.shadowBias;
                light.shadowNormalBias       = unityLight.shadowNormalBias;
                light.shadowStrength         = unityLight.shadowStrength;
                DstEntityManager.AddComponentData(entity, light);

                if (unityLight.cookie)
                {
                    LightCookie cookie;
                    cookie.texture = unityLight.cookie;
                    DstEntityManager.AddSharedComponentData(entity, cookie);
                }

                // Optional dependency to com.unity.render-pipelines.high-definition
#if HDRP_6_EXISTS
                HDLightData hdData;

                var unityHdData              = unityLight.GetComponent <HDAdditionalLightData>();
                hdData.lightTypeExtent       = unityHdData.lightTypeExtent;
                hdData.intensity             = unityHdData.intensity;
                hdData.lightDimmer           = unityHdData.lightDimmer;
                hdData.fadeDistance          = unityHdData.fadeDistance;
                hdData.affectDiffuse         = unityHdData.affectDiffuse;
                hdData.affectSpecular        = unityHdData.affectSpecular;
                hdData.shapeWidth            = unityHdData.shapeWidth;
                hdData.shapeHeight           = unityHdData.shapeHeight;
                hdData.aspectRatio           = unityHdData.aspectRatio;
                hdData.shapeRadius           = unityHdData.shapeRadius;
                hdData.maxSmoothness         = unityHdData.maxSmoothness;
                hdData.applyRangeAttenuation = unityHdData.applyRangeAttenuation;
                hdData.spotLightShape        = unityHdData.spotLightShape;
                hdData.enableSpotReflector   = unityHdData.enableSpotReflector;
                hdData.innerSpotPercent      = unityHdData.m_InnerSpotPercent;

                var unityShadowData           = unityLight.GetComponent <AdditionalShadowData>();
                hdData.shadowResolution       = unityShadowData.shadowResolution;
                hdData.shadowDimmer           = unityShadowData.shadowDimmer;
                hdData.volumetricShadowDimmer = unityShadowData.volumetricShadowDimmer;
                hdData.shadowFadeDistance     = unityShadowData.shadowFadeDistance;
                hdData.contactShadows         = unityShadowData.contactShadows;
                hdData.viewBiasMin            = unityShadowData.viewBiasMin;
                hdData.viewBiasMax            = unityShadowData.viewBiasMax;
                hdData.viewBiasScale          = unityShadowData.viewBiasScale;
                hdData.normalBiasMin          = unityShadowData.normalBiasMin;
                hdData.normalBiasMax          = unityShadowData.normalBiasMax;
                hdData.normalBiasScale        = unityShadowData.normalBiasScale;
                hdData.sampleBiasScale        = unityShadowData.sampleBiasScale;
                hdData.edgeLeakFixup          = unityShadowData.edgeLeakFixup;
                hdData.edgeToleranceNormal    = unityShadowData.edgeToleranceNormal;
                hdData.edgeTolerance          = unityShadowData.edgeTolerance;
                DstEntityManager.AddComponentData(entity, hdData);
#elif HDRP_7_EXISTS
                var unityHdData = unityLight.GetComponent <HDAdditionalLightData>();
                HDLightData hdData;
                hdData.lightTypeExtent        = unityHdData.lightTypeExtent;
                hdData.intensity              = unityHdData.intensity;
                hdData.lightDimmer            = unityHdData.lightDimmer;
                hdData.fadeDistance           = unityHdData.fadeDistance;
                hdData.affectDiffuse          = unityHdData.affectDiffuse;
                hdData.affectSpecular         = unityHdData.affectSpecular;
                hdData.shapeWidth             = unityHdData.shapeWidth;
                hdData.shapeHeight            = unityHdData.shapeHeight;
                hdData.aspectRatio            = unityHdData.aspectRatio;
                hdData.shapeRadius            = unityHdData.shapeRadius;
                hdData.maxSmoothness          = unityHdData.maxSmoothness;
                hdData.applyRangeAttenuation  = unityHdData.applyRangeAttenuation;
                hdData.spotLightShape         = unityHdData.spotLightShape;
                hdData.enableSpotReflector    = unityHdData.enableSpotReflector;
                hdData.innerSpotPercent       = unityHdData.innerSpotPercent;
                hdData.customResolution       = unityHdData.customResolution;
                hdData.shadowDimmer           = unityHdData.shadowDimmer;
                hdData.volumetricShadowDimmer = unityHdData.volumetricShadowDimmer;
                hdData.shadowFadeDistance     = unityHdData.shadowFadeDistance;
                hdData.contactShadows         = unityHdData.contactShadows;
                hdData.shadowTint             = unityHdData.shadowTint;
                hdData.normalBias             = unityHdData.normalBias;
                hdData.constantBias           = unityHdData.constantBias;
                hdData.shadowUpdateMode       = unityHdData.shadowUpdateMode;
                DstEntityManager.AddComponentData(entity, hdData);
#endif
            });
        }