Example #1
0
        public BasicEntity(ModelDefinition modelbb, MaterialEffect material, Vector3 position, double angleZ, double angleX, double angleY, Vector3 scale, MeshMaterialLibrary library = null, Entity physicsObject = null)
        {
            Id                  = IdGenerator.GetNewId();
            Name                = GetType().Name + " " + Id;
            WorldTransform      = new TransformMatrix(Matrix.Identity, Id);
            ModelDefinition     = modelbb;
            Model               = modelbb.Model;
            BoundingBox         = modelbb.BoundingBox;
            BoundingBoxOffset   = modelbb.BoundingBoxOffset;
            SignedDistanceField = modelbb.SDF;

            Material = material;
            Position = position;
            Scale    = scale;

            RotationMatrix = Matrix.CreateRotationX((float)angleX) * Matrix.CreateRotationY((float)angleY) *
                             Matrix.CreateRotationZ((float)angleZ);

            if (library != null)
            {
                RegisterInLibrary(library);
            }

            if (physicsObject != null)
            {
                RegisterPhysics(physicsObject);
            }

            WorldTransform.World        = Matrix.CreateScale(Scale) * RotationMatrix * Matrix.CreateTranslation(Position);
            WorldTransform.Scale        = Scale;
            WorldTransform.InverseWorld = Matrix.Invert(Matrix.CreateTranslation(BoundingBoxOffset * Scale) * RotationMatrix * Matrix.CreateTranslation(Position));
        }
Example #2
0
    public void Run(SignedDistanceFieldGenerator _generator, SignedDistanceField _target)
    {
        generator    = _generator;
        target       = _target;
        tex          = new Texture2D(generator.m_x_dims, generator.m_y_dims, TextureFormat.RGBAFloat, false);
        outside_grid = new float[generator.m_pixels.Length];
        inside_grid  = new float[generator.m_pixels.Length];
        col_buff     = new Color[generator.m_pixels.Length];

        target.m_texture = tex;
        target.StartCoroutine(SweepRoutine());
    }
Example #3
0
        public BasicEntity(ModelDefinition modelbb, MaterialEffect material, Vector3 position, Matrix rotationMatrix, Vector3 scale)
        {
            Id                  = IdGenerator.GetNewId();
            Name                = GetType().Name + " " + Id;
            WorldTransform      = new TransformMatrix(Matrix.Identity, Id);
            Model               = modelbb.Model;
            ModelDefinition     = modelbb;
            BoundingBox         = modelbb.BoundingBox;
            BoundingBoxOffset   = modelbb.BoundingBoxOffset;
            SignedDistanceField = modelbb.SDF;

            Material       = material;
            Position       = position;
            RotationMatrix = rotationMatrix;
            Scale          = scale;
            RotationMatrix = rotationMatrix;

            WorldTransform.World        = Matrix.CreateScale(Scale) * RotationMatrix * Matrix.CreateTranslation(Position);
            WorldTransform.Scale        = Scale;
            WorldTransform.InverseWorld = Matrix.Invert(Matrix.CreateTranslation(BoundingBoxOffset * Scale) * RotationMatrix * Matrix.CreateTranslation(Position));
        }
Example #4
0
        private void GenerateData(int xsteps, int ysteps, int zsteps, SignedDistanceField volumeTex, ref float[] data, int threadindex, int numberOfThreads, Triangle[] triangles)
        {
            int xi, yi, zi;

            float volumeTexSizeX = volumeTex.VolumeSize.X;
            float volumeTexSizeY = volumeTex.VolumeSize.Y;
            float volumeTexSizeZ = volumeTex.VolumeSize.Z;

            Vector3 offset = new Vector3(volumeTex.Offset.X, volumeTex.Offset.Y, volumeTex.Offset.Z);

            int i = 0;

            for (xi = 0; xi < xsteps; xi++)
            {
                for (yi = 0; yi < ysteps; yi++)
                {
                    for (zi = 0; zi < zsteps; zi++)
                    {
                        //Only do it for the current thread!
                        if (i++ % numberOfThreads != threadindex)
                        {
                            continue;
                        }

                        Vector3 position = new Vector3(xi * volumeTexSizeX * 2.0f / (xsteps - 1) - volumeTexSizeX,
                                                       yi * volumeTexSizeY * 2.0f / (ysteps - 1) - volumeTexSizeY,
                                                       zi * volumeTexSizeZ * 2.0f / (zsteps - 1) - volumeTexSizeZ) + offset;

                        float color = ComputeSDF(position, triangles);

                        data[toTexCoords(xi, yi, zi, xsteps, zsteps)] = color;

                        if (threadindex == 0)
                        {
                            GameStats.sdf_load = (xi + (yi + zi / (float)zsteps) / (float)ysteps) / (float)xsteps;
                        }
                    }
                }
            }
        }
        public RenderTarget2D CreateSDFTexture(GraphicsDevice graphics, Texture2D triangleData, int xsteps, int ysteps, int zsteps, SignedDistanceField sdf, FullScreenTriangle fullScreenTriangle, int trianglesLength)
        {
            RenderTarget2D output = new RenderTarget2D(graphics, xsteps * zsteps, ysteps, false, SurfaceFormat.Single, DepthFormat.None);

            graphics.SetRenderTarget(output);

            //Offset isntead of position!
            _volumeTexResolutionArray[0] = new Vector4(xsteps, ysteps, zsteps, 0);
            _volumeTexSizeArray[0]       = sdf.VolumeSize;

            _volumeTexSizeParam.SetValue(_volumeTexSizeArray);
            _volumeTexResolutionParam.SetValue(_volumeTexResolutionArray);

            MeshOffset = sdf.Offset;
            VolumeTex  = triangleData;

            _triangleTexResolution.SetValue(new Vector2(triangleData.Width, triangleData.Height));
            _triangleAmount.SetValue((float)trianglesLength);

            _generateSDFPass.Apply();
            fullScreenTriangle.Draw(graphics);

            _signedDistanceFieldDefinitionsCount = -1;

            return(output);
        }
 public SDFFigure(SignedDistanceField sdf, IMaterial material)
 {
     this.sdf      = sdf;
     this.Material = material;
 }
Example #7
0
        public void GenerateDistanceFields(BasicEntity entity, GraphicsDevice graphics, DistanceFieldRenderModule distanceFieldRenderModule, FullScreenTriangle fullScreenTriangle)
        {
            SignedDistanceField uncomputedSignedDistanceField = entity.SignedDistanceField;
            Model unprocessedModel = entity.Model;

            //Set to false so it won't get covered in future
            uncomputedSignedDistanceField.NeedsToBeGenerated = false;
            uncomputedSignedDistanceField.IsLoaded           = false;
            uncomputedSignedDistanceField.SdfTexture?.Dispose();

            //First generate tris
            Triangle[] triangles;
            GenerateTriangles(unprocessedModel, out triangles);

            int xsteps = (int)uncomputedSignedDistanceField.TextureResolution.X;
            int ysteps = (int)uncomputedSignedDistanceField.TextureResolution.Y;
            int zsteps = (int)uncomputedSignedDistanceField.TextureResolution.Z;

            Texture2D output;

            if (!GameSettings.sdf_cpu)
            {
                Stopwatch stopwatch = Stopwatch.StartNew();

                int maxwidth     = 4096; //16384
                int requiredData = triangles.Length * 3;

                int x = maxwidth;//Math.Min(requiredData, maxwidth);
                int y = requiredData / x + 1;

                Vector4[] data = new Vector4[x * y];

                int index = 0;
                for (int i = 0; i < triangles.Length; i++, index += 3)
                {
                    data[index]     = new Vector4(triangles[i].a, 0);
                    data[index + 1] = new Vector4(triangles[i].b, 0);
                    data[index + 2] = new Vector4(triangles[i].c, 0);
                }

                //16k

                Texture2D triangleData = new Texture2D(graphics, x, y, false, SurfaceFormat.Vector4);

                triangleData.SetData(data);

                output = distanceFieldRenderModule.CreateSDFTexture(graphics, triangleData, xsteps, ysteps,
                                                                    zsteps, uncomputedSignedDistanceField, fullScreenTriangle, triangles.Length);

                stopwatch.Stop();

                Debug.Write("\nSDF generated in " + stopwatch.ElapsedMilliseconds + "ms on GPU");

                float[] texData = new float[xsteps * ysteps * zsteps];

                output.GetData(texData);

                string path = uncomputedSignedDistanceField.TexturePath;
                DataStream.SaveImageData(texData, xsteps, ysteps, zsteps, path);
                uncomputedSignedDistanceField.TextureResolution = new Vector4(xsteps, ysteps, zsteps, 0);
                uncomputedSignedDistanceField.SdfTexture        = output;
                uncomputedSignedDistanceField.IsLoaded          = true;
            }
            else
            {
                generateTask = Task.Factory.StartNew(() =>
                {
                    output = new Texture2D(graphics, xsteps * zsteps, ysteps, false, SurfaceFormat.Single);

                    float[] data = new float[xsteps * ysteps * zsteps];

                    Stopwatch stopwatch = Stopwatch.StartNew();

                    int numberOfThreads = GameSettings.sdf_threads;

                    if (numberOfThreads > 1)
                    {
                        Task[] threads = new Task[numberOfThreads - 1];

                        //Make local datas

                        float[][] dataArray = new float[numberOfThreads][];

                        for (int index = 0; index < threads.Length; index++)
                        {
                            int i = index;
                            dataArray[index + 1] = new float[xsteps * ysteps * zsteps];
                            threads[i]           = Task.Factory.StartNew(() =>
                            {
                                GenerateData(xsteps, ysteps, zsteps, uncomputedSignedDistanceField,
                                             ref dataArray[i + 1], i + 1,
                                             numberOfThreads, triangles);
                            });
                        }

                        dataArray[0] = data;
                        GenerateData(xsteps, ysteps, zsteps, uncomputedSignedDistanceField, ref dataArray[0], 0,
                                     numberOfThreads, triangles);

                        Task.WaitAll(threads);

                        //Something broke?
                        for (int i = 0; i < data.Length; i++)
                        {
                            //data[i] = dataArray[i % numberOfThreads][i];
                            for (int j = 0; j < numberOfThreads; j++)
                            {
                                if (dataArray[j][i] != 0)
                                {
                                    data[i] = dataArray[j][i];
                                    break;
                                }
                            }
                        }

                        for (var index2 = 0; index2 < threads.Length; index2++)
                        {
                            threads[index2].Dispose();
                        }
                    }
                    else
                    {
                        GenerateData(xsteps, ysteps, zsteps, uncomputedSignedDistanceField, ref data, 0,
                                     numberOfThreads, triangles);
                    }

                    stopwatch.Stop();

                    Debug.Write("\nSDF generated in " + stopwatch.ElapsedMilliseconds + "ms with " +
                                GameSettings.sdf_threads + " thread(s)");

                    string path = uncomputedSignedDistanceField.TexturePath;
                    DataStream.SaveImageData(data, xsteps, ysteps, zsteps, path);
                    output.SetData(data);
                    uncomputedSignedDistanceField.TextureResolution = new Vector4(xsteps, ysteps, zsteps, 0);
                    uncomputedSignedDistanceField.SdfTexture        = output;
                    uncomputedSignedDistanceField.IsLoaded          = true;
                });
            }
        }
Example #8
0
 public UnionSDF(SignedDistanceField a, SignedDistanceField b)
 {
     this.a = a;
     this.b = b;
 }
Example #9
0
    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        DrawDefaultInspector();

        SignedDistanceField field = (SignedDistanceField)target;

        if (GUILayout.Button("BF line"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(16, 16);
            generator.BFLine(new Vector2(3.5f, 8.5f), new Vector2(12.5f, 8.5f));
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("1 BF circle"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(16, 16);
            generator.BFCircle(new Vector2(8, 8), 4);
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("1 BF rectangle"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(16, 16);
            generator.BFRect(new Vector2(3, 5), new Vector2(12, 10));
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("2 BF circles"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(16, 16);
            generator.BFCircle(new Vector2(5, 7), 3);
            generator.BFCircle(new Vector2(10, 8), 3.5f);
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("2 close BF rectangles"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(64, 64);
            generator.BFRect(new Vector2(4, 4), new Vector2(60, 35));
            generator.BFRect(new Vector2(4, 34), new Vector2(60, 60));
            field.m_texture = generator.End();
        }

        if (GUILayout.Button("1 padded line"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(32, 32);
            generator.PLine(new Vector2(8, 15), new Vector2(23, 20), 5);
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("1 padded circle"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(32, 32);
            generator.PCircle(new Vector2(16, 16), 7, 5);
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("1 padded rectangle"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(32, 32);
            generator.PRect(new Vector2(10, 12), new Vector2(20, 18), 5);
            field.m_texture = generator.End();
        }

        if (GUILayout.Button("Clear none edge pixels"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(64, 64);
            //generator.BFRect(new Vector2(4, 4), new Vector2(60, 35));
            //generator.BFRect(new Vector2(4, 34), new Vector2(60, 60));
            generator.PCircle(new Vector2(20, 28), 12, 5);
            generator.PCircle(new Vector2(40, 32), 14, 5);
            generator.ClearAndMarkNoneEdgePixels();
            field.m_texture = generator.End();
        }

        if (GUILayout.Button("Sweep close rectangle pixels"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(64, 64);
            generator.BFRect(new Vector2(4, 4), new Vector2(60, 35));
            generator.BFRect(new Vector2(4, 34), new Vector2(60, 60));
            generator.Sweep();
            field.m_texture = generator.End();
        }
        if (GUILayout.Button("Sweep close circles"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator(512, 512);
            generator.PCircle(new Vector2(160, 224), 92, 5);
            generator.PCircle(new Vector2(340, 256), 103, 5);
            generator.EikonalSweep();
            field.m_texture = generator.End();
        }

        if (GUILayout.Button("Load texture"))
        {
            SignedDistanceFieldGenerator generator = new SignedDistanceFieldGenerator();
            generator.LoadFromTextureAntiAliased(Resources.Load <Texture2D>("cathires"));
            generator.EikonalSweep();
            generator.Downsample();
            generator.Soften(3);
            field.m_texture = generator.End();
        }

        if (GUILayout.Button("Make noise texture"))
        {
            field.m_noise_texture = new Texture2D(256, 256, TextureFormat.RGBAFloat, false);
            Color[] cols = GenerateNoiseGrid(256, 256, 4, 8f, 2f, 0.5f);
            field.m_noise_texture.SetPixels(cols);
            field.m_noise_texture.Apply();
        }

        serializedObject.ApplyModifiedProperties();
    }
Example #10
0
 public IntersectSDF(SignedDistanceField a, SignedDistanceField b)
 {
     this.a = a;
     this.b = b;
 }