diff --git a/src/dlangui/graphics/scene/camera.d b/src/dlangui/graphics/scene/camera.d index 90944b76..b6a16751 100644 --- a/src/dlangui/graphics/scene/camera.d +++ b/src/dlangui/graphics/scene/camera.d @@ -9,25 +9,61 @@ import gl3n.math; class Camera : Node3d { protected mat4 _projectionMatrix; + protected mat4 _viewProjectionMatrix; + protected bool _dirtyViewProjection; + + protected bool _enabled; + + this() { + _enabled = true; + setPerspective(4.0f, 3.0f, 45.0f, 0.1f, 100.0f); + } + + /// returns true if camera is active (enabled) + @property bool enabled() { return _enabled; } + + /// activates / deactivates camera + @property void enabled(bool v) { + if (scene) + scene.activeCamera = null; + _enabled = v; + } /// get projection matrix - @property ref mat4 projectionMatrix() { + @property ref const(mat4) projectionMatrix() { return _projectionMatrix; } /// set custom projection matrix @property void projectionMatrix(mat4 v) { _projectionMatrix = v; + _dirtyViewProjection = true; + } + + /// get projection*view matrix + @property ref const(mat4) viewProjectionMatrix() { + if (_dirtyTransform || _dirtyViewProjection) { + _viewProjectionMatrix = _projectionMatrix * matrix; + _dirtyViewProjection = false; + } + return _viewProjectionMatrix; } /// set orthographic projection void setOrtho(float left, float right, float bottom, float top, float near, float far) { _projectionMatrix = mat4.orthographic(left, right, bottom, top, near, far); + _dirtyViewProjection = true; } /// set perspective projection void setPerspective(float width, float height, float fov, float near, float far) { _projectionMatrix = mat4.perspective(width, height, fov, near, far); + _dirtyViewProjection = true; } + ~this() { + // disconnect active camera + if (scene && scene.activeCamera is this) + scene.activeCamera = null; + } } diff --git a/src/dlangui/graphics/scene/node.d b/src/dlangui/graphics/scene/node.d index 71deed80..59b9823a 100644 --- a/src/dlangui/graphics/scene/node.d +++ b/src/dlangui/graphics/scene/node.d @@ -5,29 +5,50 @@ import gl3n.math; import dlangui.graphics.scene.transform; import dlangui.core.collections; +import dlangui.graphics.scene.scene3d; /// 3D scene node class Node3d : Transform { protected Node3d _parent; + protected Scene3d _scene; protected string _id; protected mat4 _worldMatrix; protected ObjectList!Node3d _children; + this() { + super(); + } + + /// returns scene for node + @property Scene3d scene() { + if (_scene) + return _scene; + if (_parent) + return _parent.scene; + return cast(Scene3d) this; + } + + @property void scene(Scene3d v) { _scene = v; } + /// returns child node count @property int childCount() { return _children.count; } + /// returns child node by index Node3d child(int index) { return _children[index]; } + /// add child node void addChild(Node3d node) { _children.add(node); node.parent = this; + node.scene = scene; } + /// removes and destroys child node by index void removeChild(int index) { destroy(_children.remove(index)); @@ -37,6 +58,7 @@ class Node3d : Transform { @property Node3d parent() { return _parent; } + @property Node3d parent(Node3d v) { _parent = v; return this; diff --git a/src/dlangui/graphics/scene/scene3d.d b/src/dlangui/graphics/scene/scene3d.d index ce45022d..d64117d1 100644 --- a/src/dlangui/graphics/scene/scene3d.d +++ b/src/dlangui/graphics/scene/scene3d.d @@ -1,6 +1,7 @@ module dlangui.graphics.scene.scene3d; import dlangui.graphics.scene.node; +import dlangui.graphics.scene.camera; import gl3n.linalg; import gl3n.math; @@ -9,9 +10,35 @@ import gl3n.math; class Scene3d : Node3d { protected vec3 _ambientColor; + protected Camera _activeCamera; + + /// ambient light color @property vec3 ambientColor() { return _ambientColor; } + /// set ambient light color @property void ambientColor(const ref vec3 v) { _ambientColor = v; } + /// active camera + @property Camera activeCamera() { + if (_activeCamera) + return _activeCamera; + // TODO: find camera in child nodes + return null; + } + /// set or clear current active camera + @property void activeCamera(Camera cam) { + _activeCamera = cam; + } + + /// returns scene for node + override @property Scene3d scene() { + return this; + } + + override @property void scene(Scene3d v) { + //ignore + } + } + diff --git a/src/dlangui/graphics/scene/transform.d b/src/dlangui/graphics/scene/transform.d index 742b42c0..59e233f3 100644 --- a/src/dlangui/graphics/scene/transform.d +++ b/src/dlangui/graphics/scene/transform.d @@ -12,6 +12,10 @@ class Transform { protected mat4 _matrix; + this() { + setIdentity(); + } + /// get scale vector public @property ref const(vec3) scaling() const { return _scale; } /// get scale X