Skip to content

Commit

Permalink
Render cloth in demo, instead of wireframe.
Browse files Browse the repository at this point in the history
  • Loading branch information
notgiven688 committed Oct 28, 2023
1 parent 83b5344 commit 9992a95
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 34 deletions.
42 changes: 33 additions & 9 deletions src/JitterDemo/Demos/Demo17.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Jitter2.LinearMath;
using Jitter2.SoftBodies;
using JitterDemo.Renderer;
using JitterDemo.Renderer.OpenGL;

namespace JitterDemo;

Expand All @@ -18,6 +19,7 @@ public class Demo17 : IDemo, ICleanDemo
private SoftBodyCloth cloth = null!;
private World world = null!;

private Renderer.Cloth clothRenderer;
public void Build()
{
pg = (Playground)RenderWindow.Instance;
Expand All @@ -44,19 +46,23 @@ public void Build()

if (even)
{
tris.Add(new JTriangle(v0, v1, v2));
tris.Add(new JTriangle(v1, v2, v3));
tris.Add(new JTriangle(v0, v2, v1));
tris.Add(new JTriangle(v2, v3, v1));
}
else
{
tris.Add(new JTriangle(v1, v3, v0));
tris.Add(new JTriangle(v3, v2, v0));
tris.Add(new JTriangle(v0, v3, v1));
tris.Add(new JTriangle(v0, v2, v3));
}
}
}

cloth = new SoftBodyCloth(world, tris);

clothRenderer = pg.CSMRenderer.GetInstance<Cloth>();
clothRenderer.SetIndices(cloth.Triangles.ToArray());
SetUVCoordinates();

var b0 = world.CreateRigidBody();
b0.Position = new JVector(-1, 10, 0);
b0.AddShape(new BoxShape(1));
Expand Down Expand Up @@ -94,15 +100,33 @@ public void Build()
world.NumberSubsteps = 4;
}

public void Draw()
private void SetUVCoordinates()
{
var dr = RenderWindow.Instance.DebugRenderer;
var vertices = clothRenderer.Vertices;

for (int i = 0; i<cloth.Vertices.Count; i++)
{
ref var pos = ref cloth.Vertices[i].Data.Position;
vertices[i].Texture = new Vector2(pos.X, pos.Z);
}
}

foreach (var spring in cloth.Springs)
private void UpdateRenderVertices()
{
var vertices = clothRenderer.Vertices;

for (int i = 0; i<cloth.Vertices.Count; i++)
{
dr.PushLine(DebugRenderer.Color.Green, Conversion.FromJitter(spring.Body1.Position),
Conversion.FromJitter(spring.Body2.Position));
vertices[i].Position = Conversion.FromJitter(cloth.Vertices[i].Position);
}

clothRenderer.VerticesChanged();
}

public void Draw()
{
UpdateRenderVertices();
clothRenderer.PushMatrix(Matrix4.Identity, Vector3.UnitY);
}

public void CleanUp()
Expand Down
26 changes: 8 additions & 18 deletions src/JitterDemo/Demos/SoftBody/SoftBodyCloth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Jitter2.Dynamics;
using Jitter2.LinearMath;
using Jitter2.SoftBodies;
using JitterDemo.Renderer;

namespace JitterDemo;

Expand Down Expand Up @@ -32,24 +33,13 @@ public int GetHashCode(Edge obj)
}
}

private struct Triangle
{
public Triangle(ushort u0, ushort u1, ushort u2)
{
IndexA = u0;
IndexB = u1;
IndexC = u2;
}

public readonly ushort IndexA;
public readonly ushort IndexB;
public readonly ushort IndexC;
}

private List<JVector> vertices = null!;
private List<Triangle> triangles = null!;
private List<TriangleVertexIndex> triangles = null!;
private List<Edge> edges = null!;

public List<TriangleVertexIndex> Triangles => triangles;

private List<SpringConstraint> MatchConstraints = new();

public SoftBodyCloth(World world, IEnumerable<JTriangle> triangles) : base(world)
Expand All @@ -75,15 +65,15 @@ ushort AddVertex(in JVector vertex)
return ind;
}

triangles = new List<Triangle>();
triangles = new List<TriangleVertexIndex>();

foreach (var tri in tris)
{
ushort u0 = AddVertex(tri.V0);
ushort u1 = AddVertex(tri.V1);
ushort u2 = AddVertex(tri.V2);

Triangle t = new Triangle(u0, u1, u2);
TriangleVertexIndex t = new TriangleVertexIndex(u0, u1, u2);
triangles.Add(t);

edgs.Add(new Edge(u0, u1));
Expand All @@ -109,13 +99,13 @@ private void Build()
{
var constraint = world.CreateConstraint<SpringConstraint>(Vertices[edge.IndexA], Vertices[edge.IndexB]);
constraint.Initialize(Vertices[edge.IndexA].Position, Vertices[edge.IndexB].Position);
constraint.Softness = 0.1f;
constraint.Softness = 0.2f;
Springs.Add(constraint);
}

foreach (var triangle in triangles)
{
var tri = new SoftBodyTriangle(this, Vertices[triangle.IndexA], Vertices[triangle.IndexB], Vertices[triangle.IndexC]);
var tri = new SoftBodyTriangle(this, Vertices[(int)triangle.T1], Vertices[(int)triangle.T2], Vertices[(int)triangle.T3]);
tri.UpdateWorldBoundingBox();
world.AddShape(tri);
Shapes.Add(tri);
Expand Down
8 changes: 4 additions & 4 deletions src/JitterDemo/Renderer/CSM/CSMInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class CSMInstance
public ArrayBuffer ab = null!;

protected ArrayBuffer worldMatrices = null!;
private int indexLen;
protected int IndexLen;

public TransformColor[] WorldMatrices = { TransformColor.Default };
public int Count { set; get; } = 1;
Expand Down Expand Up @@ -66,7 +66,7 @@ public virtual void LightPass(PhongShader shader)
Texture?.Bind(3);

Vao.Bind();
GLDevice.DrawElementsInstanced(DrawMode.Triangles, indexLen, IndexType.UnsignedInt, 0, Count);
GLDevice.DrawElementsInstanced(DrawMode.Triangles, IndexLen, IndexType.UnsignedInt, 0, Count);
}

public virtual void UpdateWorldMatrices()
Expand All @@ -80,15 +80,15 @@ public virtual void ShadowPass(ShadowShader shader)
if (Count == 0) return;

Vao.Bind();
GLDevice.DrawElementsInstanced(DrawMode.Triangles, indexLen, IndexType.UnsignedInt, 0, Count);
GLDevice.DrawElementsInstanced(DrawMode.Triangles, IndexLen, IndexType.UnsignedInt, 0, Count);
}

public virtual void Load()
{
Vao = new VertexArrayObject();

(var vertices, var indices) = ProvideVertices();
indexLen = indices.Length * 3;
IndexLen = indices.Length * 3;

ab = new ArrayBuffer();
ab.SetData(vertices);
Expand Down
20 changes: 17 additions & 3 deletions src/JitterDemo/Renderer/CSM/CSMShader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ public class Material
public UniformFloat Shininess { get; }
public UniformFloat Alpha { get; }

private UniformFloat NormalMultiply { get; }

public bool FlipNormal
{
set
{
NormalMultiply.Set(value ? -1.0f : 1.0f);
}
}

/// <summary>
/// Magic:
/// Ambient = ColorMixing.X * vertexColor + ColorMixing.Y * shaderColor
Expand All @@ -59,6 +69,7 @@ public Material(ShaderProgram shader)
Shininess = shader.GetUniform<UniformFloat>("material.shininess");
Alpha = shader.GetUniform<UniformFloat>("material.alpha");
ColorMixing = shader.GetUniform<UniformVector3>("material.mixing");
NormalMultiply = shader.GetUniform<UniformFloat>("material.flipnormal");
}

public void SetDefaultMaterial()
Expand All @@ -68,6 +79,7 @@ public void SetDefaultMaterial()
Shininess.Set(128);
Alpha.Set(1.0f);
ColorMixing.Set(1, 0, 0);
NormalMultiply.Set(1);
}
}

Expand Down Expand Up @@ -142,6 +154,7 @@ struct Material {
vec3 diffuse;
float alpha;
vec3 mixing;
float flipnormal;
};
uniform Material material;
Expand Down Expand Up @@ -224,6 +237,7 @@ void main()
{
vec3 lightColor = vec3(1, 1, 1);
vec3 mix = material.mixing;
vec3 fnormal = normal * material.flipnormal;
vec3 ambient = mix.x * vertexColor + mix.y * material.color;
vec3 diffuse = (1.0f - mix.z) * vec3(0.6f, 0.6f, 0.6f) + mix.z * vec3(texture(diffuse, TexCoords));
Expand All @@ -249,20 +263,20 @@ void main()
{
// diffuse
lightDir = normalize(lights[i]);
float diff = max(dot(normal, lightDir), 0.0);
float diff = max(dot(fnormal, lightDir), 0.0);
diffusive += lightColor * lightstrength[i] * diff * diffuse;
}
// specular
lightDir = normalize(lights[0]);
vec3 viewDir = normalize(viewPos - pos);
vec3 halfwayDir = normalize(lightDir + viewDir);
vec3 reflectDir = reflect(-lightDir, normal);
vec3 reflectDir = reflect(-lightDir, fnormal);
float spec = pow(max(dot(viewDir, halfwayDir),0.0), material.shininess);
specular = lightColor * spec * material.specular;
float shadow = ShadowCalculation(normal);
float shadow = ShadowCalculation(fnormal);
vec3 result = (1.0f*ambient + 1.0f*(diffusive + 0.4f*specular) * (1- shadow));
FragColor = vec4(result, material.alpha);
Expand Down
107 changes: 107 additions & 0 deletions src/JitterDemo/Renderer/CSM/Instances/Cloth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System.IO;
using Jitter2.Collision;
using Jitter2.LinearMath;
using JitterDemo.Renderer.OpenGL;
using JitterDemo.Renderer.OpenGL.Native;

namespace JitterDemo.Renderer;

public class Cloth : CSMInstance
{
private Vertex[] vertices;
private TriangleVertexIndex[] indices;

public Cloth()
{
// dummy data
vertices = new Vertex[4];
vertices[0] = new Vertex(new Vector3(-1, 0, -1), Vector3.UnitY, new Vector2(0, 0));
vertices[1] = new Vertex(new Vector3(-1, 0, +1), Vector3.UnitY, new Vector2(0, 1));
vertices[2] = new Vertex(new Vector3(+1, 0, -1), Vector3.UnitY, new Vector2(1, 0));
vertices[3] = new Vertex(new Vector3(+1, 0, +1), Vector3.UnitY, new Vector2(1, 1));

indices = new TriangleVertexIndex[2];
indices[0] = new TriangleVertexIndex(1, 0, 2);
indices[1] = new TriangleVertexIndex(1, 2, 3);
}

public Vertex[] Vertices => vertices;

public void SetIndices(TriangleVertexIndex[] indices)
{
IndexLen = indices.Length * 3;
Vao.ElementArrayBuffer.SetData(indices);

uint largest = 0;
for (int i = 0; i < indices.Length; i++)
{
if (indices[i].T1 > largest) largest = indices[i].T1;
if (indices[i].T2 > largest) largest = indices[i].T2;
if (indices[i].T3 > largest) largest = indices[i].T3;
}

this.vertices = new Vertex[largest + 1];
this.indices = indices;
}

public void VerticesChanged()
{
for (int i = 0; i < vertices.Length; i++)
{
vertices[i].Normal = Vector3.Zero;
}

for (int i = 0; i < indices.Length; i++)
{
ref var v1 = ref vertices[indices[i].T1];
ref var v2 = ref vertices[indices[i].T2];
ref var v3 = ref vertices[indices[i].T3];

var p0 = v1.Position;
var p1 = v2.Position;
var p2 = v3.Position;
var n = Vector3.Cross(p2 - p1, p2 - p0);

v1.Normal += n;
v2.Normal += n;
v3.Normal += n;
}

this.ab.SetData(vertices);
}

public override void Load()
{
string filename = Path.Combine("assets", "texture_10.tga");
Image.LoadImage(filename).FixedData((img, ptr) => { Texture.LoadImage(ptr, img.Width, img.Height); });

Texture.SetWrap(OpenGL.Texture.Wrap.Repeat);
Texture.SetAnisotropicFiltering(OpenGL.Texture.Anisotropy.Filter_8x);

base.Load();
}

public override (Vertex[] vertices, TriangleVertexIndex[] indices) ProvideVertices()
{
return (vertices, indices);
}

public override void ShadowPass(ShadowShader shader)
{
GLDevice.Disable(Capability.CullFace);
base.ShadowPass(shader);
GLDevice.Enable(Capability.CullFace);
}

public override void LightPass(PhongShader shader)
{
shader.MaterialProperties.SetDefaultMaterial();
shader.MaterialProperties.ColorMixing.Set(0.1f,0.0f,0.9f);
shader.MaterialProperties.FlipNormal = true;
GLDevice.SetCullFaceMode(CullMode.Back);
base.LightPass(shader);
shader.MaterialProperties.FlipNormal = false;
GLDevice.SetCullFaceMode(CullMode.Front);
base.LightPass(shader);
}
}
25 changes: 25 additions & 0 deletions src/JitterDemo/assets/texture_10.LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@


Prototype Textures 1.0

Created/distributed by Kenney (www.kenney.nl)
Creation date: 08-04-2020

------------------------------

License: (Creative Commons Zero, CC0)
http://creativecommons.org/publicdomain/zero/1.0/

This content is free to use in personal, educational and commercial projects.


Support us by crediting Kenney or www.kenney.nl (this is not mandatory)

------------------------------

Donate: http://support.kenney.nl
Request: http://request.kenney.nl
Patreon: http://patreon.com/kenney/

Follow on Twitter for updates:
http://twitter.com/KenneyNL
Binary file added src/JitterDemo/assets/texture_10.tga
Binary file not shown.

0 comments on commit 9992a95

Please sign in to comment.