예제 #1
0
        public void InitializeInputArrays(NativeArray <BoundingVolumeHierarchy.PointAndIndex> points, NativeArray <Aabb> aabbs, NativeArray <CollisionFilter> filters)
        {
            var random = new Mathematics.Random(1234);

            const float posRange       = 1000f;
            const float radiusRangeMin = 1f;
            const float radiusRangeMax = 10f;

            for (int i = 0; i < points.Length; i++)
            {
                float2 pos;
                pos.x     = random.NextFloat(-posRange, posRange);
                pos.y     = random.NextFloat(-posRange, posRange);
                points[i] = new BoundingVolumeHierarchy.PointAndIndex {
                    Position = pos, Index = i
                };

                var radius = new float2(random.NextFloat(radiusRangeMin, radiusRangeMax));
                aabbs[i] = new Aabb {
                    Min = pos - radius, Max = pos + radius
                };

                filters[i] = CollisionFilter.Default;
            }
        }
        public void CanRead_ECSBuffer_InsideFromDFG(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize)
        {
            const int k_Loops = 10;

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entity     = f.EM.CreateEntity(typeof(SimpleBuffer));
                var entityNode = f.Set.CreateComponentNode(entity);
                var dfgNode    = f.Set.Create <BufferNode>();
                var gv         = f.Set.CreateGraphValue(dfgNode, BufferNode.KernelPorts.Output);

                f.Set.Connect(entityNode, ComponentNode.Output <SimpleBuffer>(), dfgNode, BufferNode.KernelPorts.Input);

                var rng = new Mathematics.Random(0x7f);

                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(bufferSize));

                for (int i = 0; i < k_Loops; ++i)
                {
                    var ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);
                    ecsBuffer.ResizeUninitialized(bufferSize);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        ecsBuffer[n] = new SimpleBuffer {
                            Values = rng.NextFloat3()
                        };
                    }

                    f.System.Update();

                    var resolver = f.Set.GetGraphValueResolver(out var dependency);
                    dependency.Complete();

                    ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);

                    var dfgBuffer = resolver.Resolve(gv);

                    Assert.AreEqual(ecsBuffer.Length, dfgBuffer.Length);

                    // TODO: can compare alias here
                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(ecsBuffer[n], dfgBuffer[n]);
                    }
                }

                f.Set.ReleaseGraphValue(gv);
                f.Set.Destroy(entityNode, dfgNode);
            }
        }
        public void OneTimeSetup()
        {
            var skeletonNodes = new[]
            {
                new SkeletonNode {
                    ParentIndex = -1, Id = string.Empty, AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 0, Id = "Child1", AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 0, Id = "Child2", AxisIndex = -1
                }
            };

            RigDefinition = RigBuilder.CreateRigDefinition(skeletonNodes);

            var r        = new Mathematics.Random(0x12345678);
            var range    = new float3(100);
            var fullClip = new UnityEngine.AnimationClip();

            // add some error into the clip, so it is not perfectly frame aligned
            float clipDuration = clipFrames / fullClip.frameRate + 0.123f / fullClip.frameRate;


            CreateLinearTranslate(fullClip, string.Empty, float3.zero, new float3(0, 1, 0), clipDuration);
            CreateLinearTranslate(fullClip, "Child1", r.NextFloat3(-range, range), r.NextFloat3(-range, range), clipDuration);
            CreateLinearTranslate(fullClip, "Child2", r.NextFloat3(-range, range), r.NextFloat3(-range, range), clipDuration);
            CreateRotation(fullClip, string.Empty, quaternion.identity, r.NextQuaternionRotation(), clipDuration);
            CreateRotation(fullClip, "Child1", r.NextQuaternionRotation(), r.NextQuaternionRotation(), clipDuration);
            CreateRotation(fullClip, "Child2", r.NextQuaternionRotation(), r.NextQuaternionRotation(), clipDuration);
            CreateScale(fullClip, string.Empty, new float3(1), new float3(1), clipDuration);
            CreateScale(fullClip, "Child1", new float3(1), new float3(2), clipDuration);
            CreateScale(fullClip, "Child2", new float3(2), new float3(3), clipDuration);
            FullAnimationClip = ClipBuilder.AnimationClipToDenseClip(fullClip);

            var partialClip = new UnityEngine.AnimationClip();

            CreateLinearTranslate(partialClip, "Child1", r.NextFloat3(-range, range), r.NextFloat3(-range, range), clipDuration);
            CreateRotation(partialClip, string.Empty, quaternion.identity, r.NextQuaternionRotation(), clipDuration);
            CreateRotation(partialClip, "Child2", quaternion.identity, r.NextQuaternionRotation(), clipDuration);
            CreateScale(partialClip, string.Empty, float3.zero, new float3(1), clipDuration);
            PartialAnimationClip = ClipBuilder.AnimationClipToDenseClip(partialClip);

            var alignedClip = new UnityEngine.AnimationClip();

            CreateLinearTranslate(alignedClip, string.Empty, float3.zero, new float3(0, 1, 0), 1.0f);
            CreateLinearTranslate(alignedClip, "Child1", r.NextFloat3(-range, range), r.NextFloat3(-range, range), 1.0f);
            CreateLinearTranslate(alignedClip, "Child2", r.NextFloat3(-range, range), r.NextFloat3(-range, range), 1.0f);
            CreateRotation(alignedClip, string.Empty, quaternion.identity, r.NextQuaternionRotation(), 1.0f);
            AlignedClip = ClipBuilder.AnimationClipToDenseClip(alignedClip);
        }
        public void DFGBuffer_ToECSBuffer_WithMismatchedSize_OnlyBlitsSharedPortion([Values(1, 3, 13, 50)] int bufferSize, [Values(true, false)] bool sourceIsBigger)
        {
            const int k_SizeDifference = 11;

            using (var f = new Fixture <UpdateSystem>())
            {
                var entitySource      = f.EM.CreateEntity(typeof(SimpleBuffer), typeof(SimpleData));
                var entityDestination = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNodeSource = f.Set.CreateComponentNode(entitySource);
                var entityNodeDest   = f.Set.CreateComponentNode(entityDestination);

                var dfgNode = f.Set.Create <BufferNode>();
                var gv      = f.Set.CreateGraphValue(dfgNode, BufferNode.KernelPorts.Output);

                f.Set.Connect(entityNodeSource, ComponentNode.Output <SimpleBuffer>(), dfgNode, BufferNode.KernelPorts.Input);
                f.Set.Connect(dfgNode, BufferNode.KernelPorts.Output, entityNodeDest, ComponentNode.Input <SimpleBuffer>());

                var rng = new Mathematics.Random(0x8f);

                var ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                var ecsDestBuffer   = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                var sourceSize = sourceIsBigger ? bufferSize * k_SizeDifference : bufferSize;
                var destSize   = sourceIsBigger ? bufferSize : bufferSize * k_SizeDifference;

                // Make sources much larger than destination
                ecsSourceBuffer.ResizeUninitialized(sourceSize);
                ecsDestBuffer.ResizeUninitialized(destSize);
                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(sourceSize));

                ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                for (int n = 0; n < sourceSize; ++n)
                {
                    ecsSourceBuffer[n] = new SimpleBuffer {
                        Values = rng.NextFloat3()
                    };
                }

                f.System.Update();
                ecsDestBuffer = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                // TODO: can compare alias here
                for (int n = 0; n < bufferSize; ++n)
                {
                    Assert.AreEqual(ecsSourceBuffer[n], ecsDestBuffer[n]);
                }

                f.Set.ReleaseGraphValue(gv);
                f.Set.Destroy(entityNodeSource, entityNodeDest, dfgNode);
            }
        }
        static unsafe string MakeRandomFileName()
        {
            const int kFilenameLen   = 16;
            var       filenameBuffer = stackalloc char[kFilenameLen];
            var       rng            = new Mathematics.Random((uint)Time.realtimeSinceStartup);

            for (int i = 0; i < kFilenameLen; ++i)
            {
                filenameBuffer[i] = rng.NextBool() ? (char)rng.NextInt('a', 'z') : (char)rng.NextInt('0', '9');
            }

            return(new string(filenameBuffer, 0, kFilenameLen));
        }
예제 #6
0
        public void InitializeInputWithCopyArrays(NativeArray <BoundingVolumeHierarchy.PointAndIndex> points, NativeArray <Aabb> aabbs, NativeArray <CollisionFilter> filters)
        {
            var random = new Mathematics.Random(1234);

            const float posRange       = 1000f;
            const float radiusRangeMin = 1f;
            const float radiusRangeMax = 10f;

            for (int i = 0; i < points.Length; i++)
            {
                var pos = random.NextFloat2(-posRange, posRange);
                points[i] = new BoundingVolumeHierarchy.PointAndIndex {
                    Position = pos, Index = i
                };

                var radius = new float2(random.NextFloat(radiusRangeMin, radiusRangeMax));
                aabbs[i] = new Aabb {
                    Min = pos - radius, Max = pos + radius
                };

                points[i + 1] = new BoundingVolumeHierarchy.PointAndIndex {
                    Position = pos, Index = i + 1
                };

                aabbs[i + 1] = new Aabb {
                    Min = pos - radius, Max = pos + radius
                };

                filters[i] = new CollisionFilter
                {
                    GroupIndex   = 0,
                    BelongsTo    = random.NextUInt(0, 16),
                    CollidesWith = random.NextUInt(0, 16)
                };

                filters[i + 1] = new CollisionFilter
                {
                    GroupIndex   = 0,
                    BelongsTo    = random.NextUInt(0, 16),
                    CollidesWith = random.NextUInt(0, 16)
                };

                i++;
            }
        }
예제 #7
0
        unsafe public void Render()
        {
            if (m_DebugRenderMode == DebugRenderMode.None)
            {
                return;
            }

            if (m_DebugRenderMode == DebugRenderMode.Mesh)
            {
                var OcclusionMesh = GetComponentTypeHandle <OcclusionMesh>();

                var material = new Material(Shader.Find("Hidden/OcclusionDebug"));

                var layout = new[]
                {
                    new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 4)
                };

                var chunks = m_Occluders.CreateArchetypeChunkArray(Allocator.TempJob);

                Mathematics.Random rnd = new Mathematics.Random(1);
                for (int i = 0; i < chunks.Length; ++i)
                {
                    var chunk  = chunks[i];
                    var meshes = chunk.GetNativeArray(OcclusionMesh);
                    for (int k = 0; k < meshes.Length; k++)
                    {
                        var m = meshes[k];

                        Mesh mesh = new Mesh();
                        mesh.SetVertexBufferParams(m.vertexCount, layout);

                        var verts = (float4 *)m.transformedVertexData.GetUnsafePtr();
                        var tris  = (int *)m.indexData.GetUnsafePtr();

                        var outVerts = new NativeArray <Vector4>(m.vertexCount, Allocator.Temp);
                        for (int vtx = 0; vtx < m.vertexCount; vtx++, ++verts)
                        {
                            outVerts[vtx] = new Vector4(verts->x, verts->y, verts->z, verts->w);
                        }
                        mesh.SetVertexBufferData(outVerts, 0, 0, m.vertexCount);
                        outVerts.Dispose();

                        var outTris = new int[m.indexCount];
                        for (int idx = 0; idx < m.indexCount; idx++, ++tris)
                        {
                            outTris[idx] = *tris;
                        }
                        mesh.SetIndices(outTris, MeshTopology.Triangles, 0);

                        mesh.name = $"Debug Occluder {i}:{k}";

                        // the vertices are already in screenspace and perspective projected
                        mesh.bounds = new Bounds(Vector3.zero, new Vector3(10000, 10000, 1000));

                        var color = Color.HSVToRGB(rnd.NextFloat(), 1.0f, 1.0f);
                        material.SetColor("_Color", color);

                        material.SetPass(0);
                        Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
                    }
                }

                chunks.Dispose();
            }
            else if (m_DepthTexture != null)
            {
                var  material = new Material(Shader.Find("Hidden/OcclusionShowDepth"));
                Mesh quad     = GetQuadMesh();


                if (m_DebugRenderMode == DebugRenderMode.Bounds)
                {
                    material.EnableKeyword("BOUNDS_ONLY");
                }
                else if (m_DebugRenderMode == DebugRenderMode.Test)
                {
                    material.EnableKeyword("DEPTH_WITH_TEST");
                }

                material.SetTexture("_Depth", m_DepthTexture);
                material.SetTexture("_Test", m_TestTexture);
                material.SetTexture("_Bounds", m_BoundsTexture);
                material.SetPass(0);
                Graphics.DrawMeshNow(quad, Matrix4x4.identity);
            }
        }
        public void CanReadAndWrite_ToSameECSBuffer_FromInsideDFG(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize,
            [Values] bool feedbackAfterProcessing)
        {
            const int k_Loops  = 10;
            var       k_Offset = new float3(1.0f, 1.5f, 2.0f);

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entity = f.EM.CreateEntity(typeof(SimpleBuffer), typeof(SimpleData));

                var entityNode = f.Set.CreateComponentNode(entity);

                var dfgNode = f.Set.Create <BufferNode>();
                f.Set.SetData(dfgNode, BufferNode.KernelPorts.Offset, k_Offset);

                f.Set.Connect(
                    entityNode,
                    ComponentNode.Output <SimpleBuffer>(),
                    dfgNode,
                    BufferNode.KernelPorts.Input,
                    !feedbackAfterProcessing ? NodeSet.ConnectionType.Feedback : NodeSet.ConnectionType.Normal
                    );

                f.Set.Connect(
                    dfgNode,
                    BufferNode.KernelPorts.Output,
                    entityNode,
                    ComponentNode.Input <SimpleBuffer>(),
                    feedbackAfterProcessing ? NodeSet.ConnectionType.Feedback : NodeSet.ConnectionType.Normal
                    );

                var ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);

                // match all buffer sizes
                ecsBuffer.ResizeUninitialized(bufferSize);
                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(bufferSize));

                var expected = new List <SimpleBuffer>();

                var rng = new Mathematics.Random(0x8f);
                for (int n = 0; n < bufferSize; ++n)
                {
                    ecsBuffer[n] = new SimpleBuffer {
                        Values = feedbackAfterProcessing ? -k_Offset : rng.NextFloat3()
                    };
                    expected.Add(ecsBuffer[n]);
                }

                for (int i = 0; i < k_Loops; ++i)
                {
                    f.System.Update();

                    // This should fence on all dependencies
                    ecsBuffer = f.EM.GetBuffer <SimpleBuffer>(entity);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        expected[n] = new SimpleBuffer {
                            Values = expected[n].Values + k_Offset
                        }
                    }
                    ;

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(expected[n], ecsBuffer[n]);
                    }
                }

                f.Set.Destroy(entityNode, dfgNode);
            }
        }
    }
        public void CanConnect_ECSBuffer_ToECSBuffer_UsingOnlyComponentNodes_AndTransferData(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize,
            [Values] ConnectionMode strongNess)
        {
            const int k_Loops = 10;

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entitySource      = f.EM.CreateEntity(typeof(SimpleBuffer));
                var entityDestination = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNodeSource = f.Set.CreateComponentNode(entitySource);
                var entityNodeDest   = f.Set.CreateComponentNode(entityDestination);

                if (strongNess == ConnectionMode.Strong)
                {
                    f.Set.Connect(
                        entityNodeSource,
                        ComponentNode.Output <SimpleBuffer>(),
                        entityNodeDest,
                        ComponentNode.Input <SimpleBuffer>()
                        );
                }
                else
                {
                    f.Set.Connect(
                        entityNodeSource,
                        (OutputPortID)ComponentNode.Output <SimpleBuffer>(),
                        entityNodeDest,
                        (InputPortID)ComponentNode.Input <SimpleBuffer>()
                        );
                }

                var rng = new Mathematics.Random(0x8f);

                var ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                var ecsDestBuffer   = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                // match all buffer sizes
                ecsSourceBuffer.ResizeUninitialized(bufferSize);
                ecsDestBuffer.ResizeUninitialized(bufferSize);

                for (int i = 0; i < k_Loops; ++i)
                {
                    ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        ecsSourceBuffer[n] = new SimpleBuffer {
                            Values = rng.NextFloat3()
                        };
                    }

                    f.System.Update();

                    // This should fence on all dependencies
                    ecsDestBuffer = f.EM.GetBuffer <SimpleBuffer>(entityDestination);
                    //f.Set.DataGraph.SyncAnyRendering();
                    // TODO: can compare alias here
                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(ecsSourceBuffer[n], ecsDestBuffer[n]);
                    }
                }

                f.Set.Destroy(entityNodeSource, entityNodeDest);
            }
        }
        public void CanWrite_ToECSBuffer_InsideFromDFG_FromOriginalECS_Source(
            [Values] NodeSet.RenderExecutionModel model,
            [Values(1, 3, 13, 50)] int bufferSize,
            [Values] ConnectionMode strongNess)
        {
            const int k_Loops = 10;

            using (var f = new Fixture <UpdateSystem>())
            {
                f.Set.RendererModel = model;
                var entitySource      = f.EM.CreateEntity(typeof(SimpleBuffer));
                var entityDestination = f.EM.CreateEntity(typeof(SimpleBuffer));

                var entityNodeSource = f.Set.CreateComponentNode(entitySource);
                var entityNodeDest   = f.Set.CreateComponentNode(entityDestination);

                var dfgNode = f.Set.Create <BufferNode>();
                var gv      = f.Set.CreateGraphValue(dfgNode, BufferNode.KernelPorts.Output);

                if (strongNess == ConnectionMode.Strong)
                {
                    f.Set.Connect(entityNodeSource, ComponentNode.Output <SimpleBuffer>(), dfgNode, BufferNode.KernelPorts.Input);
                    f.Set.Connect(dfgNode, BufferNode.KernelPorts.Output, entityNodeDest, ComponentNode.Input <SimpleBuffer>());
                }
                else
                {
                    f.Set.Connect(
                        entityNodeSource,
                        (OutputPortID)ComponentNode.Output <SimpleBuffer>(),
                        dfgNode,
                        (InputPortID)BufferNode.KernelPorts.Input
                        );

                    f.Set.Connect(
                        dfgNode,
                        (OutputPortID)BufferNode.KernelPorts.Output,
                        entityNodeDest,
                        (InputPortID)ComponentNode.Input <SimpleBuffer>()
                        );
                }

                var rng = new Mathematics.Random(0x8f);

                var ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);
                var ecsDestBuffer   = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                // match all buffer sizes
                ecsSourceBuffer.ResizeUninitialized(bufferSize);
                ecsDestBuffer.ResizeUninitialized(bufferSize);
                f.Set.SetBufferSize(dfgNode, BufferNode.KernelPorts.Output, Buffer <SimpleBuffer> .SizeRequest(bufferSize));

                for (int i = 0; i < k_Loops; ++i)
                {
                    ecsSourceBuffer = f.EM.GetBuffer <SimpleBuffer>(entitySource);

                    for (int n = 0; n < bufferSize; ++n)
                    {
                        ecsSourceBuffer[n] = new SimpleBuffer {
                            Values = rng.NextFloat3()
                        };
                    }

                    f.System.Update();

                    // This should fence on all dependencies
                    ecsDestBuffer = f.EM.GetBuffer <SimpleBuffer>(entityDestination);

                    // TODO: can compare alias here
                    for (int n = 0; n < bufferSize; ++n)
                    {
                        Assert.AreEqual(ecsSourceBuffer[n], ecsDestBuffer[n]);
                    }
                }

                f.Set.ReleaseGraphValue(gv);
                f.Set.Destroy(entityNodeSource, entityNodeDest, dfgNode);
            }
        }