# HG changeset patch # User John Tsiombikas # Date 1397335075 -10800 # Node ID 964f8ea5f095dbd26efdcc38cc92b53b5850efb4 # Parent d94a69933a7105a04e8b2350b58c7033f9c51795 missed quite a lot of things in my last commit apparently diff -r d94a69933a71 -r 964f8ea5f095 GNUmakefile --- a/GNUmakefile Sat Apr 12 23:28:24 2014 +0300 +++ b/GNUmakefile Sat Apr 12 23:37:55 2014 +0300 @@ -1,7 +1,7 @@ baseobj = src/main.o src/logger.o src/screen.o src/scrman.o modelobj = src/modeller.o src/min3d.o src/m3drast.o src/lines.o rendobj = src/renderer.o src/vmath.o -scnobj = src/scene.o src/object.o src/xfnode.o +scnobj = src/scene.o src/object.o src/light.o src/camera.o src/snode.o sysobj = src/dosemu/dosemu.o obj = $(baseobj) $(modelobj) $(rendobj) $(scnobj) $(sysobj) dep = $(obj:.o=.d) diff -r d94a69933a71 -r 964f8ea5f095 Makefile --- a/Makefile Sat Apr 12 23:28:24 2014 +0300 +++ b/Makefile Sat Apr 12 23:37:55 2014 +0300 @@ -1,7 +1,7 @@ baseobj = main.obj logger.obj screen.obj scrman.obj swapbuf.obj modelobj = modeller.obj min3d.obj m3drast.obj lines.obj rendobj = renderer.obj vmath.obj -scnobj = scene.obj object.obj xfnode.obj +scnobj = scene.obj object.obj light.obj camera.obj snode.obj sysobj = gfx.obj vbe.obj dpmi.obj timer.obj mouse.obj keyb.obj obj = $(baseobj) $(modelobj) $(rendobj) $(scnobj) $(sysobj) bin = rayzor.exe diff -r d94a69933a71 -r 964f8ea5f095 doc/sample.rzr --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/sample.rzr Sat Apr 12 23:37:55 2014 +0300 @@ -0,0 +1,61 @@ +# vim:set ts=4 sw=4 sts=4 ai: +scene { + name = "test" + + material { + name = "red" + diffuse = [1, 0, 0] + specular = [0.8, 0.8, 0.8] + shininess = 32.0 + } + + material { + name = "mirror" + diffuse = [0.15 0.15 0.15] + specular = [0.9 0.9 0.9] + shininess = 60 + reflect = 0.9 + } + + object { + name = "sph01" + type = "sphere" + material = "red" + + xform { position = [0, 1, 0] } + } + + object { + name = "box01" + type = "box" + material = "mirror" + + xform { scale = [3, 0.2, 3] } + } + + light { + name = "lt-prim" + type = "point" + color = [1, 0.95, 0.85] + + xform { position = [-10, 10, 10] } + } + + light { + name = "lt-sec" + type = "point" + color = [0.3, 0.4, 0.75] + + xform { position = [20, 10, 6] } + } + + camera { + name = "cam01" + type = "lookat" + fov = 50 + + xform { position = [0, 5, 6] } + + target = [0, 0, 0] + } +} diff -r d94a69933a71 -r 964f8ea5f095 src/camera.cc --- a/src/camera.cc Sat Apr 12 23:28:24 2014 +0300 +++ b/src/camera.cc Sat Apr 12 23:37:55 2014 +0300 @@ -9,12 +9,12 @@ void Camera::set_target(const Vector3 &target) { - this->target->set_position(target); + this->target.set_position(target); } -const Vector3 &Camera::get_target() const +Vector3 Camera::get_target() const { - return target->get_position(); + return target.get_position(); } void Camera::set_fov(float fov) @@ -30,7 +30,7 @@ void Camera::calc_matrix() const { xform.set_identity(); - xform.lookat(pos, target, Vector3(0, 1, 0)); + xform.lookat(pos, target.get_position(), Vector3(0, 1, 0)); xform_valid = true; } @@ -43,7 +43,7 @@ { } -bool Camera::intersect(const Ray &ray, float *dist) +bool Camera::intersect(const Ray &ray, float *dist) const { return false; } diff -r d94a69933a71 -r 964f8ea5f095 src/camera.h --- a/src/camera.h Sat Apr 12 23:28:24 2014 +0300 +++ b/src/camera.h Sat Apr 12 23:37:55 2014 +0300 @@ -2,7 +2,7 @@ #define CAMERA_H_ #include "vmath.h" -#include "xfnode.h" +#include "snode.h" class Camera : public SceneNode { private: @@ -16,7 +16,7 @@ Camera(); void set_target(const Vector3 &target); - const Vector3 &get_target() const; + Vector3 get_target() const; void set_fov(float fov); float get_fov() const; diff -r d94a69933a71 -r 964f8ea5f095 src/light.h --- a/src/light.h Sat Apr 12 23:28:24 2014 +0300 +++ b/src/light.h Sat Apr 12 23:37:55 2014 +0300 @@ -2,7 +2,7 @@ #define LIGHT_H_ #include "vmath.h" -#include "xfnode.h" +#include "snode.h" class Light : public SceneNode { private: diff -r d94a69933a71 -r 964f8ea5f095 src/object.h --- a/src/object.h Sat Apr 12 23:28:24 2014 +0300 +++ b/src/object.h Sat Apr 12 23:37:55 2014 +0300 @@ -2,7 +2,7 @@ #define OBJECT_H_ #include "vmath.h" -#include "xfnode.h" +#include "snode.h" class Object : public SceneNode { protected: diff -r d94a69933a71 -r 964f8ea5f095 src/quat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/quat.h Sat Apr 12 23:37:55 2014 +0300 @@ -0,0 +1,108 @@ +#ifndef QUATERNION_H_ +#define QUATERNION_H_ + +class Quat; + +inline Quat operator *(const Quat &a, const Quat &b); + +class Quat{ +public: + float x, y, z, w; + + Quat() : x(0), y(0), z(0), w(1) {} + Quat(float xx, float yy, float zz, float ww) : x(xx), y(yy), z(zz), w(ww) {} + + void set_identity() + { + x = y = z = 0.0f; + w = 1.0f; + } + + Quat conjugate() const + { + return Quat(-x, -y, -z, w); + } + + float length() const + { + return (float)sqrt(x * x + y * y + z * z + w * w); + } + + float length_sq() const + { + return x * x + y * y + z * z + w * w; + } + + void normalize() + { + float len = length(); + if(len != 0.0) { + x /= len; + y /= len; + z /= len; + w /= len; + } + } + + Quat inverse() const + { + Quat inv = conjugate(); + float len_sq = length_sq(); + if(len_sq != 0.0) { + inv.x /= len_sq; + inv.y /= len_sq; + inv.z /= len_sq; + inv.w /= len_sq; + } + return inv; + } + + void set_rotation(float angle, float axis_x, float axis_y, float axis_z) + { + float half_angle = angle * 0.5; + float sin_half = sin(half_angle); + + w = cos(half_angle); + x = axis_x * sin_half; + y = axis_y * sin_half; + z = axis_z * sin_half; + } + + void rotate(float angle, float x, float y, float z) + { + Quat q; + q.set_rotation(angle, x, y, z); + *this = *this * q; + } + + void rotate(const Quat &q) + { + *this = q * *this * q.conjugate(); + } + + Matrix4x4 get_matrix() const + { + return Matrix4x4( + 1.0 - 2.0 * y*y - 2.0 * z*z, 2.0 * x * y - 2.0 * w * z, 2.0 * z * x + 2.0 * w * y, 0, + 2.0 * x * y + 2.0 * w * z, 1.0 - 2.0 * x*x - 2.0 * z*z, 2.0 * y * z - 2.0 * w * x, 0, + 2.0 * z * x - 2.0 * w * y, 2.0 * y * z + 2.0 * w * x, 1.0 - 2.0 * x*x - 2.0 * y*y, 0, + 0, 0, 0, 1); + } +}; + +inline Quat operator *(const Quat &a, const Quat &b) +{ + float dot = a.x * b.x + a.y * b.y + a.z * b.z; + float cross_x = a.y * b.z - a.z * b.y; + float cross_y = a.z * b.x - a.x * b.z; + float cross_z = a.x * b.y - a.y * b.x; + + float w = a.w * b.w - dot; + float x = a.x * b.w + b.x * a.w + cross_x; + float y = a.y * b.w + b.y * a.w + cross_y; + float z = a.z * b.w + b.z * a.w + cross_z; + + return Quat(x, y, z, w); +} + +#endif // QUATERNION_H_ diff -r d94a69933a71 -r 964f8ea5f095 src/scene.h --- a/src/scene.h Sat Apr 12 23:28:24 2014 +0300 +++ b/src/scene.h Sat Apr 12 23:37:55 2014 +0300 @@ -3,7 +3,7 @@ #include #include -#include "xfnode.h" +#include "snode.h" #include "object.h" #include "light.h" #include "camera.h" diff -r d94a69933a71 -r 964f8ea5f095 src/snode.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/snode.cc Sat Apr 12 23:37:55 2014 +0300 @@ -0,0 +1,193 @@ +#include +#include +#include "snode.h" + + +SceneNode::SceneNode() +{ + parent = 0; + name = 0; + type = NODE_NULL; + scale = Vector3(1, 1, 1); + invalidate(); +} + +SceneNode::~SceneNode() +{ + delete [] name; +} + +void SceneNode::set_name(const char *name) +{ + this->name = new char[strlen(name) + 1]; + strcpy(this->name, name); +} + +const char *SceneNode::get_name() const +{ + return name ? name : ""; +} + +NodeType SceneNode::get_type() const +{ + return type; +} + +SceneNode *SceneNode::get_parent() +{ + return parent; +} + +const SceneNode *SceneNode::get_parent() const +{ + return parent; +} + +void SceneNode::add_child(SceneNode *child) +{ + children.push_back(child); + child->parent = this; + invalidate(); +} + +void SceneNode::remove_child(SceneNode *child) +{ + // TODO + invalidate(); +} + +int SceneNode::get_children_count() const +{ + return (int)children.size(); +} + +SceneNode *SceneNode::get_child(int idx) +{ + if(idx >= 0 && idx < get_children_count()) { + return children[idx]; + } + return 0; +} + +const SceneNode *SceneNode::get_child(int idx) const +{ + if(idx >= 0 && idx < get_children_count()) { + return children[idx]; + } + return 0; +} + + + +void SceneNode::set_position(const Vector3 &pos) +{ + this->pos = pos; + invalidate(); +} + +Vector3 SceneNode::get_node_position() const +{ + return pos; +} + +void SceneNode::set_rotation(const Quat &quat) +{ + rot = quat; + invalidate(); +} + +Quat SceneNode::get_node_rotation() const +{ + return rot; +} + +void SceneNode::set_scaling(const Vector3 &scale) +{ + this->scale = scale; + invalidate(); +} + +Vector3 SceneNode::get_node_scaling() const +{ + return scale; +} + +// these take hierarchy into account +Vector3 SceneNode::get_position() const +{ + return transform(get_matrix(), Vector3(0, 0, 0)); +} + +Quat SceneNode::get_rotation() const +{ + if(parent) { + return parent->get_rotation() * rot; + } + return rot; +} + +Vector3 SceneNode::get_scaling() const +{ + if(parent) { + return parent->get_scaling() * scale; + } + return scale; +} + +void SceneNode::set_pivot(const Vector3 &pivot) +{ + this->pivot = pivot; + invalidate(); +} + +Vector3 SceneNode::get_pivot() const +{ + return pivot; +} + +const Matrix4x4 &SceneNode::get_matrix() const +{ + calc_matrix(); + return xform; +} + +const Matrix4x4 &SceneNode::get_inv_matrix() const +{ + calc_inv_matrix(); + return inv_xform; +} + +void SceneNode::invalidate() const +{ + xform_valid = inv_xform_valid = false; +} + +// TODO: hierarchy +void SceneNode::calc_matrix() const +{ + xform.set_identity(); + xform.translate(pivot.x, pivot.y, pivot.z); + xform = xform * rot.get_matrix(); + xform.translate(pos.x, pos.y, pos.z); + xform.scale(scale.x, scale.y, scale.z); + xform.translate(-pivot.x, -pivot.y, -pivot.z); + + xform_valid = true; +} + +void SceneNode::calc_inv_matrix() const +{ + calc_matrix(); + + inv_xform = xform.inverse(); + inv_xform_valid = true; +} + +void SceneNode::draw() const +{ +} + +bool SceneNode::intersect(const Ray &ray, float *dist) const +{ + return false; +} diff -r d94a69933a71 -r 964f8ea5f095 src/snode.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/snode.h Sat Apr 12 23:37:55 2014 +0300 @@ -0,0 +1,85 @@ +#ifndef SCENE_NODE_H_ +#define SCENE_NODE_H_ + +#include "vector.h" +#include "vmath.h" +#include "quat.h" +#include "vmathmat.h" +#include "vmathray.h" + +enum NodeType { + NODE_NULL, + NODE_OBJECT, + NODE_LIGHT, + NODE_CAMERA +}; + +class SceneNode { +protected: + char *name; + NodeType type; + + Vector3 pos; + Quat rot; + Vector3 scale; + Vector3 pivot; + + mutable Matrix4x4 xform, inv_xform; + mutable bool xform_valid, inv_xform_valid; + + vector children; + SceneNode *parent; + + SceneNode(const SceneNode &node) {} + SceneNode &operator =(const SceneNode &node) { return *this; } + + void invalidate() const; + virtual void calc_matrix() const; + virtual void calc_inv_matrix() const; + +public: + SceneNode(); + virtual ~SceneNode(); + + virtual void set_name(const char *name); + virtual const char *get_name() const; + + virtual NodeType get_type() const; + + virtual SceneNode *get_parent(); + virtual const SceneNode *get_parent() const; + + // children management + virtual void add_child(SceneNode *child); + virtual void remove_child(SceneNode *child); + + virtual int get_children_count() const; + virtual SceneNode *get_child(int idx); + virtual const SceneNode *get_child(int idx) const; + + virtual void set_position(const Vector3 &pos); + virtual Vector3 get_node_position() const; + + virtual void set_rotation(const Quat &quat); + virtual Quat get_node_rotation() const; + + virtual void set_scaling(const Vector3 &scale); + virtual Vector3 get_node_scaling() const; + + // these take hierarchy into account + virtual Vector3 get_position() const; + virtual Quat get_rotation() const; + virtual Vector3 get_scaling() const; + + virtual void set_pivot(const Vector3 &pivot); + virtual Vector3 get_pivot() const; + + virtual const Matrix4x4 &get_matrix() const; + virtual const Matrix4x4 &get_inv_matrix() const; + + virtual void draw() const; + + virtual bool intersect(const Ray &ray, float *dist = 0) const; +}; + +#endif /* SCENE_NODE_H_ */ diff -r d94a69933a71 -r 964f8ea5f095 src/vmathmat.h --- a/src/vmathmat.h Sat Apr 12 23:28:24 2014 +0300 +++ b/src/vmathmat.h Sat Apr 12 23:37:55 2014 +0300 @@ -34,7 +34,7 @@ inline void rotate(float angle, float x, float y, float z); inline void scale(float x, float y, float z); inline void perspective(float vfov, float aspect, float znear, float zfar); - inline void lookat(const Vector3 &pos, const Vector3 &targ, const Vector3 &up); + void lookat(const Vector3 &pos, const Vector3 &targ, const Vector3 &up); float *operator [](int idx) { return m[idx]; } const float *operator [](int idx) const { return m[idx]; } diff -r d94a69933a71 -r 964f8ea5f095 src/vmathray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vmathray.h Sat Apr 12 23:37:55 2014 +0300 @@ -0,0 +1,24 @@ +#ifndef VMATH_RAY_H_ +#define VMATH_RAY_H_ + +#include "vmath.h" +#include "vmathmat.h" + +class Ray { +public: + Vector3 pos, dir; + + Ray() {} + Ray(const Vector3 &p, const Vector3 &d) : pos(p), dir(d) {} +}; + +inline Ray transform(const Matrix4x4 &m, const Ray &r) +{ + Matrix4x4 rmat = m; + rmat[0][3] = rmat[1][3] = rmat[2][3] = rmat[3][0] = rmat[3][1] = rmat[3][2] = 0.0; + rmat[3][3] = 1.0; + + return Ray(transform(m, r.pos), transform(rmat, r.dir)); +} + +#endif // VMATH_RAY_H_