BoundingBox - Make 'GetVertices' static & add GetTransform

This commit is contained in:
miku-666
2024-10-23 11:30:34 +02:00
parent d523572235
commit 227456f711
7 changed files with 102 additions and 74 deletions

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PckStudio.Rendering;
namespace PckStudio.Extensions
{
internal static class BoundingBoxExtensions
{
public static BoundingBox GetEnclosingBoundingBox(this IEnumerable<BoundingBox> boundingBoxes)
{
return boundingBoxes.DefaultIfEmpty().Aggregate((a, b) => new BoundingBox(OpenTK.Vector3.ComponentMin(a.Start, b.Start), OpenTK.Vector3.ComponentMax(a.End, b.End)));
}
}
}

View File

@@ -136,6 +136,7 @@
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extensions\BoundingBoxExtensions.cs" />
<Compile Include="Extensions\MaterialContainerExtensions.cs" />
<Compile Include="Extensions\PictureBoxExtensions.cs" />
<Compile Include="Extensions\TreeViewExtensions.cs" />

View File

@@ -29,45 +29,56 @@ namespace PckStudio.Rendering
{
}
public ColorVertex[] GetVertices()
public OpenTK.Matrix4 GetTransform()
{
OpenTK.Vector3 s = Start;
OpenTK.Vector3 e = End;
return [
new ColorVertex(new OpenTK.Vector3(s.X, e.Y, e.Z)),
new ColorVertex(new OpenTK.Vector3(e.X, e.Y, e.Z)),
new ColorVertex(new OpenTK.Vector3(e.X, s.Y, e.Z)),
new ColorVertex(new OpenTK.Vector3(s.X, s.Y, e.Z)),
new ColorVertex(new OpenTK.Vector3(s.X, e.Y, s.Z)),
new ColorVertex(new OpenTK.Vector3(e.X, e.Y, s.Z)),
new ColorVertex(new OpenTK.Vector3(e.X, s.Y, s.Z)),
new ColorVertex(new OpenTK.Vector3(s.X, s.Y, s.Z)),
return OpenTK.Matrix4.CreateScale(Volume) * OpenTK.Matrix4.CreateTranslation(Start);
}
private static readonly ColorVertex[] _vertices = [
new ColorVertex(new OpenTK.Vector3(0f, 1f, 1f)),
new ColorVertex(new OpenTK.Vector3(1f, 1f, 1f)),
new ColorVertex(new OpenTK.Vector3(1f, 0f, 1f)),
new ColorVertex(new OpenTK.Vector3(0f, 0f, 1f)),
new ColorVertex(new OpenTK.Vector3(0f, 1f, 0f)),
new ColorVertex(new OpenTK.Vector3(1f, 1f, 0f)),
new ColorVertex(new OpenTK.Vector3(1f, 0f, 0f)),
new ColorVertex(new OpenTK.Vector3(0f, 0f, 0f)),
];
}
public static int[] GetIndecies()
{
return [0, 1,
1, 2,
2, 3,
3, 0,
private static readonly int[] _indecies = [
0, 1,
1, 2,
2, 3,
3, 0,
4, 5,
5, 6,
6, 7,
7, 4,
4, 5,
5, 6,
6, 7,
7, 4,
0, 4,
1, 5,
2, 6,
3, 7
0, 4,
1, 5,
2, 6,
3, 7
];
}
public static BoundingBox GetEnclosingBoundingBox(IEnumerable<BoundingBox> boundingBoxes)
public static ColorVertex[] GetVertices()
{
return boundingBoxes.DefaultIfEmpty().Aggregate((a, b) => new BoundingBox(OpenTK.Vector3.ComponentMin(a.Start, b.Start), OpenTK.Vector3.ComponentMax(a.End, b.End)));
return _vertices;
//OpenTK.Vector3 s = Start; // 0, 0, 0
//OpenTK.Vector3 e = End; // 1, 1, 1
//return [
// new ColorVertex(new OpenTK.Vector3(s.X, e.Y, e.Z)),
// new ColorVertex(new OpenTK.Vector3(e.X, e.Y, e.Z)),
// new ColorVertex(new OpenTK.Vector3(e.X, s.Y, e.Z)),
// new ColorVertex(new OpenTK.Vector3(s.X, s.Y, e.Z)),
// new ColorVertex(new OpenTK.Vector3(s.X, e.Y, s.Z)),
// new ColorVertex(new OpenTK.Vector3(e.X, e.Y, s.Z)),
// new ColorVertex(new OpenTK.Vector3(e.X, s.Y, s.Z)),
// new ColorVertex(new OpenTK.Vector3(s.X, s.Y, s.Z)),
//];
}
public static int[] GetIndecies() => _indecies;
}
}

View File

@@ -178,10 +178,10 @@ namespace PckStudio.Rendering
public override BoundingBox GetBounds(Matrix4 transform)
{
IEnumerable<BoundingBox> boundingBoxes = cubes
return cubes
.Where(c => c.Visible)
.Select(c => c.GetBounds(GetTransform() * transform))
return BoundingBox.GetEnclosingBoundingBox(boundingBoxes);
.GetEnclosingBoundingBox();
}
internal Vector3 GetFaceCenter(int index, Cube.Face face)

View File

@@ -96,11 +96,10 @@ namespace PckStudio.Rendering
{
_rootCollection?.Clear();
IEnumerable<BoundingBox> allBoxes = model.GetParts()
.SelectMany(p => p.GetBoxes().Select(b => new BoundingBox(b.Position + p.Translation, b.Position + p.Translation + b.Size)));
_maxBounds = model.GetParts()
.SelectMany(p => p.GetBoxes().Select(b => new BoundingBox(b.Position + p.Translation, b.Position + p.Translation + b.Size)))
.GetEnclosingBoundingBox();
_maxBounds = BoundingBox.GetEnclosingBoundingBox(allBoxes);
if (!GameModelImporter.ModelMetaData.TryGetValue(model.Name, out JsonModelMetaData modelMetaData))
{
Trace.TraceError($"[{nameof(ModelRenderer)}@{nameof(LoadModel)}] : Couldn't get meta data for model: '{model.Name}'");
@@ -139,10 +138,10 @@ namespace PckStudio.Rendering
if (Context.IsCurrent)
{
ShaderProgram shader = GetShader("CubeShader");
shader.Bind();
shader.SetUniform2("TexSize", model.TextureSize);
}
ShaderProgram shader = GetShader("CubeShader");
shader.Bind();
shader.SetUniform2("TexSize", model.TextureSize);
}
}
public override void ResetCamera(Vector3 offset)

View File

@@ -167,7 +167,8 @@ namespace PckStudio.Rendering
VertexBufferLayout layout = new VertexBufferLayout();
layout.Add(ShaderDataType.Float3);
layout.Add(ShaderDataType.Float4);
vao.AddNewBuffer(layout);
int id = vao.AddNewBuffer(layout);
vao.GetBuffer(id).SetData(BoundingBox.GetVertices());
var ibo = IndexBuffer.Create(BoundingBox.GetIndecies());
_boundingBoxDrawContext = new DrawContext(vao, ibo, PrimitiveType.Lines);
@@ -267,6 +268,7 @@ namespace PckStudio.Rendering
colorShader.Bind();
Matrix4 viewProjection = Camera.GetViewProjection();
colorShader.SetUniformMat4("ViewProjection", ref viewProjection);
transform = boundingBox.GetTransform() * transform;
colorShader.SetUniformMat4("Transform", ref transform);
colorShader.SetUniform4("BlendColor", color);
colorShader.SetUniform1("Intensity", 0.6f);
@@ -276,7 +278,6 @@ namespace PckStudio.Rendering
GL.DepthFunc(DepthFunction.Always);
Renderer.SetLineWidth(2f);
_boundingBoxDrawContext.VertexArray.GetBuffer(0).SetData(boundingBox.GetVertices());
Renderer.Draw(colorShader, _boundingBoxDrawContext);
GL.DepthFunc(DepthFunction.Less);

View File

@@ -505,7 +505,7 @@ namespace PckStudio.Rendering
void AddOutline(BoundingBox boundingBox, ref List<ColorVertex> vertices, ref List<int> indices)
{
int offset = vertices.Count;
vertices.AddRange(boundingBox.GetVertices());
vertices.AddRange(BoundingBox.GetVertices().Select(vert => new ColorVertex(Vector3.TransformPosition(vert.Position, boundingBox.GetTransform()), vert.Color)));
indices.AddRange(BoundingBox.GetIndecies().Select(i => i + offset));
}
@@ -689,7 +689,7 @@ namespace PckStudio.Rendering
private void CalculateSkinBounds()
{
_skinBounds = BoundingBox.GetEnclosingBoundingBox(meshStorage.Values.Select(item => item.GetBounds(Matrix4.Identity)));
_skinBounds = meshStorage.Values.Select(item => item.GetBounds(Matrix4.Identity)).GetEnclosingBoundingBox();
}
private void AddCustomModelPart(SkinBOX skinBox)
@@ -829,7 +829,7 @@ namespace PckStudio.Rendering
GL.DepthMask(true);
GL.DepthFunc(DepthFunction.Less);
}
ShaderProgram lineShader = GetShader("PlainColorShader");
// Render (custom) skin
@@ -846,7 +846,7 @@ namespace PckStudio.Rendering
if (showWireFrame)
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
Matrix4 transform = Matrix4.CreateScale(1f, -1f, -1f);
Matrix4 renderTransform = Matrix4.CreateScale(1f, -1f, -1f);
ShaderProgram cubeShader = GetShader("CubeShader");
cubeShader.Bind();
@@ -863,8 +863,8 @@ namespace PckStudio.Rendering
{
if (ANIM.GetFlag(SkinAnimFlag.DINNERBONE))
{
transform *= Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(-180f));
transform = transform.Pivoted(head.GetFaceCenter(0, Cube.Face.Top), Vector3.UnitY * 12f);
renderTransform *= Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(-180f));
renderTransform = Matrix4.CreateTranslation(head.GetFaceCenter(0, Cube.Face.Top)) * renderTransform.Pivoted(Vector3.UnitY * 12f);
}
if (!ANIM.GetFlag(SkinAnimFlag.STATIC_ARMS))
@@ -893,12 +893,11 @@ namespace PckStudio.Rendering
armLeftMatrix = LeftArmMatrix * armLeftMatrix;
}
RenderBodyPart(cubeShader, Matrix4.Identity, transform, "HEAD", "HEADWEAR");
RenderBodyPart(cubeShader, Matrix4.Identity, transform, "BODY", "JACKET");
RenderBodyPart(cubeShader, armRightMatrix, transform, "ARM0", "SLEEVE0");
RenderBodyPart(cubeShader, armLeftMatrix, transform, "ARM1", "SLEEVE1");
RenderBodyPart(cubeShader, legRightMatrix, transform, "LEG0", "PANTS0");
RenderBodyPart(cubeShader, legLeftMatrix, transform, "LEG1", "PANTS1");
RenderBodyPart(cubeShader, Matrix4.Identity, renderTransform, "HEAD", "HEADWEAR", "BODY", "JACKET");
RenderBodyPart(cubeShader, armRightMatrix, renderTransform, "ARM0", "SLEEVE0");
RenderBodyPart(cubeShader, armLeftMatrix, renderTransform, "ARM1", "SLEEVE1");
RenderBodyPart(cubeShader, legRightMatrix, renderTransform, "LEG0", "PANTS0");
RenderBodyPart(cubeShader, legLeftMatrix, renderTransform, "LEG1", "PANTS1");
if (_capeImage is not null)
{
@@ -914,7 +913,7 @@ namespace PckStudio.Rendering
Matrix4 partMatrix =
Matrix4.CreateRotationY(MathHelper.DegreesToRadians(180f)) *
Matrix4.CreateRotationX(MathHelper.DegreesToRadians(capeRotation));
RenderPart(cubeShader, cape, partMatrix, transform);
RenderPart(cubeShader, cape, partMatrix, renderTransform);
}
// Armor rendering
@@ -923,33 +922,33 @@ namespace PckStudio.Rendering
armorTexture.Bind();
cubeShader.SetUniform2("TexSize", new Vector2(64, 64));
if (!ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED) || ANIM.GetFlag(SkinAnimFlag.FORCE_HEAD_ARMOR))
RenderPart(cubeShader, offsetSpecificMeshStorage["HELMET"], Matrix4.Identity, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["HELMET"], Matrix4.Identity, renderTransform);
if (!ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED) || ANIM.GetFlag(SkinAnimFlag.FORCE_BODY_ARMOR))
RenderPart(cubeShader, offsetSpecificMeshStorage["CHEST"], Matrix4.Identity, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["CHEST"], Matrix4.Identity, renderTransform);
if (!ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED) || ANIM.GetFlag(SkinAnimFlag.FORCE_RIGHT_ARM_ARMOR))
RenderPart(cubeShader, offsetSpecificMeshStorage["SHOULDER0"], armRightMatrix, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["SHOULDER0"], armRightMatrix, renderTransform);
if (!ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED) || ANIM.GetFlag(SkinAnimFlag.FORCE_LEFT_ARM_ARMOR))
RenderPart(cubeShader, offsetSpecificMeshStorage["SHOULDER1"], armLeftMatrix, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["SHOULDER1"], armLeftMatrix, renderTransform);
bool showRightLegArmor = !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED) || ANIM.GetFlag(SkinAnimFlag.FORCE_RIGHT_LEG_ARMOR);
if (showRightLegArmor)
{
RenderPart(cubeShader, offsetSpecificMeshStorage["PANTS0"], legRightMatrix, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["BOOT0"], legRightMatrix, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["PANTS0"], legRightMatrix, renderTransform);
RenderPart(cubeShader, offsetSpecificMeshStorage["BOOT0"], legRightMatrix, renderTransform);
}
bool showLeftLegArmor = !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED) || ANIM.GetFlag(SkinAnimFlag.FORCE_LEFT_LEG_ARMOR);
if (showLeftLegArmor)
{
RenderPart(cubeShader, offsetSpecificMeshStorage["PANTS1"], legLeftMatrix, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["BOOT1"], legLeftMatrix, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["PANTS1"], legLeftMatrix, renderTransform);
RenderPart(cubeShader, offsetSpecificMeshStorage["BOOT1"], legLeftMatrix, renderTransform);
}
if (showRightLegArmor && showLeftLegArmor)
RenderPart(cubeShader, offsetSpecificMeshStorage["WAIST"], Matrix4.Identity, transform);
RenderPart(cubeShader, offsetSpecificMeshStorage["WAIST"], Matrix4.Identity, renderTransform);
}
if (showWireFrame)
@@ -961,7 +960,7 @@ namespace PckStudio.Rendering
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
lineShader.Bind();
lineShader.SetUniformMat4("ViewProjection", ref viewProjection);
lineShader.SetUniformMat4("Transform", ref transform);
lineShader.SetUniformMat4("Transform", ref renderTransform);
lineShader.SetUniform1("Intensity", 1f);
lineShader.SetUniform4("BlendColor", GuideLineColor);
Renderer.SetLineWidth(2.5f);
@@ -972,7 +971,7 @@ namespace PckStudio.Rendering
BoundingBox boundingBox = GetSelectedBoundingArea();
Matrix4 boundingBoxTransform = transform;
Matrix4 boundingBoxRenderTransform = renderTransform;
if (SelectedIndices.Length == 1 && ModelData.IndexInRange(SelectedIndices[0]))
{
@@ -1002,19 +1001,19 @@ namespace PckStudio.Rendering
return Matrix4.Identity;
}
}
boundingBoxTransform = GetGroupTransform(box.Type) * boundingBoxTransform;
boundingBoxRenderTransform = GetGroupTransform(box.Type) * cubeMesh.GetTransform() * renderTransform;
}
}
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.SrcColor);
DrawBoundingBox(boundingBoxTransform, boundingBox, HighlightlingColor);
DrawBoundingBox(boundingBoxRenderTransform, boundingBox, HighlightlingColor);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
// Show skin bounds
if (ShowBoundingBox)
{
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.SrcColor);
DrawBoundingBox(transform, _skinBounds, Color.BurlyWood);
GL.BlendFunc(BlendingFactor.SrcColor, BlendingFactor.SrcAlpha);
DrawBoundingBox(renderTransform, _skinBounds, Color.BurlyWood);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
}
}
@@ -1056,10 +1055,10 @@ namespace PckStudio.Rendering
Cube cube = box.ToCube(inflate);
CubeMeshCollection cubeMesh = meshStorage[box.Type];
yield return cube.GetBoundingBox(cubeMesh.GetTransform());
}
}
yield break;
}
return BoundingBox.GetEnclosingBoundingBox(GetBoundingBoxesFromSelectedIndices(SelectedIndices));
return GetBoundingBoxesFromSelectedIndices(SelectedIndices).GetEnclosingBoundingBox();
}
private void RenderBodyPart(ShaderProgram shader, Matrix4 partsMatrix, Matrix4 globalMatrix, params string[] partNames)