3D Editor treaks

This commit is contained in:
IlyaShurupov 2024-11-05 12:26:48 +03:00
parent 60a15fad8b
commit fdaab48158
27 changed files with 254 additions and 124 deletions

View file

@ -7,6 +7,61 @@ extern "C" {
}
#include <filesystem>
#include <utility>
tp::Vec3F tp::Scene::getVec3(lua_State* state, const char* name) {
int stackSize = lua_gettop(state);
// Access the "pos" field and validate it
lua_getfield(state, -1, name);
if (!lua_istable(state, -1) || lua_rawlen(state, -1) != 3) {
throw IOError(std::string("Invalid vec3 named ") + name);
}
// Read the values from the table
float pos[3];
for (int i = 0; i < 3; i++) {
lua_rawgeti(state, -1, i + 1);
if (lua_isnumber(state, -1)) {
pos[i] = lua_tonumber(state, -1);
} else {
throw IOError("vec3 values must be numbers");
}
lua_pop(state, 1); // pop number
}
lua_pop(state, 1); // pop vec3
ASSERT(stackSize == lua_gettop(state))
return { pos[0], pos[1], pos[2] };
}
tp::Vec2F tp::Scene::getVec2(lua_State* state, const char* name) {
int stackSize = lua_gettop(state);
// Access the "pos" field and validate it
lua_getfield(state, -1, name);
if (!lua_istable(state, -1) || lua_rawlen(state, -1) != 2) {
throw IOError(std::string("Invalid vec2 named ") + name);
}
// Read the values from the table
float pos[2];
for (int i = 0; i < 2; i++) {
lua_rawgeti(state, -1, i + 1);
if (lua_isnumber(state, -1)) {
pos[i] = lua_tonumber(state, -1);
} else {
throw IOError("vec3 values must be numbers");
}
lua_pop(state, 1); // pop number
}
lua_pop(state, 1); // pop vec3
ASSERT(stackSize == lua_gettop(state))
return { pos[0], pos[1] };
}
// Function to read a Lua table representing RenderSettings
int readRenderSettings(lua_State* L, tp::RenderSettings& settings) {
@ -53,23 +108,8 @@ int readRenderSettings(lua_State* L, tp::RenderSettings& settings) {
}
// Function to read a Lua table representing a light
int readLight(lua_State* L, tp::PointLight* light) {
lua_getfield(L, -1, "pos"); // Get the "pos" field from the light table
if (!lua_istable(L, -1)) {
printf("Light is missing the 'pos' table.\n");
return 0; // Error
}
for (int i = 0; i < 3; i++) {
lua_rawgeti(L, -1, i + 1); // Index is 1-based in Lua
if (!lua_isnumber(L, -1)) {
printf("Light 'pos' field is not a number at index %d.\n", i);
lua_pop(L, 2); // Pop both the number and the 'pos' table
return 0; // Error
}
light->pos[i] = lua_tonumber(L, -1);
lua_pop(L, 1); // Pop the number
}
lua_pop(L, 1); // Pop the 'pos' table
int tp::Scene::readLight(lua_State* L, tp::PointLight* light) {
light->pos = getVec3(L, "pos");
lua_getfield(L, -1, "intensity"); // Get the "intensity" field from the light table
if (!lua_isnumber(L, -1)) {
@ -121,66 +161,29 @@ bool tp::Scene::loadLuaFormat(const std::string& scenePath) {
}
// --- camera
// Access Camera table
lua_getglobal(L, "Camera");
if (!lua_istable(L, -1)) {
printf("Camera is not a table.\n");
lua_close(L);
return false;
}
// Verify you are inside the "Camera" table
int cameraTableIndex = lua_gettop(L); // Get the index of the "Camera" table
// Access the "pos" field and validate it
lua_getfield(L, cameraTableIndex, "pos");
if (!lua_istable(L, -1) || lua_rawlen(L, -1) != 3) {
printf("Invalid 'pos' field in Camera table.\n");
lua_close(L);
return false;
}
// Read the values from the table
float pos[3];
for (int i = 0; i < 3; i++) {
lua_rawgeti(L, -1, i + 1);
if (lua_isnumber(L, -1)) {
pos[i] = lua_tonumber(L, -1);
} else {
printf("Invalid 'pos' field value at index %d.\n", i + 1);
{
lua_getglobal(L, "Camera");
if (!lua_istable(L, -1)) {
printf("Camera is not a table.\n");
lua_close(L);
return false;
}
Vec3F camPos = getVec3(L, "pos");
Vec3F camTarget = getVec3(L, "target");
Vec3F camUp = getVec3(L, "up");
Vec2F camSize = getVec2(L, "size");
mRenderSettings.size = camSize;
mCamera.lookAtPoint(camTarget, camPos, camUp);
mCamera.setFOV(3.14 / 4);
mCamera.setFar(100);
mCamera.setRatio((tp::halnf) camSize.y / (tp::halnf) camSize.x);
lua_pop(L, 1);
}
// Access the "size_x" field and validate it
lua_getfield(L, cameraTableIndex, "size_x");
if (!lua_isnumber(L, -1)) {
printf("Invalid or missing 'size_x' field in Camera table.\n");
lua_close(L);
return false;
}
int size_x = lua_tointeger(L, -1);
lua_pop(L, 1); // Pop the 'size_x' value from the stack
// Access the "size_y" field and validate it
lua_getfield(L, cameraTableIndex, "size_y");
if (!lua_isnumber(L, -1)) {
printf("Invalid or missing 'size_y' field in Camera table.\n");
lua_close(L);
return false;
}
int size_y = lua_tointeger(L, -1);
mRenderSettings.size = { (tp::halnf) size_x, (tp::halnf) size_y };
mCamera.lookAtPoint({ 0, 0, 0 }, { pos[0], pos[1], pos[2] }, { 0, 0, 1 });
mCamera.setFOV(3.14 / 4);
mCamera.setFar(100);
mCamera.setRatio((tp::halnf) size_y / (tp::halnf) size_x);
// ---------- LIGHTS
{
lua_getglobal(L, "Lights");

View file

@ -48,4 +48,39 @@ bool tp::Scene::loadOBJFormat(const std::string& objetsPath) {
}
return mObjects.size();
}
const tp::RayCastData& tp::Scene::castRay(const Ray& ray, alnf farVal) {
auto& out = mRayCastData;
out.hit = false;
out.obj = nullptr;
farVal *= farVal;
for (auto obj : mObjects) {
for (auto trig : obj->mCache.TrigCaches) {
if (trig->castRay(ray)) {
auto dist = (TrigCache::getHitPos() - ray.pos).length2();
if (farVal > dist && dist > EPSILON) {
out.trig = &trig.data();
out.hitPos = TrigCache::getHitPos();
out.obj = &obj.data();
out.hit = true;
farVal = dist;
}
}
}
}
return mRayCastData;
}
void tp::Scene::updateCache() {
for (auto obj : mObjects) {
obj->mCache.updateCache();
}
}

View file

@ -2,5 +2,13 @@
#include "Scene.hpp"
bool tp::Scene::load(const std::string& scenePath) {
return loadLuaFormat(scenePath);
try {
auto res = loadLuaFormat(scenePath);
if (!res) throw IOError("Failed loading lua script");
} catch (const IOError& err) {
printf("Failed loading scene : %s\n", err.description.c_str());
return false;
}
return true;
}

View file

@ -6,6 +6,8 @@
#include <string>
struct lua_State;
namespace tp {
struct RenderSettings {
uhalni depth = 2;
@ -42,7 +44,22 @@ namespace tp {
halnf intensity = 1.f;
};
struct RayCastData {
Object* obj = nullptr;
TrigCache* trig = nullptr;
Vec3F hitPos = { 0, 0, 0 };
bool hit = false;
bool inv = false;
};
class Scene {
struct IOError : public std::exception {
explicit IOError(std::string in) :
description(std::move(in)) {}
std::string description;
};
public:
Scene() = default;
@ -51,11 +68,23 @@ namespace tp {
bool loadLuaFormat(const std::string& scenePath);
bool loadOBJFormat(const std::string& objectsPath);
const RayCastData& castRay(const Ray& ray, alnf farVal);
void updateCache();
private:
Vec3F getVec3(lua_State* state, const char* name);
Vec2F getVec2(lua_State* state, const char* name);
int readLight(lua_State* L, tp::PointLight* light);
public:
Buffer<Object> mObjects;
Buffer<PointLight> mLights;
Camera mCamera;
RenderSettings mRenderSettings;
RayCastData mRayCastData;
};
}

View file

@ -0,0 +1,20 @@
# Blender MTL File: 'scene.blend'
# Material Count: 2
newmtl Material
Ns 323.999994
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
newmtl None
Ns 500
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View file

@ -0,0 +1,112 @@
# Blender v3.0.1 OBJ File: 'scene.blend'
# www.blender.org
mtllib meshes.mtl
o Cube
v -1.039076 1.039076 1.792917
v -1.039076 1.039076 -1.285234
v 1.039076 1.039076 1.792917
v 1.039076 1.039076 -1.285234
v -1.039076 -1.039076 1.792917
v -1.039076 -1.039076 -1.285234
v 1.039076 -1.039076 1.792917
v 1.039076 -1.039076 -1.285234
vt 0.625000 0.500000
vt 0.625000 0.750000
vt 0.875000 0.750000
vt 0.875000 0.500000
vt 0.375000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.375000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.375000 0.500000
vn 0.0000 0.0000 -1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 1.0000 0.0000 0.0000
usemtl Material
s off
f 1/1/1 3/2/1 7/3/1 5/4/1
f 4/5/2 8/6/2 7/7/2 3/2/2
f 8/8/3 6/9/3 5/10/3 7/11/3
f 6/12/4 8/13/4 4/5/4 2/14/4
f 6/9/5 2/14/5 1/1/5 5/10/5
o Cube.001
v 0.411013 -0.208216 -1.264212
v 0.411013 -0.208216 -0.612621
v -0.208216 -0.411013 -1.264212
v -0.208216 -0.411013 -0.612621
v 0.208216 0.411013 -1.264212
v 0.208216 0.411013 -0.612621
v -0.411013 0.208216 -1.264212
v -0.411013 0.208216 -0.612621
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn 0.3112 -0.9503 0.0000
vn -0.9503 -0.3112 0.0000
vn -0.3112 0.9503 0.0000
vn 0.9503 0.3112 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl None
s off
f 9/15/6 10/16/6 12/17/6 11/18/6
f 11/18/7 12/17/7 16/19/7 15/20/7
f 15/20/8 16/19/8 14/21/8 13/22/8
f 13/22/9 14/21/9 10/23/9 9/24/9
f 11/25/10 15/20/10 13/22/10 9/26/10
f 16/19/11 12/27/11 10/28/11 14/21/11
o Cube.002
v -0.351718 -0.467100 -0.602050
v -0.351718 -0.467100 0.049542
v -0.800825 0.004996 -0.602050
v -0.800825 0.004996 0.049542
v 0.120377 -0.017993 -0.602050
v 0.120377 -0.017993 0.049542
v -0.328730 0.454103 -0.602050
v -0.328730 0.454103 0.049542
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn -0.7245 -0.6892 0.0000
vn -0.6892 0.7245 0.0000
vn 0.7245 0.6892 0.0000
vn 0.6892 -0.7245 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl None
s off
f 17/29/12 18/30/12 20/31/12 19/32/12
f 19/32/13 20/31/13 24/33/13 23/34/13
f 23/34/14 24/33/14 22/35/14 21/36/14
f 21/36/15 22/35/15 18/37/15 17/38/15
f 19/39/16 23/34/16 21/36/16 17/40/16
f 24/33/17 20/41/17 18/42/17 22/35/17

View file

@ -0,0 +1,26 @@
Meshes = "meshes.obj"
Camera = {
pos = { 0, 5, 0 },
target = { 0, 0, 0 },
up = { 0, 0, 1 },
size = { 600, 800 },
}
Lights = {
{
pos = { -0.5, 3.5, 1 },
intensity = 1
},
{
pos = { 0, 0, 1 },
intensity = 0.5
},
}
RenderSettings = {
depth = 1,
spray = 1,
multisampling = 1,
}