Model loading fully working and tools for workbench

This commit is contained in:
Arnau Alier Torres 2025-04-27 01:36:11 +02:00
parent 423e41efda
commit b1215c2563
22 changed files with 11264 additions and 72 deletions

View File

@ -17,6 +17,9 @@ namespace Deer {
MeshRenderComponent(const MeshRenderComponent&) = default;
MeshRenderComponent(uint32_t _mesh, uint32_t _shader) : shaderAssetID(_shader), meshAssetID(_mesh) { }
Ref<Shader> shader;
Ref<VertexArray> vertexArray;
uint32_t shaderAssetID = 0;
uint32_t meshAssetID = 0;
};

View File

@ -2,30 +2,17 @@
#include <cstdint>
#include "Deer/Path.h"
#include "DeerRender/Render/VertexArray.h"
namespace Deer {
// This struct represents the data save in a position vertex, this is
// defined by: integerPart.decimalPart, where each decimal part represents
// 1 / 256. And the integer part is substracted 128
// Example: integerPart = 129; decimalPart = 32;
// Result = (129-128).(32/256) = 1.125f
struct PositionAxis {
uint8_t integerPart = 0;
uint8_t decimalPart = 0;
PositionAxis() = default;
PositionAxis(uint8_t ip, uint8_t dp)
: integerPart(ip), decimalPart(dp) {}
};
// The real position is the axis divided by 256, the model precition is 1 / 256.0f
struct VertexPosition {
PositionAxis x;
PositionAxis y;
PositionAxis z;
int16_t x;
int16_t y;
int16_t z;
VertexPosition() = default;
VertexPosition(PositionAxis _x, PositionAxis _y, PositionAxis _z)
VertexPosition(int16_t _x, int16_t _y, int16_t _z)
: x(_x), y(_y), z(_z) {}
};
@ -69,6 +56,10 @@ namespace Deer {
}
};
namespace Mesh {
Ref<VertexArray> loadModelToGPU(const MeshData&);
}
namespace DataStore {
void saveModel(const MeshData&, const Path& name);
void loadModel(MeshData&, const Path& name);

View File

@ -6,7 +6,6 @@
namespace Deer {
class VertexArray;
using Mesh = VertexArray;
class VertexArray {
public:

View File

@ -2,17 +2,18 @@
namespace Deer {
void DataStore::createExampleMeshData() {
/*
MeshData meshData;
meshData.vertexCount = 3;
// Triangle
meshData.vertexPositionsData = new VertexPosition[3]{
VertexPosition(PositionAxis(0 + 128, 0), PositionAxis(0 + 128, 0),
PositionAxis(0 + 128, 0)),
VertexPosition(PositionAxis(0 + 128, 64), PositionAxis(0 + 128, 0),
PositionAxis(1 + 128, 0)),
VertexPosition(PositionAxis(1 + 128, 0), PositionAxis(0 + 128, 0),
PositionAxis(0 + 128, 0))};
VertexPosition(PositionAxis(0 * 128, 0), PositionAxis(0 + 128, 0),
PositionAxis(0 * 128, 0)),
VertexPosition(PositionAxis(0 * 128, 64), PositionAxis(0 + 128, 0),
PositionAxis(1 * 128, 0)),
VertexPosition(PositionAxis(1 * 128, 0), PositionAxis(0 + 128, 0),
PositionAxis(0 * 128, 0))};
meshData.vertexNormalData =
new VertexNormal[3]{VertexNormal(0, 64, 0), VertexNormal(0, 64, 0),
VertexNormal(0, 64, 0)};
@ -21,6 +22,6 @@ namespace Deer {
meshData.indexData = new uint16_t[3]{0, 1, 2};
DataStore::saveModel(meshData, "exampleTriangle");
DataStore::saveBinModel(meshData, "exampleTriangle");
DataStore::saveBinModel(meshData, "exampleTriangle");*/
}
} // namespace Deer

View File

@ -0,0 +1,34 @@
#include "DeerRender/Mesh.h"
#include "Deer/Log.h"
#include "DeerRender/Render/Buffer.h"
namespace Deer{
Ref<VertexArray> Mesh::loadModelToGPU(const MeshData& data) {
Ref<VertexArray> vertexArray = VertexArray::create();
vertexArray->bind();
Ref<VertexBuffer> vertexPositionBuffer = VertexBuffer::create(data.vertexPositionsData, data.vertexCount * sizeof(VertexPosition));
BufferLayout positionLayout({
{"v_position", DataType::Short3, ShaderDataType::FloatingPoint}
}, sizeof(VertexPosition)); //
BufferLayout normalLayout({
{"v_normal", DataType::Byte3, ShaderDataType::NormalizedFloatingPoint}
}, sizeof(VertexNormal));
vertexPositionBuffer->bind();
vertexPositionBuffer->setLayout(positionLayout);
vertexArray->addVertexBuffer(vertexPositionBuffer);
Ref<VertexBuffer> vertexNormalBuffer = VertexBuffer::create(data.vertexNormalData, data.vertexCount * sizeof(VertexNormal));
vertexNormalBuffer->bind();
vertexNormalBuffer->setLayout(normalLayout);
vertexArray->addVertexBuffer(vertexNormalBuffer);
Ref<IndexBuffer> indexBuffer = IndexBuffer::create(data.indexData, data.indexCount * sizeof(uint16_t), IndexDataType::Unsigned_Short);
indexBuffer->bind();
vertexArray->setIndexBuffer(indexBuffer);
return vertexArray;
}
}

View File

@ -5,12 +5,6 @@
#include "cereal/cereal.hpp"
namespace Deer {
template <class Archive>
void serialize(Archive& archive, PositionAxis& positionAxis) {
archive(cereal::make_nvp("int", positionAxis.integerPart));
archive(cereal::make_nvp("dec", positionAxis.decimalPart));
}
template <class Archive>
void serialize(Archive& archive, VertexPosition& vertexPosition) {
archive(cereal::make_nvp("x", vertexPosition.x));

View File

@ -24,11 +24,11 @@ namespace Deer {
auto view = m_registry.view<MeshRenderComponent, TagComponent>();
for (auto entityId : view) {
auto& meshRender = view.get<MeshRenderComponent>(entityId);
if (meshRender.shaderAssetID == 0)
continue;
//if (meshRender.shaderAssetID == 0)
// continue;
if (meshRender.meshAssetID == 0)
continue;
//if (meshRender.meshAssetID == 0)
// continue;
auto& tag = view.get<TagComponent>(entityId);
Entity& entity = getEntity(tag.entityUID);
@ -46,16 +46,17 @@ namespace Deer {
}
glm::mat4 matrix = entity.getWorldMatrix();
Asset<Shader>& shaderAsset = AssetManager::getAsset<Shader>(meshRender.shaderAssetID);
shaderAsset.value->bind();
shaderAsset.value->uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
shaderAsset.value->uploadUniformMat4("u_worldMatrix", matrix);
shaderAsset.value->uploadUniformInt("u_objectID", tag.entityUID);
//Asset<Shader>& shaderAsset = AssetManager::getAsset<Shader>(meshRender.shaderAssetID);
meshRender.shader->bind();
meshRender.shader->uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
meshRender.shader->uploadUniformMat4("u_worldMatrix", matrix);
meshRender.shader->uploadUniformInt("u_objectID", tag.entityUID);
Asset<Mesh>& meshAsset = AssetManager::getAsset<Mesh>(meshRender.meshAssetID);
meshAsset.value->bind();
//Asset<VertexArray> meshAsset = AssetManager::getAsset<VertexArray>(meshRender.meshAssetID);
meshRender.vertexArray->bind();
Render::submit(meshAsset.value);
Render::submit(meshRender.vertexArray);
}
}

View File

@ -22,7 +22,7 @@ namespace Deer{
std::string shaderLocation;
archive(cereal::make_nvp("shader", shaderLocation));
meshRender.meshAssetID = AssetManager::loadAsset<Mesh>(std::filesystem::path(meshLocation));
meshRender.meshAssetID = AssetManager::loadAsset<VertexArray>(std::filesystem::path(meshLocation));
meshRender.shaderAssetID = AssetManager::loadAsset<Shader>(std::filesystem::path(shaderLocation));
}
}

View File

@ -56,7 +56,17 @@ namespace Deer {
auto m_gamePannel = Ref<GamePannel>(new GamePannel());
pannels.push_back(m_gamePannel);
DataStore::createExampleMeshData();
Environment& env = Project::m_scene.getMainEnviroment();
Entity& exampleObject = env.createEntity("Example");
MeshRenderComponent& renderComponent = exampleObject.addComponent<MeshRenderComponent>();
MeshData meshData;
DataStore::loadModel(meshData, "example");
renderComponent.shader = Shader::create(DataStore::rootPath / DEER_SHADER_PATH / "shader.glsl");
renderComponent.vertexArray = Mesh::loadModelToGPU(meshData);
return 0;
}

View File

@ -124,7 +124,7 @@ namespace Deer {
std::string receivedData =
std::string((const char*)payload->Data);
mesh.meshAssetID =
AssetManager::loadAsset<Mesh>(receivedData);
AssetManager::loadAsset<VertexArray>(receivedData);
}
ImGui::EndDragDropTarget();
}

View File

@ -5,6 +5,7 @@
#include "Deer/Enviroment.h"
#include "Deer/Scene.h"
#include "DeerRender/Events/KeyEvent.h"
#include "Deer/Log.h"
#include "DeerRender/Events/MouseEvent.h"
#include "DeerRender/GizmoRenderer.h"
#include "DeerRender/Input.h"
@ -38,6 +39,9 @@ namespace Deer {
enum class TransformMode { Translate = 0, Rotate = 1, Scale = 2 };
TransformMode m_transformMode = TransformMode::Translate;
float pitch = 0.0f; // global for the camera
float yaw = 0.0f; // global for the camera
void processMovment();
bool viewport_onClickEvent(MouseButtonPressedEvent mouseEvent);
@ -132,15 +136,20 @@ namespace Deer {
void processMovment() {
if (!viewport_isActive) return;
if (!Input::isKeyPressed(DEER_KEY_LEFT_CONTROL)) {
float vel = 1.5f;
if (Input::isKeyPressed(DEER_KEY_LEFT_SHIFT)) vel = 8;
if (Input::isKeyPressed(DEER_KEY_LEFT_ALT)) vel = 1.0f;
if (!Input::isKeyPressed(DEER_KEY_LEFT_SHIFT)) {
float vel = 0.6f;
static float w_vel = 1;
//if (Input::isKeyPressed(DEER_KEY_LEFT_SHIFT)) vel = 8;
if (Input::isKeyPressed(DEER_KEY_LEFT_ALT)) vel = 0.1f;
if (Input::isKeyPressed(DEER_KEY_W))
if (Input::isKeyPressed(DEER_KEY_W)){
viewport_sceneCamera.transform.position +=
viewport_sceneCamera.transform.rotation *
glm::vec3(0, 0, 1) * 0.02f * vel;
glm::vec3(0, 0, 1) * 0.02f * vel * w_vel;
w_vel += 0.025f;
} else {
w_vel = 1;
}
if (Input::isKeyPressed(DEER_KEY_S))
viewport_sceneCamera.transform.position +=
@ -159,26 +168,43 @@ namespace Deer {
if (Input::isKeyPressed(DEER_KEY_SPACE))
viewport_sceneCamera.transform.position.y += 0.02f;
if (Input::isKeyPressed(DEER_KEY_LEFT_CONTROL))
viewport_sceneCamera.transform.position.y -= 0.02f;
}
if (Input::isMouseButtonPressed(DEER_MOUSE_BUTTON_2)) {
float posX, posY;
Input::getMousePos(posX, posY);
glm::vec2 newMousePos = glm::vec2(posX, posY);
static bool lastShift = false;
if (m_lastMousePressedButton1) {
glm::vec2 mouseDiff = newMousePos - m_lastMousePos;
glm::quat pitchQuat = glm::angleAxis(
mouseDiff.y * m_sensitivity, glm::vec3(1, 0, 0));
glm::quat yawQuat = glm::angleAxis(mouseDiff.x * m_sensitivity,
glm::vec3(0, 1, 0));
if (lastShift) {
glm::vec4 movePosition = glm::vec4(-mouseDiff.x * 0.007f, mouseDiff.y * 0.007f, 0, 1);
movePosition = viewport_sceneCamera.transform.getMatrix() * movePosition;
movePosition.x -= viewport_sceneCamera.transform.position.x;
movePosition.y -= viewport_sceneCamera.transform.position.y;
movePosition.z -= viewport_sceneCamera.transform.position.z;
viewport_sceneCamera.transform.rotation =
yawQuat * viewport_sceneCamera.transform.rotation *
pitchQuat;
viewport_sceneCamera.transform.position += movePosition;
} else {
glm::quat pitchQuat = glm::angleAxis(
mouseDiff.y * m_sensitivity, glm::vec3(1, 0, 0));
glm::quat yawQuat = glm::angleAxis(mouseDiff.x * m_sensitivity,
glm::vec3(0, 1, 0));
viewport_sceneCamera.transform.rotation =
yawQuat * viewport_sceneCamera.transform.rotation *
pitchQuat;
}
} else {
lastShift = Input::isKeyPressed(DEER_KEY_LEFT_SHIFT);
}
m_lastMousePos = newMousePos;
m_lastMousePressedButton1 = true;
} else
@ -222,6 +248,10 @@ namespace Deer {
glm::decompose(relativeMatrix, t.scale, t.rotation, t.position,
skew, perspective);
t.position.x = glm::round(t.position.x * 16) / 16;
t.position.y = glm::round(t.position.y * 16) / 16;
t.position.z = glm::round(t.position.z * 16) / 16;
return true;
}
}

View File

@ -0,0 +1,244 @@
let exporterAction;
function exportToDeerEngine() {
// Build your JSON structure and trigger download
var json = {
mesh: {
hasNormalData: true,
vertexPositions: [],
vertexNormals: [],
indices: [],
},
};
function addVertex(vector) {
json.mesh.vertexPositions.push({
x: Math.round((vector[0] / 16) * 256),
y: Math.round((vector[1] / 16) * 256),
z: Math.round((vector[2] / 16) * 256),
});
return json.mesh.vertexPositions.length - 1;
}
function addIndex(indexID) {
json.mesh.indices.push(indexID);
}
function addNormal(normal) {
json.mesh.vertexNormals.push({
x: Math.round(normal[0] * 64),
y: Math.round(normal[1] * 64),
z: Math.round(normal[2] * 64),
});
}
Mesh.all.forEach((mesh) => {
function getWorldPosition(v) {
const mat = mesh.mesh.matrixWorld; // mat4 (THREE.Matrix4)
const vec = new THREE.Vector3(v[0], v[1], v[2]);
vec.applyMatrix4(mat);
// Convert to your engines left-handed space: flip Y and Z
return [vec.x, vec.y, -vec.z];
}
for (const fkey in mesh.faces) {
const face = mesh.faces[fkey];
var verticesIDs = [];
for (const vKey of face.vertices) {
const position = getWorldPosition(mesh.vertices[vKey]);
verticesIDs.push(addVertex(position));
}
// DEER ENGINE IS CLOCK FACE
//for (var i = 0; i < verticesIDs.length; i++) {
// addIndex(verticesIDs[i]);
//}
if (verticesIDs.length == 3) {
addIndex(verticesIDs[0]);
addIndex(verticesIDs[2]);
addIndex(verticesIDs[1]);
} else if (verticesIDs.length == 4) {
addIndex(verticesIDs[0]);
addIndex(verticesIDs[2]);
addIndex(verticesIDs[1]);
addIndex(verticesIDs[1]);
addIndex(verticesIDs[2]);
addIndex(verticesIDs[3]);
}
// Normal calulation
var origin = getWorldPosition(mesh.vertices[face.vertices[0]]);
var dirBRef = getWorldPosition(mesh.vertices[face.vertices[1]]);
var dirARef = getWorldPosition(mesh.vertices[face.vertices[2]]);
var dirA = [0, 0, 0];
var dirB = [0, 0, 0];
for (var i = 0; i < 3; i++) {
dirB[i] = dirARef[i] - origin[i];
dirA[i] = dirBRef[i] - origin[i];
}
var normalDir = [0, 0, 0];
normalDir[0] = dirB[1] * dirA[2] - dirB[2] * dirA[1];
normalDir[1] = dirB[2] * dirA[0] - dirB[0] * dirA[2];
normalDir[2] = dirB[0] * dirA[1] - dirB[1] * dirA[0];
var normalMagnitude = Math.sqrt(
normalDir[0] * normalDir[0] +
normalDir[1] * normalDir[1] +
normalDir[2] * normalDir[2]
);
for (var i = 0; i < 3; i++) {
normalDir[i] = normalDir[i] / normalMagnitude;
}
for (var i = 0; i < verticesIDs.length; i++) {
addNormal(normalDir);
}
}
});
const face_corners = {
north: [5, 4, 7, 6],
east: [1, 5, 3, 7],
south: [0, 1, 2, 3],
west: [4, 0, 6, 2],
up: [2, 3, 6, 7],
down: [4, 5, 0, 1],
};
Cube.all.forEach((cube) => {
// Cubes are simpler: they have 6 faces and 8 vertices
const mat = cube.mesh.matrixWorld;
function getWorldPosition(v) {
const vec = new THREE.Vector3(v[0], v[1], v[2]);
vec.applyMatrix4(mat);
return [vec.x, vec.y, -vec.z]; // Flip Z to match left-handed
}
// cube.from and cube.to define the min and max corners
const from = cube.from; // [x, y, z]
const to = cube.to; // [x, y, z]
const corners = [
[from[0], from[1], from[2]],
[to[0], from[1], from[2]],
[from[0], to[1], from[2]],
[to[0], to[1], from[2]],
[from[0], from[1], to[2]],
[to[0], from[1], to[2]],
[from[0], to[1], to[2]],
[to[0], to[1], to[2]],
];
for (var i = 0; i < corners.length; i++) {
corners[i][0] -= cube.origin[0];
corners[i][1] -= cube.origin[1];
corners[i][2] -= cube.origin[2];
}
for (const fkey in cube.faces) {
const face = cube.faces[fkey];
const verticesIDs = [];
const corner_indices = face_corners[fkey]; // get the right 4 corner indices
if (!corner_indices) continue; // just in case
const face_vertices = corner_indices.map((i) => corners[i]);
for (const v of face_vertices) {
const position = getWorldPosition(v);
verticesIDs.push(addVertex(position));
}
if (verticesIDs.length == 4) {
addIndex(verticesIDs[0]);
addIndex(verticesIDs[1]);
addIndex(verticesIDs[2]);
addIndex(verticesIDs[1]);
addIndex(verticesIDs[3]);
addIndex(verticesIDs[2]);
}
// Calculate normal like in your mesh code
var origin = getWorldPosition(face_vertices[0]);
var dirBRef = getWorldPosition(face_vertices[1]);
var dirARef = getWorldPosition(face_vertices[2]);
var dirA = [0, 0, 0];
var dirB = [0, 0, 0];
for (var i = 0; i < 3; i++) {
dirA[i] = dirARef[i] - origin[i];
dirB[i] = dirBRef[i] - origin[i];
}
var normalDir = [0, 0, 0];
normalDir[0] = dirB[1] * dirA[2] - dirB[2] * dirA[1];
normalDir[1] = dirB[2] * dirA[0] - dirB[0] * dirA[2];
normalDir[2] = dirB[0] * dirA[1] - dirB[1] * dirA[0];
var normalMagnitude = Math.sqrt(
normalDir[0] * normalDir[0] +
normalDir[1] * normalDir[1] +
normalDir[2] * normalDir[2]
);
for (var i = 0; i < 3; i++) {
normalDir[i] = normalDir[i] / normalMagnitude;
}
for (var i = 0; i < verticesIDs.length; i++) {
addNormal(normalDir);
}
}
});
Blockbench.export({
type: "DeerMesh",
extensions: ["dmesh"],
name: Project.name,
content: autoStringify(json),
});
/*
Blockbench.showQuickMessage(
PathModule.join(folder, Project.name + ".dmesh"),
10000
);
Blockbench.writeFile(PathModule.join(folder, Project.name + ".dmesh"), {
content: autoStringify(json),
});*/
}
Plugin.register("deer_engine_exporter", {
title: "Deer Engine",
author: "Chewico",
description: "Utilities to work with Deer Engine",
icon: "export", // any valid Blockbench icon :contentReference[oaicite:5]{index=5}
version: "1.0.0",
variant: "both", // supports desktop & web
onload() {
// (1) Create the export action
exporterAction = new Action("export_deer_engine_json", {
name: "Export to Deer Engine Mesh Format",
icon: "export",
click() {
//visibleOverridesDialog.show();
exportToDeerEngine();
},
});
// (2) Add it under File → Export (top position)
MenuBar.addAction(exporterAction, "file.export.0"); // “export” submenu, index 0 :contentReference[oaicite:6]{index=6}
},
onunload() {
// Remove the action when plugin unloads
exporterAction.delete();
},
});

File diff suppressed because one or more lines are too long

3011
roe/3dMesh.dmesh Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[Window][DockSpace Demo]
Pos=0,0
Size=1280,720
Size=2560,1371
Collapsed=0
[Window][Debug##Default]
@ -9,32 +9,32 @@ Size=400,400
Collapsed=0
[Window][Properties]
Pos=911,24
Size=369,214
Pos=2191,24
Size=369,531
Collapsed=0
DockId=0x00000009,0
[Window][Game Window]
Pos=368,24
Size=541,442
Size=1821,1093
Collapsed=0
DockId=0x00000006,1
[Window][Tree Pannel]
Pos=0,24
Size=366,442
Size=366,1093
Collapsed=0
DockId=0x00000005,0
[Window][Terrain Editor]
Pos=911,240
Size=369,226
Pos=2191,557
Size=369,560
Collapsed=0
DockId=0x0000000A,0
[Window][Viewport]
Pos=368,24
Size=541,442
Size=1821,1093
Collapsed=0
DockId=0x00000006,0
@ -45,13 +45,13 @@ Collapsed=0
DockId=0x00000002,0
[Window][Mesh Explorer]
Pos=0,468
Size=1280,252
Pos=0,1119
Size=2560,252
Collapsed=0
DockId=0x00000008,0
[Docking][Data]
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=2560,1347 Split=Y
DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,442 Split=Y
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=909,779 Split=X Selected=0x13926F0B

466
roe/meshes/3dMesh.dmesh Normal file
View File

@ -0,0 +1,466 @@
{
"mesh": {
"hasNormalData": true,
"vertexPositions": [
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
}
],
"vertexNormals": [
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": 64
},
{
"x": 0,
"y": 0,
"z": 64
},
{
"x": 0,
"y": 0,
"z": 64
},
{
"x": 0,
"y": 0,
"z": 64
}
],
"indices": [0, 2, 1, 0, 3, 2, 4, 6, 5, 4, 7, 6, 8, 10, 9, 8, 11, 10, 12, 14, 13, 12, 15, 14, 16, 18, 17, 16, 19, 18, 20, 22, 21, 20, 23, 22]
}
}

5206
roe/meshes/Mesh.dmesh Normal file

File diff suppressed because it is too large Load Diff

1667
roe/meshes/example.dmesh Normal file

File diff suppressed because it is too large Load Diff

466
roe/meshes/mainObject Normal file
View File

@ -0,0 +1,466 @@
{
"mesh": {
"hasNormalData": true,
"vertexPositions": [
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 136,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 136,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 136,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
},
{
"x": {
"int": 120,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 120,
"dec": 0
}
}
],
"vertexNormals": [
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": -64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 64,
"y": 0,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": -64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": -64
},
{
"x": 0,
"y": 0,
"z": 64
},
{
"x": 0,
"y": 0,
"z": 64
},
{
"x": 0,
"y": 0,
"z": 64
},
{
"x": 0,
"y": 0,
"z": 64
}
],
"indices": [0, 2, 1, 0, 3, 2, 4, 6, 5, 4, 7, 6, 8, 10, 9, 8, 11, 10, 12, 14, 13, 12, 15, 14, 16, 18, 17, 16, 19, 18, 20, 22, 21, 20, 23, 22]
}
}

View File

@ -0,0 +1,18 @@
{
"voxelAspect": {
"name": "",
"textureFaces": {
"left": "",
"right": "",
"down": "",
"up": "",
"front": "",
"back": ""
},
"emission": {
"red": 0,
"green": 0,
"blue": 0
}
}
}

View File

@ -0,0 +1,6 @@
{
"voxel": {
"name": "",
"type": "air"
}
}

37
roe/shaders/shader.glsl Normal file
View File

@ -0,0 +1,37 @@
#type vertex
#version 410 core
layout(location = 0) in vec3 v_position;
layout(location = 1) in vec3 v_normal;
out vec3 normal;
uniform mat4 u_viewMatrix;
uniform mat4 u_worldMatrix;
void main()
{
vec3 positon = v_position / 256.0;
gl_Position = u_viewMatrix * u_worldMatrix * vec4(positon,1.0);
normal = v_normal;
}
#type fragment
#version 410 core
layout(location = 0) out vec4 fragColor;
layout(location = 1) out int objectID;
in vec3 normal;
uniform int u_objectID;
void main()
{
float light = clamp(dot(normal, normalize(vec3(1,7,3))), 0.1, 1.0);
fragColor = vec4(light, light, light, 1.0);
//fragColor = vec4(1, 1, 1, 1.0);
objectID = u_objectID;
}