Пример #1
0
 void EndStroke()
 {
     if (eCurrentShape != Entity.Null)
     {
         DynamicMeshData dmd = EntityManager.GetComponentData <DynamicMeshData>(eCurrentShape);
         dmd.Dirty = true;
         dmd.UseDynamicGPUBuffer = false;
         EntityManager.SetComponentData(eCurrentShape, dmd);
         //EntityManager.RemoveComponent<GizmoNormalsAndTangents>(eCurrentShape);
         //EntityManager.RemoveComponent<GizmoObjectBoundingBox>(eCurrentShape);
         strokeStack.Add(eCurrentShape);
     }
     eCurrentShape = Entity.Null;
     drawList.Clear();
 }
Пример #2
0
        void AddMeshRendererComponents(Entity e, int nVertex, int nIndex, NativeArray <SimpleVertex> vertices)
        {
            MeshRenderer mr = EntityManager.GetComponentData <MeshRenderer>(e);

            mr.startIndex = 0;
            mr.indexCount = nIndex;
            EntityManager.SetComponentData(e, mr);

            DynamicMeshData dmd = EntityManager.GetComponentData <DynamicMeshData>(e);

            dmd.Dirty       = true;
            dmd.NumIndices  = nIndex;
            dmd.NumVertices = nVertex;

            MeshBounds mb = default;

            mb.Bounds = MeshHelper.ComputeBounds(vertices);

            EntityManager.SetComponentData <DynamicMeshData>(e, dmd);
            EntityManager.SetComponentData(e, mb);
        }
Пример #3
0
        void ContinueStroke(float2 inputPos)
        {
            if (eCurrentShape == Entity.Null)
            {
                return;
            }
            float3 pos = s2w.InputPosToWorldSpacePos(inputPos, 4.0f);

            drawList.Add(pos);
            var resampleList = MeshHelper.ResampleCatmullRom(drawList, .075f, false, Allocator.TempJob);

            if (resampleList.Length >= 3)
            {
                // replace the existing CPU mesh, invalidate content
                var       iBuffer   = EntityManager.GetBuffer <DynamicIndex>(eCurrentShape);
                var       vBuffer   = EntityManager.GetBuffer <DynamicLitVertex>(eCurrentShape);
                const int nSegments = 9;
                int       ni        = MeshHelper.ExtrudedLineMeshRequiredIndices(resampleList.Length, nSegments);
                int       nv        = MeshHelper.ExtrudedLineMeshRequiredVertices(resampleList.Length, nSegments);
                if (ni <= iBuffer.Capacity && nv <= vBuffer.Capacity)
                {
                    vBuffer.ResizeUninitialized(nv);
                    iBuffer.ResizeUninitialized(ni);
                    MeshHelper.SmoothCurve(resampleList);
                    MeshHelper.SmoothCurve(resampleList);
                    MeshHelper.FillExtrudedLineCircle(
                        vBuffer.AsNativeArray().Reinterpret <DynamicLitVertex, LitVertex>(),
                        iBuffer.AsNativeArray().Reinterpret <DynamicIndex, ushort>(),
                        drawSize, drawSize, .5f, resampleList, nSegments, false);
                    MeshHelper.SetAlbedoColor(
                        vBuffer.AsNativeArray().Reinterpret <DynamicLitVertex, LitVertex>(),
                        new float4(drawColor, 1));
                    DynamicMeshData dmd = EntityManager.GetComponentData <DynamicMeshData>(eCurrentShape);
                    dmd.Dirty       = true;
                    dmd.NumIndices  = iBuffer.Length;
                    dmd.NumVertices = vBuffer.Length;
                    MeshBounds mb;
                    mb.Bounds = MeshHelper.ComputeBounds(vBuffer.AsNativeArray().Reinterpret <DynamicLitVertex, LitVertex>());
                    EntityManager.SetComponentData <DynamicMeshData>(eCurrentShape, dmd);
                    EntityManager.SetComponentData(eCurrentShape, mb);
                    EntityManager.SetComponentData <Translation>(eCurrentShape, new Translation {
                        Value = new float3(0)
                    });
                    EntityManager.SetComponentData <Rotation>(eCurrentShape, new Rotation {
                        Value = quaternion.identity
                    });
                    EntityManager.SetComponentData <LocalToWorld>(eCurrentShape, new LocalToWorld {
                        Value = float4x4.identity
                    });
                    // have to update the index count of the submesh
                    var mr = EntityManager.GetComponentData <MeshRenderer>(eCurrentShape);
                    mr.indexCount = dmd.NumIndices;
                    mr.material   = eCurrentMaterial;
                    EntityManager.SetComponentData(eCurrentShape, mr);
                    if (EntityManager.HasComponent <DemoSpinner>(eCurrentShape))
                    {
                        EntityManager.RemoveComponent <DemoSpinner>(eCurrentShape);
                    }
                }
                else
                {
                    Debug.Log("Stroke is too long.");
                }
            }
            resampleList.Dispose();
        }
Пример #4
0
        void BeginStroke(float2 inputPos)
        {
            if (eCurrentShape != Entity.Null)
            {
                EndStroke();
            }
            float3 pos = s2w.InputPosToWorldSpacePos(inputPos, 4.0f);

            // start a new shape
            eCurrentShape = EntityManager.CreateEntity();
            EntityManager.AddBuffer <DynamicLitVertex>(eCurrentShape);
            EntityManager.AddBuffer <DynamicIndex>(eCurrentShape);
            var iBuffer = EntityManager.GetBuffer <DynamicIndex>(eCurrentShape);
            var vBuffer = EntityManager.GetBuffer <DynamicLitVertex>(eCurrentShape);
            int tess    = 65;

            vBuffer.Capacity = 0x10000;
            vBuffer.ResizeUninitialized(tess * tess);
            iBuffer.Capacity = 0x60000;
            iBuffer.ResizeUninitialized((tess - 1) * (tess - 1) * 6);
            DynamicMeshData dmd = new DynamicMeshData
            {
                Dirty               = true,
                IndexCapacity       = iBuffer.Capacity,
                VertexCapacity      = vBuffer.Capacity,
                NumIndices          = iBuffer.Length,
                NumVertices         = vBuffer.Length,
                UseDynamicGPUBuffer = true
            };
            MeshBounds mb;

            MeshHelper.CreateSuperEllipsoid(new float3(drawSize * 2.0f),
                                            vBuffer.AsNativeArray().Reinterpret <DynamicLitVertex, LitVertex>(),
                                            iBuffer.AsNativeArray().Reinterpret <DynamicIndex, ushort>(),
                                            random.NextFloat(0.04f, 3.0f), random.NextFloat(0.04f, 3.0f), tess, tess,
                                            out mb.Bounds); // start with a dot.. box
            MeshHelper.SetAlbedoColor(
                vBuffer.AsNativeArray().Reinterpret <DynamicLitVertex, LitVertex>(),
                new float4(drawColor, 1));
            EntityManager.AddComponentData <DynamicMeshData>(eCurrentShape, dmd);
            EntityManager.AddComponentData <MeshRenderer>(eCurrentShape, new MeshRenderer
            {
                mesh       = eCurrentShape,
                material   = eCurrentMaterial,
                startIndex = 0,
                indexCount = dmd.NumIndices // because mesh renderers can render only parts of a mesh (sub-mesh) we need to also update the count here
            });
            EntityManager.AddComponentData(eCurrentShape, new LitMeshRenderer());
            EntityManager.AddComponentData(eCurrentShape, mb);
            EntityManager.AddComponentData <Translation>(eCurrentShape, new Translation {
                Value = pos
            });
            EntityManager.AddComponentData <Rotation>(eCurrentShape, new Rotation {
                Value = quaternion.identity
            });
            EntityManager.AddComponentData <LocalToWorld>(eCurrentShape, new LocalToWorld {
                Value = float4x4.Translate(pos)
            });
            EntityManager.AddComponentData(eCurrentShape, new DemoSpinner {
                spin = math.normalize(new quaternion(new float4(random.NextFloat3Direction(), 1)))
            });
            //EntityManager.AddComponentData(eCurrentShape, new GizmoNormalsAndTangents { width = 2.0f, length = .1f });
            //EntityManager.AddComponentData(eCurrentShape, new GizmoObjectBoundingBox {  color = new float4(0,0,0,1), width=4.0f });
            //EntityManager.AddComponentData(eCurrentShape, new GizmoBoundingSphere {  subdiv=32, width=4.0f });

            // start shaper
            drawList.Clear();
            drawList.Add(pos);
        }
Пример #5
0
        protected override unsafe void OnUpdate()
        {
            CompleteDependency();

            // If someone is just creating text, we'll take care of the material and mesh
            // TODO -- we really need an efficient way to one-step transform an entity into
            // the shape that we need
            Entities
            .WithAll <TextRendererString>()
            .WithNone <MeshRenderer, DynamicMeshData>()
            .WithNone <MeshBounds, DynamicSimpleVertex, DynamicIndex>()
            .WithStructuralChanges()
            .ForEach((ref Entity entity, in TextRenderer font) =>
            {
                // will fill in startIndex/indexCount later
                if (!EntityManager.HasComponent <MeshRenderer>(entity))
                {
                    EntityManager.AddComponentData(entity, new MeshRenderer
                    {
                        mesh       = entity,
                        material   = font.FontMaterial,
                        startIndex = 0,
                        indexCount = 0
                    });
                }

                // may as well, these are likely not there
                EntityManager.AddComponent <DynamicMeshData>(entity);
                EntityManager.AddComponent <MeshBounds>(entity);
                EntityManager.AddBuffer <DynamicSimpleVertex>(entity);
                EntityManager.AddBuffer <DynamicIndex>(entity);

                // for new things force the update
                EntityManager.AddComponent <TextRendererNeedsUpdate>(entity);
            })
            .Run();

            var textMaterialFromEntity    = GetComponentDataFromEntity <BitmapFontMaterial>();
            var textSDFMaterialFromEntity = GetComponentDataFromEntity <SDFFontMaterial>();
            var dsvFromEntity             = GetBufferFromEntity <DynamicSimpleVertex>();
            var diFromEntity = GetBufferFromEntity <DynamicIndex>();

            var srgbColors = GetSingleton <DisplayInfo>().colorSpace == ColorSpace.Gamma;

            // we're going to do fine-grained change tracking, because mesh generation is costly since it'll
            // cause a re-upload to graphics
            var ecb = new EntityCommandBuffer(Allocator.TempJob);

            Entities
            .WithAll <TextRendererNeedsUpdate>()
            .ForEach((Entity entity, ref MeshRenderer meshRenderer,
                      ref TextRenderer fontRef,
                      ref DynamicBuffer <TextRendererString> text) =>
            {
                if (fontRef.FontMaterial == Entity.Null)
                {
                    return;
                }

                //Console.WriteLine($"[{entity.Index}:{entity.Version}] match");

                // TODO support static text meshes too.  For our initial impl the mesh is always dynamic
                var meshEntity = meshRenderer.mesh;

                // This meshEntity will often be the same as the renderer entity (e.g. if setup was done
                // as above, next to TextRendererString component).  But it doesn't need to be; there could be
                // a shared mesh.  In that case though, this code will end up modifying every text string
                // that uses that mesh, which is probably not what's desired!
                // We also don't really need a dozen meshes for the identical string/font.  All of this can
                // be significantly optimized.
                var vertexBuffer = dsvFromEntity[meshEntity];
                var indexBuffer  = diFromEntity[meshEntity];

                var vertexColor = srgbColors ? Color.LinearToSRGB(fontRef.MeshColor.AsFloat4()) : fontRef.MeshColor.AsFloat4();

                //string s = new String((char*)UnsafeUtility.AddressOf(ref text.ElementAt(0)), 0, text.Length);
                //Console.WriteLine($"[{entity.Index}:{entity.Version}] Generating mesh for {s}");

                AABB bounds;
                BlobAssetReference <FontData> fontData;

                if (textMaterialFromEntity.HasComponent(fontRef.FontMaterial))
                {
                    var material = textMaterialFromEntity[fontRef.FontMaterial];
                    fontData     = material.FontData;
                }
                else if (textSDFMaterialFromEntity.HasComponent(fontRef.FontMaterial))
                {
                    var material = textSDFMaterialFromEntity[fontRef.FontMaterial];
                    fontData     = material.FontData;
                }
                else
                {
                    throw new InvalidOperationException();
                }

                TextLayout.LayoutString((char *)text.GetUnsafePtr(), text.Length,
                                        fontRef.Size, fontRef.HorizontalAlignment,
                                        vertexColor,
                                        ref fontData.Value,
                                        vertexBuffer, indexBuffer, out bounds);

                meshRenderer.startIndex = 0;
                meshRenderer.indexCount = indexBuffer.Length;

                var dmd = new DynamicMeshData
                {
                    Dirty               = true,
                    IndexCapacity       = indexBuffer.Capacity,
                    VertexCapacity      = vertexBuffer.Capacity,
                    NumIndices          = indexBuffer.Length,
                    NumVertices         = vertexBuffer.Length,
                    UseDynamicGPUBuffer = true
                };

                ecb.SetComponent(meshEntity, dmd);
                ecb.SetComponent(meshEntity, new MeshBounds {
                    Bounds = bounds
                });

                ecb.RemoveComponent <TextRendererNeedsUpdate>(entity);
            })
            .Run();
            ecb.Playback(EntityManager);
            ecb.Dispose();
        }
Пример #6
0
        void CreateSimpleRenderer(Entity eMesh, quaternion rot, float3 pos, float3 scale)
        {
            EntityManager.AddComponentData(eMesh, new MeshRenderer // renderer -> maps to shader to use
            {
                material   = eMesh,
                mesh       = eMesh,
                startIndex = 0,
                indexCount = 0
            });

            EntityManager.AddComponentData(eMesh, new LocalToWorld
            {
                Value = float4x4.identity
            });
            EntityManager.AddComponentData(eMesh, new Translation
            {
                Value = pos
            });
            EntityManager.AddComponentData(eMesh, new Rotation
            {
                Value = rot
            });
            if (scale.x != scale.y || scale.y != scale.z)
            {
                EntityManager.AddComponentData(eMesh, new NonUniformScale
                {
                    Value = scale
                });
            }
            else if (scale.x != 1.0f)
            {
                EntityManager.AddComponentData(eMesh, new Scale
                {
                    Value = scale.x
                });
            }

            EntityManager.AddComponentData(eMesh, new WorldBounds());

            EntityManager.AddBuffer <DynamicSimpleVertex>(eMesh);
            EntityManager.AddBuffer <DynamicIndex>(eMesh);

            var iBuffer = EntityManager.GetBuffer <DynamicIndex>(eMesh);
            var vBuffer = EntityManager.GetBuffer <DynamicSimpleVertex>(eMesh);

            vBuffer.Capacity = kMaxVertex;
            vBuffer.ResizeUninitialized(kMaxVertex);
            iBuffer.Capacity = kMaxIndex;
            iBuffer.ResizeUninitialized(kMaxIndex);

            DynamicMeshData dmd = new DynamicMeshData
            {
                Dirty               = true,
                IndexCapacity       = iBuffer.Capacity,
                VertexCapacity      = vBuffer.Capacity,
                NumIndices          = iBuffer.Length,
                NumVertices         = vBuffer.Length,
                UseDynamicGPUBuffer = false
            };

            EntityManager.AddComponentData <DynamicMeshData>(eMesh, dmd);
        }