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)); }
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++; } }
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); } }