Files
PCK-Studio/PckStudio.Rendering/CubeMesh.cs

137 lines
6.9 KiB
C#

/* Copyright (c) 2024-present miku-666
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1.The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using OpenTK;
using PckStudio.Core;
using PckStudio.Core.Extensions;
namespace PckStudio.Rendering
{
public class CubeMesh : GenericMesh<TextureVertex>
{
private Cube _cube;
public Vector3 Center => _cube.Center;
internal static int[] IndicesData { get; } = [
// Face 1 (Back)
0, 1, 2,
2, 3, 0,
// Face 2 (Front)
4, 5, 6,
6, 7, 4,
// Face 3 (Top)
8, 9, 10,
10, 11, 8,
// Face 4 (Bottom)
12, 13, 14,
14, 15, 12,
// Face 5 (Left)
16, 17, 18,
18, 19, 16,
// Face 6 (Right)
20, 21, 22,
22, 23, 20
];
internal static VertexBufferLayout VertexBufferLayout { get; } = new VertexBufferLayout().Add(ShaderDataType.Float3).Add(ShaderDataType.Float2);
public CubeMesh(Cube cube) : this(nameof(CubeMesh), cube)
{
}
public CubeMesh(string name, Cube cube) : this(name, cube, true)
{
}
private CubeMesh(string name, Cube cube, bool visible)
: base(name, visible, OpenTK.Graphics.OpenGL.PrimitiveType.Triangles, VertexBufferLayout)
{
_cube = cube;
}
public CubeMesh SetCube(Cube cube)
{
_ = cube ?? throw new ArgumentNullException(nameof(cube));
return new CubeMesh(Name, cube, Visible);
}
public override GenericMesh<TextureVertex> SetVisible(bool visible) => new CubeMesh(Name, _cube, visible);
public Cube GetCube() => _cube;
public override Matrix4 GetTransform() => _cube.GetBoundingBox().GetTransform();
public override BoundingBox GetBounds(Matrix4 transform)
{
return _cube.GetBoundingBox(transform);
}
public override IEnumerable<TextureVertex> GetVertices()
{
int mirror = Convert.ToInt32(_cube.MirrorTexture);
Vector2 uv = _cube.Uv;
Vector3 size = _cube.Size;
// Back
yield return new TextureVertex(new Vector3(0f, 1f, 1f), new Vector2(uv.X + size.Z * 2 + size.X + size.X * (1 - mirror), uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(1f, 1f, 1f), new Vector2(uv.X + size.Z * 2 + size.X + size.X * mirror, uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(1f, 0f, 1f), new Vector2(uv.X + size.Z * 2 + size.X + size.X * mirror, uv.Y + size.Z));
yield return new TextureVertex(new Vector3(0f, 0f, 1f), new Vector2(uv.X + size.Z * 2 + size.X + size.X * (1 - mirror), uv.Y + size.Z));
// Front
yield return new TextureVertex(new Vector3(0f, 1f, 0f), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(1f, 1f, 0f), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(1f, 0f, 0f), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z));
yield return new TextureVertex(new Vector3(0f, 0f, 0f), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z));
// Top
yield return new TextureVertex(new Vector3(0f, 0f, 0f), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y + size.Z));
yield return new TextureVertex(new Vector3(0f, 0f, 1f), new Vector2(uv.X + size.Z + size.X * mirror, uv.Y));
yield return new TextureVertex(new Vector3(1f, 0f, 1f), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y));
yield return new TextureVertex(new Vector3(1f, 0f, 0f), new Vector2(uv.X + size.Z + size.X * (1 - mirror), uv.Y + size.Z));
// Bottom
yield return new TextureVertex(new Vector3(1f, 1f, 0f), new Vector2(uv.X + size.Z + size.X + size.X * (1 - mirror), uv.Y + (_cube.FlipZMapping ? size.Z : 0)));
yield return new TextureVertex(new Vector3(1f, 1f, 1f), new Vector2(uv.X + size.Z + size.X + size.X * (1 - mirror), uv.Y + (!_cube.FlipZMapping ? size.Z : 0)));
yield return new TextureVertex(new Vector3(0f, 1f, 1f), new Vector2(uv.X + size.Z + size.X + size.X * mirror, uv.Y + (!_cube.FlipZMapping ? size.Z : 0)));
yield return new TextureVertex(new Vector3(0f, 1f, 0f), new Vector2(uv.X + size.Z + size.X + size.X * mirror, uv.Y + (_cube.FlipZMapping ? size.Z : 0)));
// Left
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 0f : 1f, 0f, 0f), new Vector2(uv.X + size.X + size.Z, uv.Y + size.Z));
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 0f : 1f, 1f, 0f), new Vector2(uv.X + size.X + size.Z, uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 0f : 1f, 1f, 1f), new Vector2(uv.X + size.X + size.Z * 2, uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 0f : 1f, 0f, 1f), new Vector2(uv.X + size.X + size.Z * 2, uv.Y + size.Z));
// Right
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 1f : 0f, 0f, 0f), new Vector2(uv.X + size.Z, uv.Y + size.Z));
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 1f : 0f, 1f, 0f), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 1f : 0f, 1f, 1f), new Vector2(uv.X, uv.Y + size.Z + size.Y));
yield return new TextureVertex(new Vector3(_cube.MirrorTexture ? 1f : 0f, 0f, 1f), new Vector2(uv.X, uv.Y + size.Z));
yield break;
}
public override IEnumerable<int> GetIndices() => IndicesData;
}
}