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)); }
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()); }
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)); }
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; }
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; }); } }
public UnionSDF(SignedDistanceField a, SignedDistanceField b) { this.a = a; this.b = b; }
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(); }
public IntersectSDF(SignedDistanceField a, SignedDistanceField b) { this.a = a; this.b = b; }