diff --git a/dlangui-msvc.visualdproj b/dlangui-msvc.visualdproj index de7058e1..51f5d7cd 100644 --- a/dlangui-msvc.visualdproj +++ b/dlangui-msvc.visualdproj @@ -787,6 +787,7 @@ + diff --git a/src/dlangui/graphics/scene/camera.d b/src/dlangui/graphics/scene/camera.d index b64dcd5a..9e515089 100644 --- a/src/dlangui/graphics/scene/camera.d +++ b/src/dlangui/graphics/scene/camera.d @@ -18,12 +18,17 @@ class Camera : Node3d { protected bool _enabled; + protected float _far = 100; + this(string ID = null) { super(ID); _enabled = true; setPerspective(4.0f, 3.0f, 45.0f, 0.1f, 100.0f); } + /// returns FAR range of camera + @property float farRange() { return _far; } + /// returns true if camera is active (enabled) @property bool enabled() { return _enabled; } @@ -75,12 +80,14 @@ class Camera : Node3d { /// set orthographic projection void setOrtho(float left, float right, float bottom, float top, float near, float far) { + _far = far; _projectionMatrix.setOrtho(left, right, bottom, top, near, far); _dirtyViewProjection = true; } /// set perspective projection void setPerspective(float width, float height, float fov, float near, float far) { + _far = far; _projectionMatrix.setPerspective(fov, width / height, near, far); _dirtyViewProjection = true; } diff --git a/src/dlangui/graphics/scene/mesh.d b/src/dlangui/graphics/scene/mesh.d index acafd74c..13ae8af8 100644 --- a/src/dlangui/graphics/scene/mesh.d +++ b/src/dlangui/graphics/scene/mesh.d @@ -491,7 +491,7 @@ class Mesh : RefCountedObject { } - private void addQuad(ref vec3 v0, ref vec3 v1, ref vec3 v2, ref vec3 v3, ref vec4 color) { + void addQuad(ref vec3 v0, ref vec3 v1, ref vec3 v2, ref vec3 v3, ref vec4 color) { ushort startVertex = cast(ushort)vertexCount; if (hasElement(VertexElementType.NORMAL)) { vec3 normal = vec3.crossProduct((v1 - v0), (v3 - v0)).normalized; diff --git a/src/dlangui/graphics/scene/node.d b/src/dlangui/graphics/scene/node.d index e9e1ea16..0688269e 100644 --- a/src/dlangui/graphics/scene/node.d +++ b/src/dlangui/graphics/scene/node.d @@ -92,6 +92,27 @@ class Node3d : Transform { destroy(_children.remove(index)); } + /// remove and destroy child node (returns true if child is found and removed) + bool removeChild(Node3d child) { + int index = findChild(child); + if (index >= 0) { + removeChild(index); + return true; + } + return false; + } + + /// find node index, returns -1 if not found + int findChild(Node3d node) { + if (node is null) + return -1; + for (int i = 0; i < childCount; i++) { + if (child(i) is node) + return i; + } + return -1; + } + @property ref ObjectList!Node3d children() { return _children; } /// parent node diff --git a/src/dlangui/graphics/scene/scene3d.d b/src/dlangui/graphics/scene/scene3d.d index b420a6cb..bb459fa8 100644 --- a/src/dlangui/graphics/scene/scene3d.d +++ b/src/dlangui/graphics/scene/scene3d.d @@ -7,6 +7,7 @@ import dlangui.core.types; import dlangui.core.math3d; import dlangui.graphics.scene.node; +import dlangui.graphics.scene.skybox; /// Reference counted Scene3d object alias Scene3dRef = Ref!Scene3d; @@ -19,12 +20,23 @@ class Scene3d : Node3d { protected vec3 _ambientColor; protected Camera _activeCamera; + protected SkyBox _skyBox; /// ambient light color @property vec3 ambientColor() { return _ambientColor; } /// set ambient light color @property void ambientColor(const ref vec3 v) { _ambientColor = v; } + this(string id = null) { + super(id); + _skyBox = new SkyBox(this); + } + + ~this() { + destroy(_skyBox); + } + + @property SkyBox skyBox() { return _skyBox; } /// active camera override @property Camera activeCamera() { @@ -53,10 +65,19 @@ class Scene3d : Node3d { void drawScene(bool wireframe) { _wireframe = wireframe; updateAutoboundLights(); + if (_skyBox.visible) { + if (_activeCamera) { + _skyBox.translation = _activeCamera.translation; + _skyBox.scaling = _activeCamera.farRange * 0.8; + } + sceneDrawVisitor(_skyBox); + } visit(this, &sceneDrawVisitor); } protected bool sceneDrawVisitor(Node3d node) { + if (!node.visible) + return false; if (!node.drawable.isNull) node.drawable.draw(node, _wireframe); return false;