mirror of https://github.com/buggins/dlangui.git
#183 improvements
This commit is contained in:
parent
b01f90c7c2
commit
a48dd1d99b
|
@ -1512,9 +1512,94 @@ struct mat4 {
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decomposes the scale, rotation and translation components of this matrix.
|
||||
*
|
||||
* @param scale The scale.
|
||||
* @param rotation The rotation.
|
||||
* @param translation The translation.
|
||||
*/
|
||||
bool decompose(vec3 * scale, vec4 * rotation, vec3 * translation) const {
|
||||
if (translation)
|
||||
{
|
||||
// Extract the translation.
|
||||
translation.x = m[12];
|
||||
translation.y = m[13];
|
||||
translation.z = m[14];
|
||||
}
|
||||
|
||||
// Nothing left to do.
|
||||
if (!scale && !rotation)
|
||||
return true;
|
||||
|
||||
// Extract the scale.
|
||||
// This is simply the length of each axis (row/column) in the matrix.
|
||||
vec3 xaxis = vec3(m[0], m[1], m[2]);
|
||||
float scaleX = xaxis.length();
|
||||
|
||||
vec3 yaxis = vec3(m[4], m[5], m[6]);
|
||||
float scaleY = yaxis.length();
|
||||
|
||||
vec3 zaxis = vec3(m[8], m[9], m[10]);
|
||||
float scaleZ = zaxis.length();
|
||||
|
||||
// Determine if we have a negative scale (true if determinant is less than zero).
|
||||
// In this case, we simply negate a single axis of the scale.
|
||||
float det = determinant();
|
||||
if (det < 0)
|
||||
scaleZ = -scaleZ;
|
||||
|
||||
if (scale)
|
||||
{
|
||||
scale.x = scaleX;
|
||||
scale.y = scaleY;
|
||||
scale.z = scaleZ;
|
||||
}
|
||||
|
||||
// Nothing left to do.
|
||||
if (!rotation)
|
||||
return true;
|
||||
|
||||
//// Scale too close to zero, can't decompose rotation.
|
||||
//if (scaleX < MATH_TOLERANCE || scaleY < MATH_TOLERANCE || fabs(scaleZ) < MATH_TOLERANCE)
|
||||
// return false;
|
||||
// TODO: support rotation
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translational component of this matrix in the specified vector.
|
||||
*
|
||||
* @param translation A vector to receive the translation.
|
||||
*/
|
||||
void getTranslation(ref vec3 translation) const
|
||||
{
|
||||
decompose(null, null, &translation);
|
||||
}
|
||||
|
||||
@property float determinant() const
|
||||
{
|
||||
float a0 = m[0] * m[5] - m[1] * m[4];
|
||||
float a1 = m[0] * m[6] - m[2] * m[4];
|
||||
float a2 = m[0] * m[7] - m[3] * m[4];
|
||||
float a3 = m[1] * m[6] - m[2] * m[5];
|
||||
float a4 = m[1] * m[7] - m[3] * m[5];
|
||||
float a5 = m[2] * m[7] - m[3] * m[6];
|
||||
float b0 = m[8] * m[13] - m[9] * m[12];
|
||||
float b1 = m[8] * m[14] - m[10] * m[12];
|
||||
float b2 = m[8] * m[15] - m[11] * m[12];
|
||||
float b3 = m[9] * m[14] - m[10] * m[13];
|
||||
float b4 = m[9] * m[15] - m[11] * m[13];
|
||||
float b5 = m[10] * m[15] - m[11] * m[14];
|
||||
// Calculate the determinant.
|
||||
return (a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0);
|
||||
}
|
||||
|
||||
static __gshared const mat4 IDENTITY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unittest {
|
||||
vec3 a, b, c;
|
||||
a.clear(5);
|
||||
|
|
|
@ -351,6 +351,15 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect {
|
|||
checkgl!glUniformMatrix4fv(getUniformLocation(id), 1, false, matrix.m.ptr);
|
||||
}
|
||||
|
||||
/// returns true if effect has uniform
|
||||
override bool hasUniform(DefaultUniform id) {
|
||||
return getUniformLocation(id) >= 0;
|
||||
}
|
||||
|
||||
/// returns true if effect has uniform
|
||||
override bool hasUniform(string uniformName) {
|
||||
return getUniformLocation(uniformName) >= 0;
|
||||
}
|
||||
|
||||
/// draw mesh using this program (program should be bound by this time and all uniforms should be set)
|
||||
override void draw(Mesh mesh) {
|
||||
|
|
|
@ -53,7 +53,7 @@ class Camera : Node3d {
|
|||
_dirtyView = true;
|
||||
}
|
||||
|
||||
@property ref const(mat4) viewMatrix() {
|
||||
override @property ref const(mat4) viewMatrix() {
|
||||
if (_dirtyView) {
|
||||
_viewMatrix = matrix.invert();
|
||||
_dirtyView = false;
|
||||
|
@ -62,7 +62,7 @@ class Camera : Node3d {
|
|||
}
|
||||
|
||||
/// get projection*view matrix
|
||||
@property ref const(mat4) projectionViewMatrix() {
|
||||
override @property ref const(mat4) projectionViewMatrix() {
|
||||
if (_dirtyTransform || _dirtyViewProjection) {
|
||||
_viewProjectionMatrix = _projectionMatrix * viewMatrix;
|
||||
_dirtyViewProjection = false;
|
||||
|
|
|
@ -75,7 +75,12 @@ class Material : RefCountedObject {
|
|||
texture.texture.setSamplerParams(true);
|
||||
}
|
||||
// TODO: more uniforms
|
||||
if (_effect.hasUniform(DefaultUniform.u_worldViewProjectionMatrix))
|
||||
_effect.setUniform(DefaultUniform.u_worldViewProjectionMatrix, node.projectionViewModelMatrix);
|
||||
if (_effect.hasUniform(DefaultUniform.u_cameraPosition))
|
||||
_effect.setUniform(DefaultUniform.u_cameraPosition, node.cameraPosition);
|
||||
if (_effect.hasUniform(DefaultUniform.u_worldViewMatrix))
|
||||
_effect.setUniform(DefaultUniform.u_worldViewMatrix, node.worldViewMatrix);
|
||||
}
|
||||
|
||||
void drawMesh(Mesh mesh) {
|
||||
|
|
|
@ -29,6 +29,12 @@ abstract class GraphicsEffect : RefCountedObject {
|
|||
|
||||
void setUniform(DefaultUniform id, vec4 vec);
|
||||
|
||||
/// returns true if effect has uniform
|
||||
bool hasUniform(DefaultUniform id);
|
||||
|
||||
/// returns true if effect has uniform
|
||||
bool hasUniform(string uniformName);
|
||||
|
||||
void draw(Mesh mesh);
|
||||
}
|
||||
|
||||
|
@ -51,9 +57,9 @@ enum DefaultUniform : int {
|
|||
u_modulateAlpha, //uniform float u_modulateAlpha;
|
||||
|
||||
u_worldViewProjectionMatrix, //uniform mat4 u_worldViewProjectionMatrix;
|
||||
u_matrixPalette, //uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
|
||||
u_inverseTransposeWorldViewMatrix, //uniform mat4 u_inverseTransposeWorldViewMatrix;
|
||||
u_worldViewMatrix, //uniform mat4 u_worldViewMatrix;
|
||||
u_matrixPalette, //uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
|
||||
u_cameraPosition, //uniform vec3 u_cameraPosition;
|
||||
u_worldMatrix, //uniform mat4 u_worldMatrix;
|
||||
u_clipPlane, //uniform vec4 u_clipPlane;
|
||||
|
|
|
@ -7,6 +7,7 @@ import dlangui.core.collections;
|
|||
import dlangui.graphics.scene.scene3d;
|
||||
import dlangui.graphics.scene.drawableobject;
|
||||
import dlangui.graphics.scene.light;
|
||||
import dlangui.graphics.scene.camera;
|
||||
|
||||
/// 3D scene node
|
||||
class Node3d : Transform {
|
||||
|
@ -97,10 +98,68 @@ class Node3d : Transform {
|
|||
return this;
|
||||
}
|
||||
|
||||
/// active camera or null of no camera
|
||||
@property Camera activeCamera() {
|
||||
if (!scene)
|
||||
return null;
|
||||
return scene.activeCamera;
|
||||
}
|
||||
|
||||
@property vec3 cameraPosition() {
|
||||
auto cam = activeCamera;
|
||||
if (cam)
|
||||
return cam.translationWorld;
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
/// get view matrix based on active camera
|
||||
@property ref const(mat4) viewMatrix() {
|
||||
auto cam = activeCamera;
|
||||
if (cam)
|
||||
return cam.viewMatrix;
|
||||
return mat4.IDENTITY;
|
||||
}
|
||||
|
||||
/// get projection*view matrix based on active camera
|
||||
@property ref const(mat4) projectionViewMatrix() {
|
||||
auto cam = activeCamera;
|
||||
if (cam)
|
||||
return cam.projectionViewMatrix;
|
||||
return mat4.IDENTITY;
|
||||
}
|
||||
|
||||
protected mat4 _projectionViewModelMatrix;
|
||||
|
||||
/// returns projectionMatrix * viewMatrix * modelMatrix
|
||||
@property ref const(mat4) projectionViewModelMatrix() {
|
||||
// TODO: optimize
|
||||
_projectionViewModelMatrix = _scene.projectionViewMatrix * matrix;
|
||||
return _projectionViewModelMatrix;
|
||||
}
|
||||
|
||||
/// returns world matrix
|
||||
@property ref const(mat4) worldMatrix() {
|
||||
if (!parent)
|
||||
return matrix;
|
||||
_worldMatrix = parent.worldMatrix * matrix;
|
||||
return _worldMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world view matrix corresponding to this node.
|
||||
*
|
||||
* @return The world view matrix of this node.
|
||||
*/
|
||||
@property ref const(mat4) worldViewMatrix() {
|
||||
static mat4 worldView;
|
||||
worldView = viewMatrix * worldMatrix;
|
||||
return worldView;
|
||||
}
|
||||
|
||||
/// returns translation vector (position) of this node in world space
|
||||
@property vec3 translationWorld() {
|
||||
vec3 translation;
|
||||
worldMatrix.getTranslation(translation);
|
||||
return translation;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class Scene3d : Node3d {
|
|||
|
||||
|
||||
/// active camera
|
||||
@property Camera activeCamera() {
|
||||
override @property Camera activeCamera() {
|
||||
if (_activeCamera)
|
||||
return _activeCamera;
|
||||
// TODO: find camera in child nodes
|
||||
|
@ -44,14 +44,6 @@ class Scene3d : Node3d {
|
|||
//ignore
|
||||
}
|
||||
|
||||
/// get projection*view matrix
|
||||
@property ref const(mat4) projectionViewMatrix() {
|
||||
if (_activeCamera)
|
||||
return _activeCamera.projectionViewMatrix;
|
||||
static mat4 dummyIdentityMatrix;
|
||||
return dummyIdentityMatrix;
|
||||
}
|
||||
|
||||
protected bool _wireframe;
|
||||
void drawScene(bool wireframe) {
|
||||
_wireframe = wireframe;
|
||||
|
|
Loading…
Reference in New Issue