mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-14 16:07:39 +00:00
TINYGL: Done several optimizations to the maths code.
This commit is contained in:
parent
9be1423802
commit
4fbb2d0dc3
@ -25,18 +25,18 @@ void glopArrayElement(GLContext *c, GLParam *param) {
|
||||
}
|
||||
if (states & NORMAL_ARRAY) {
|
||||
i = idx * (3 + c->normal_array_stride);
|
||||
c->current_normal.setX(c->normal_array[i]);
|
||||
c->current_normal.setY(c->normal_array[i + 1]);
|
||||
c->current_normal.setZ(c->normal_array[i + 2]);
|
||||
c->current_normal.setW(0.0f); // NOTE: this used to be Z but assigning Z again seemed like a bug...
|
||||
c->current_normal.X = (c->normal_array[i]);
|
||||
c->current_normal.Y = (c->normal_array[i + 1]);
|
||||
c->current_normal.Z = (c->normal_array[i + 2]);
|
||||
c->current_normal.W = (0.0f); // NOTE: this used to be Z but assigning Z again seemed like a bug...
|
||||
}
|
||||
if (states & TEXCOORD_ARRAY) {
|
||||
int size = c->texcoord_array_size;
|
||||
i = idx * (size + c->texcoord_array_stride);
|
||||
c->current_tex_coord.setX(c->texcoord_array[i]);
|
||||
c->current_tex_coord.setY(c->texcoord_array[i + 1]);
|
||||
c->current_tex_coord.setZ(size > 2 ? c->texcoord_array[i + 2] : 0.0f);
|
||||
c->current_tex_coord.setW(size > 3 ? c->texcoord_array[i + 3] : 1.0f);
|
||||
c->current_tex_coord.X = (c->texcoord_array[i]);
|
||||
c->current_tex_coord.Y = (c->texcoord_array[i + 1]);
|
||||
c->current_tex_coord.Z = (size > 2 ? c->texcoord_array[i + 2] : 0.0f);
|
||||
c->current_tex_coord.W = (size > 3 ? c->texcoord_array[i + 3] : 1.0f);
|
||||
}
|
||||
if (states & VERTEX_ARRAY) {
|
||||
GLParam p[5];
|
||||
|
@ -14,9 +14,9 @@ void glopClearDepth(GLContext *c, GLParam *p) {
|
||||
void glopClear(GLContext *c, GLParam *p) {
|
||||
int mask = p[1].i;
|
||||
int z = 0;
|
||||
int r = (int)(c->clear_color.getX() * 65535);
|
||||
int g = (int)(c->clear_color.getY() * 65535);
|
||||
int b = (int)(c->clear_color.getZ() * 65535);
|
||||
int r = (int)(c->clear_color.X * 65535);
|
||||
int g = (int)(c->clear_color.Y * 65535);
|
||||
int b = (int)(c->clear_color.Z * 65535);
|
||||
|
||||
// TODO : correct value of Z
|
||||
ZB_clear(c->zb, mask & TGL_DEPTH_BUFFER_BIT, z, mask & TGL_COLOR_BUFFER_BIT, r, g, b);
|
||||
|
@ -17,17 +17,17 @@ void gl_transform_to_viewport(GLContext *c, GLVertex *v) {
|
||||
float winv;
|
||||
|
||||
// coordinates
|
||||
winv = (float)(1.0 / v->pc.getW());
|
||||
v->zp.x = (int)(v->pc.getX() * winv * c->viewport.scale.getX() + c->viewport.trans.getX());
|
||||
v->zp.y = (int)(v->pc.getY() * winv * c->viewport.scale.getY() + c->viewport.trans.getY());
|
||||
v->zp.z = (int)(v->pc.getZ() * winv * c->viewport.scale.getZ() + c->viewport.trans.getZ());
|
||||
winv = (float)(1.0 / v->pc.W);
|
||||
v->zp.x = (int)(v->pc.X * winv * c->viewport.scale.X + c->viewport.trans.X);
|
||||
v->zp.y = (int)(v->pc.Y * winv * c->viewport.scale.Y + c->viewport.trans.Y);
|
||||
v->zp.z = (int)(v->pc.Z * winv * c->viewport.scale.Z + c->viewport.trans.Z);
|
||||
// color
|
||||
if (c->lighting_enabled) {
|
||||
v->zp.r = (int)(v->color.getX() * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN)
|
||||
v->zp.r = (int)(v->color.X * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN)
|
||||
+ ZB_POINT_RED_MIN);
|
||||
v->zp.g = (int)(v->color.getY() * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN)
|
||||
v->zp.g = (int)(v->color.Y * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN)
|
||||
+ ZB_POINT_GREEN_MIN);
|
||||
v->zp.b = (int)(v->color.getZ() * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)
|
||||
v->zp.b = (int)(v->color.Z * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)
|
||||
+ ZB_POINT_BLUE_MIN);
|
||||
} else {
|
||||
// no need to convert to integer if no lighting : take current color
|
||||
@ -38,8 +38,8 @@ void gl_transform_to_viewport(GLContext *c, GLVertex *v) {
|
||||
|
||||
// texture
|
||||
if (c->texture_2d_enabled) {
|
||||
v->zp.s = (int)(v->tex_coord.getX() * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
|
||||
v->zp.t = (int)(v->tex_coord.getY() * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
|
||||
v->zp.s = (int)(v->tex_coord.X * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
|
||||
v->zp.t = (int)(v->tex_coord.Y * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,14 +125,14 @@ void gl_draw_line(GLContext *c, GLVertex *p1, GLVertex *p2) {
|
||||
} else if ((cc1 & cc2) != 0) {
|
||||
return;
|
||||
} else {
|
||||
dx = p2->pc.getX() - p1->pc.getX();
|
||||
dy = p2->pc.getY() - p1->pc.getY();
|
||||
dz = p2->pc.getZ() - p1->pc.getZ();
|
||||
dw = p2->pc.getW() - p1->pc.getW();
|
||||
x1 = p1->pc.getX();
|
||||
y1 = p1->pc.getY();
|
||||
z1 = p1->pc.getZ();
|
||||
w1 = p1->pc.getW();
|
||||
dx = p2->pc.X - p1->pc.X;
|
||||
dy = p2->pc.Y - p1->pc.Y;
|
||||
dz = p2->pc.Z - p1->pc.Z;
|
||||
dw = p2->pc.W - p1->pc.W;
|
||||
x1 = p1->pc.X;
|
||||
y1 = p1->pc.Y;
|
||||
z1 = p1->pc.Z;
|
||||
w1 = p1->pc.W;
|
||||
|
||||
tmin = 0;
|
||||
tmax = 1;
|
||||
@ -166,19 +166,19 @@ void gl_draw_line(GLContext *c, GLVertex *p1, GLVertex *p2) {
|
||||
#define clip_func(name, sign, dir, dir1, dir2) \
|
||||
static float name(Vector4 *c, Vector4 *a, Vector4 *b) { \
|
||||
float t, dX, dY, dZ, dW, den;\
|
||||
dX = (b->getX() - a->getX()); \
|
||||
dY = (b->getY() - a->getY()); \
|
||||
dZ = (b->getZ() - a->getZ()); \
|
||||
dW = (b->getW() - a->getW()); \
|
||||
dX = (b->X - a->X); \
|
||||
dY = (b->Y - a->Y); \
|
||||
dZ = (b->Z - a->Z); \
|
||||
dW = (b->W - a->W); \
|
||||
den = -(sign d ## dir) + dW; \
|
||||
if (den == 0) \
|
||||
t = 0; \
|
||||
else \
|
||||
t = (sign a->get ## dir () - a->getW()) / den; \
|
||||
c->set ## dir1 (a->get ## dir1 () + t * d ## dir1); \
|
||||
c->set ## dir2 (a->get ## dir2 () + t * d ## dir2); \
|
||||
c->setW(a->getW() + t * dW); \
|
||||
c->set ## dir (sign c->getW()); \
|
||||
t = (sign a-> dir - a->W) / den; \
|
||||
c-> dir1 = (a-> dir1 + t * d ## dir1); \
|
||||
c-> dir2 = (a-> dir2 + t * d ## dir2); \
|
||||
c->W = (a->W + t * dW); \
|
||||
c-> dir = (sign c->W); \
|
||||
return t; \
|
||||
}
|
||||
|
||||
@ -198,23 +198,23 @@ float(*clip_proc[6])(Vector4 *, Vector4 *, Vector4 *) = {
|
||||
static inline void updateTmp(GLContext *c, GLVertex *q,
|
||||
GLVertex *p0, GLVertex *p1, float t) {
|
||||
if (c->current_shade_model == TGL_SMOOTH) {
|
||||
float a = q->color.getW();
|
||||
float a = q->color.W;
|
||||
q->color = p0->color + (p1->color - p0->color) * t;
|
||||
q->color.setW(a);
|
||||
q->color.W = a;
|
||||
} else {
|
||||
q->color.setX(p0->color.getX());
|
||||
q->color.setY(p0->color.getY());
|
||||
q->color.setZ(p0->color.getZ());
|
||||
q->color.X = (p0->color.X);
|
||||
q->color.Y = (p0->color.Y);
|
||||
q->color.Z = (p0->color.Z);
|
||||
//q->color = p0->color;
|
||||
}
|
||||
|
||||
if (c->texture_2d_enabled) {
|
||||
//NOTE: This could be implemented with operator overloading, but i'm not 100% sure that we can completely disregard Z and W components so I'm leaving it like this for now.
|
||||
q->tex_coord.setX(p0->tex_coord.getX() + (p1->tex_coord.getX() - p0->tex_coord.getX()) * t);
|
||||
q->tex_coord.setY(p0->tex_coord.getY() + (p1->tex_coord.getY() - p0->tex_coord.getY()) * t);
|
||||
q->tex_coord.X = (p0->tex_coord.X + (p1->tex_coord.X - p0->tex_coord.X) * t);
|
||||
q->tex_coord.Y = (p0->tex_coord.Y + (p1->tex_coord.Y - p0->tex_coord.Y) * t);
|
||||
}
|
||||
|
||||
q->clip_code = gl_clipcode(q->pc.getX(), q->pc.getY(), q->pc.getZ(), q->pc.getW());
|
||||
q->clip_code = gl_clipcode(q->pc.X, q->pc.Y, q->pc.Z, q->pc.W);
|
||||
if (q->clip_code == 0)
|
||||
gl_transform_to_viewport(c, q);
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ void tglGetIntegerv(int pname, int *params) {
|
||||
}
|
||||
|
||||
void tglGetFloatv(int pname, float *v) {
|
||||
TinyGL::Matrix4* m;
|
||||
int i;
|
||||
int mnr = 0; // just a trick to return the correct matrix
|
||||
TinyGL::GLContext *c = TinyGL::gl_get_context();
|
||||
|
@ -33,8 +33,8 @@ void glopMaterial(GLContext *c, GLParam *p) {
|
||||
m->specular = v;
|
||||
break;
|
||||
case TGL_SHININESS:
|
||||
m->shininess = v.getX();
|
||||
m->shininess_i = (int)(v.getX() / 128.0f) * SPECULAR_BUFFER_RESOLUTION;
|
||||
m->shininess = v.X;
|
||||
m->shininess_i = (int)(v.X / 128.0f) * SPECULAR_BUFFER_RESOLUTION;
|
||||
break;
|
||||
case TGL_AMBIENT_AND_DIFFUSE:
|
||||
m->diffuse = v;
|
||||
@ -78,7 +78,7 @@ void glopLight(GLContext *c, GLParam *p) {
|
||||
|
||||
l->position = pos;
|
||||
|
||||
if (l->position.getW() == 0) {
|
||||
if (l->position.W == 0) {
|
||||
l->norm_position = pos.toVector3();
|
||||
l->norm_position.normalize();
|
||||
}
|
||||
@ -90,10 +90,10 @@ void glopLight(GLContext *c, GLParam *p) {
|
||||
l->norm_spot_direction.normalize();
|
||||
break;
|
||||
case TGL_SPOT_EXPONENT:
|
||||
l->spot_exponent = v.getX();
|
||||
l->spot_exponent = v.X;
|
||||
break;
|
||||
case TGL_SPOT_CUTOFF: {
|
||||
float a = v.getX();
|
||||
float a = v.X;
|
||||
assert(a == 180 || (a >= 0 && a <= 90));
|
||||
l->spot_cutoff = a;
|
||||
if (a != 180)
|
||||
@ -101,13 +101,13 @@ void glopLight(GLContext *c, GLParam *p) {
|
||||
}
|
||||
break;
|
||||
case TGL_CONSTANT_ATTENUATION:
|
||||
l->attenuation[0] = v.getX();
|
||||
l->attenuation[0] = v.X;
|
||||
break;
|
||||
case TGL_LINEAR_ATTENUATION:
|
||||
l->attenuation[1] = v.getX();
|
||||
l->attenuation[1] = v.X;
|
||||
break;
|
||||
case TGL_QUADRATIC_ATTENUATION:
|
||||
l->attenuation[2] = v.getX();
|
||||
l->attenuation[2] = v.X;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@ -178,26 +178,26 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
|
||||
|
||||
n = v->normal;
|
||||
|
||||
R = m->emission.getX() + m->ambient.getX() * c->ambient_light_model.getX();
|
||||
G = m->emission.getY() + m->ambient.getY() * c->ambient_light_model.getY();
|
||||
B = m->emission.getZ() + m->ambient.getZ() * c->ambient_light_model.getZ();
|
||||
A = clampf(m->diffuse.getW(), 0, 1);
|
||||
R = m->emission.X + m->ambient.X * c->ambient_light_model.X;
|
||||
G = m->emission.Y + m->ambient.Y * c->ambient_light_model.Y;
|
||||
B = m->emission.Z + m->ambient.Z * c->ambient_light_model.Z;
|
||||
A = clampf(m->diffuse.W, 0, 1);
|
||||
|
||||
for (l = c->first_light; l != NULL; l = l->next) {
|
||||
float lR, lB, lG;
|
||||
|
||||
// ambient
|
||||
lR = l->ambient.getX() * m->ambient.getX();
|
||||
lG = l->ambient.getY() * m->ambient.getY();
|
||||
lB = l->ambient.getZ() * m->ambient.getZ();
|
||||
lR = l->ambient.X * m->ambient.X;
|
||||
lG = l->ambient.Y * m->ambient.Y;
|
||||
lB = l->ambient.Z * m->ambient.Z;
|
||||
|
||||
if (l->position.getW() == 0) {
|
||||
if (l->position.W == 0) {
|
||||
// light at infinity
|
||||
d = l->position.toVector3();
|
||||
att = 1;
|
||||
} else {
|
||||
// distance attenuation
|
||||
d = l->position.toVector3() - v->ec.toVector3();
|
||||
d = (l->position - v->ec).toVector3();
|
||||
dist = d.getLength();
|
||||
if (dist > 1E-3) {
|
||||
tmp = 1 / dist;
|
||||
@ -211,9 +211,9 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
|
||||
dot = -dot;
|
||||
if (dot > 0) {
|
||||
// diffuse light
|
||||
lR += dot * l->diffuse.getX() * m->diffuse.getX();
|
||||
lG += dot * l->diffuse.getY() * m->diffuse.getY();
|
||||
lB += dot * l->diffuse.getZ() * m->diffuse.getZ();
|
||||
lR += dot * l->diffuse.X * m->diffuse.X;
|
||||
lG += dot * l->diffuse.Y * m->diffuse.Y;
|
||||
lB += dot * l->diffuse.Z * m->diffuse.Z;
|
||||
|
||||
// spot light
|
||||
if (l->spot_cutoff != 180) {
|
||||
@ -237,13 +237,13 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
|
||||
Vector3 vcoord;
|
||||
vcoord = v->ec.toVector3();
|
||||
vcoord.normalize();
|
||||
s.setX(d.getX() - vcoord.getX());
|
||||
s.setY(d.getY() - vcoord.getX());
|
||||
s.setZ(d.getZ() - vcoord.getX());
|
||||
s.X = (d.X - vcoord.X);
|
||||
s.Y = (d.Y - vcoord.X);
|
||||
s.Z = (d.Z - vcoord.X);
|
||||
//NOTE: this operation is rather suspicious, this code should be tested.
|
||||
} else {
|
||||
s = d;
|
||||
s.setZ(s.getZ() + 1.0);
|
||||
s.Z = (s.Z + 1.0);
|
||||
}
|
||||
dot_spec = Vector3::dot(n, s);
|
||||
if (twoside && dot_spec < 0)
|
||||
@ -267,9 +267,9 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
|
||||
idx = (int)tmp;
|
||||
|
||||
dot_spec = specbuf->buf[idx];
|
||||
lR += dot_spec * l->specular.getX() * m->specular.getX();
|
||||
lG += dot_spec * l->specular.getY() * m->specular.getY();
|
||||
lB += dot_spec * l->specular.getZ() * m->specular.getZ();
|
||||
lR += dot_spec * l->specular.X * m->specular.X;
|
||||
lG += dot_spec * l->specular.Y * m->specular.Y;
|
||||
lB += dot_spec * l->specular.Z * m->specular.Z;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,26 +172,25 @@ void glopRotate(GLContext *c, GLParam *p) {
|
||||
void glopScale(GLContext *c, GLParam *p) {
|
||||
float x = p[1].f, y = p[2].f, z = p[3].f;
|
||||
|
||||
Matrix4 m = Matrix4::identity();
|
||||
Matrix4 *m = c->matrix_stack_ptr[c->matrix_mode];
|
||||
|
||||
m.set(0, 0, x);
|
||||
m.set(1, 1, y);
|
||||
m.set(2, 2, z);
|
||||
|
||||
*c->matrix_stack_ptr[c->matrix_mode] *= m;
|
||||
m->set(0, 0, m->get(0, 0) * x); m->set(0, 1, m->get(0, 1) * y); m->set(0, 2, m->get(0, 2) * z);
|
||||
m->set(1, 0, m->get(1, 0) * x); m->set(1, 1, m->get(1, 1) * y); m->set(1, 2, m->get(1, 2) * z);
|
||||
m->set(2, 0, m->get(2, 0) * x); m->set(2, 1, m->get(2, 1) * y); m->set(2, 2, m->get(2, 2) * z);
|
||||
m->set(3, 0, m->get(3, 0) * x); m->set(3, 1, m->get(3, 1) * y); m->set(3, 2, m->get(3, 2) * z);
|
||||
|
||||
gl_matrix_update(c);
|
||||
}
|
||||
|
||||
void glopTranslate(GLContext *c, GLParam *p) {
|
||||
Matrix4 m = Matrix4::identity();
|
||||
float x = p[1].f, y = p[2].f, z = p[3].f;
|
||||
|
||||
m.set(0, 3, x);
|
||||
m.set(1, 3, y);
|
||||
m.set(2, 3, z);
|
||||
Matrix4 *m = c->matrix_stack_ptr[c->matrix_mode];
|
||||
|
||||
*c->matrix_stack_ptr[c->matrix_mode] *= m;
|
||||
m->set(0, 3, m->get(0,0) * x + m->get(0,1) * y + m->get(0,2) * z + m->get(0,3));
|
||||
m->set(1, 3, m->get(1,0) * x + m->get(1,1) * y + m->get(1,2) * z + m->get(1,3));
|
||||
m->set(2, 3, m->get(2,0) * x + m->get(2,1) * y + m->get(2,2) * z + m->get(2,3));
|
||||
m->set(3, 3, m->get(3,0) * x + m->get(3,1) * y + m->get(3,2) * z + m->get(3,3));
|
||||
|
||||
gl_matrix_update(c);
|
||||
}
|
||||
|
@ -40,13 +40,13 @@ void gl_eval_viewport(GLContext *c) {
|
||||
|
||||
v = &c->viewport;
|
||||
|
||||
v->trans.setX((float)(((v->xsize - 0.5) / 2.0) + v->xmin));
|
||||
v->trans.setY((float)(((v->ysize - 0.5) / 2.0) + v->ymin));
|
||||
v->trans.setZ((float)(((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2));
|
||||
v->trans.X = ((float)(((v->xsize - 0.5) / 2.0) + v->xmin));
|
||||
v->trans.Y = ((float)(((v->ysize - 0.5) / 2.0) + v->ymin));
|
||||
v->trans.Z = ((float)(((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2));
|
||||
|
||||
v->scale.setX((float)((v->xsize - 0.5) / 2.0));
|
||||
v->scale.setY((float)(-(v->ysize - 0.5) / 2.0));
|
||||
v->scale.setZ((float)(-((zsize - 0.5) / 2.0)));
|
||||
v->scale.X = ((float)((v->xsize - 0.5) / 2.0));
|
||||
v->scale.Y = ((float)(-(v->ysize - 0.5) / 2.0));
|
||||
v->scale.Z = ((float)(-((zsize - 0.5) / 2.0)));
|
||||
}
|
||||
|
||||
void glopBegin(GLContext *c, GLParam *p) {
|
||||
@ -63,7 +63,9 @@ void glopBegin(GLContext *c, GLParam *p) {
|
||||
if (c->matrix_model_projection_updated) {
|
||||
if (c->lighting_enabled) {
|
||||
// precompute inverse modelview
|
||||
c->matrix_model_view_inv = c->matrix_stack_ptr[0]->inverse().transpose();
|
||||
c->matrix_model_view_inv = *c->matrix_stack_ptr[0];
|
||||
c->matrix_model_view_inv.invert();
|
||||
c->matrix_model_view_inv.transpose();
|
||||
} else {
|
||||
// precompute projection matrix
|
||||
c->matrix_model_projection = (*c->matrix_stack_ptr[1]) * (*c->matrix_stack_ptr[0]);
|
||||
@ -153,11 +155,11 @@ static inline void gl_vertex_transform(GLContext *c, GLVertex *v) {
|
||||
|
||||
v->pc = m->transform3x4(v->coord);
|
||||
if (c->matrix_model_projection_no_w_transform) {
|
||||
v->pc.setW(m->get(3,3));
|
||||
v->pc.W = (m->get(3,3));
|
||||
}
|
||||
}
|
||||
|
||||
v->clip_code = gl_clipcode(v->pc.getX(), v->pc.getY(), v->pc.getZ(), v->pc.getW());
|
||||
v->clip_code = gl_clipcode(v->pc.X, v->pc.Y, v->pc.Z, v->pc.W);
|
||||
}
|
||||
|
||||
void glopVertex(GLContext *c, GLParam *p) {
|
||||
|
@ -8,67 +8,132 @@ namespace TinyGL {
|
||||
// Inversion of a general nxn matrix.
|
||||
// Note : m is destroyed
|
||||
int Matrix_Inv(float *r, float *m, int n) {
|
||||
int k;
|
||||
float max, tmp, t;
|
||||
double inv[16], det;
|
||||
int i;
|
||||
|
||||
// identitée dans r
|
||||
for (int i = 0; i < n * n; i++)
|
||||
r[i] = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
r[i * n + i] = 1;
|
||||
inv[0] = m[5] * m[10] * m[15] -
|
||||
m[5] * m[11] * m[14] -
|
||||
m[9] * m[6] * m[15] +
|
||||
m[9] * m[7] * m[14] +
|
||||
m[13] * m[6] * m[11] -
|
||||
m[13] * m[7] * m[10];
|
||||
|
||||
for (int j = 0; j < n; j++) {
|
||||
max = m[j * n + j];
|
||||
k = j;
|
||||
for (int i = j + 1; i < n; i++) {
|
||||
if (fabs(m[i * n + j]) > fabs(max)) {
|
||||
k = i;
|
||||
max = m[i * n + j];
|
||||
}
|
||||
}
|
||||
// non intersible matrix
|
||||
if (max == 0)
|
||||
return 1;
|
||||
inv[4] = -m[4] * m[10] * m[15] +
|
||||
m[4] * m[11] * m[14] +
|
||||
m[8] * m[6] * m[15] -
|
||||
m[8] * m[7] * m[14] -
|
||||
m[12] * m[6] * m[11] +
|
||||
m[12] * m[7] * m[10];
|
||||
|
||||
if (k != j) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
tmp = m[j * n + i];
|
||||
m[j * n + i] = m[k * n + i];
|
||||
m[k * n + i] = tmp;
|
||||
inv[8] = m[4] * m[9] * m[15] -
|
||||
m[4] * m[11] * m[13] -
|
||||
m[8] * m[5] * m[15] +
|
||||
m[8] * m[7] * m[13] +
|
||||
m[12] * m[5] * m[11] -
|
||||
m[12] * m[7] * m[9];
|
||||
|
||||
tmp = r[j * n + i];
|
||||
r[j * n + i] = r[k * n + i];
|
||||
r[k * n + i] = tmp;
|
||||
}
|
||||
}
|
||||
inv[12] = -m[4] * m[9] * m[14] +
|
||||
m[4] * m[10] * m[13] +
|
||||
m[8] * m[5] * m[14] -
|
||||
m[8] * m[6] * m[13] -
|
||||
m[12] * m[5] * m[10] +
|
||||
m[12] * m[6] * m[9];
|
||||
|
||||
max = 1 / max;
|
||||
for (int i = 0; i < n; i++) {
|
||||
m[j * n + i] *= max;
|
||||
r[j * n + i] *= max;
|
||||
}
|
||||
inv[1] = -m[1] * m[10] * m[15] +
|
||||
m[1] * m[11] * m[14] +
|
||||
m[9] * m[2] * m[15] -
|
||||
m[9] * m[3] * m[14] -
|
||||
m[13] * m[2] * m[11] +
|
||||
m[13] * m[3] * m[10];
|
||||
|
||||
inv[5] = m[0] * m[10] * m[15] -
|
||||
m[0] * m[11] * m[14] -
|
||||
m[8] * m[2] * m[15] +
|
||||
m[8] * m[3] * m[14] +
|
||||
m[12] * m[2] * m[11] -
|
||||
m[12] * m[3] * m[10];
|
||||
|
||||
for (int l = 0; l < n; l++) {
|
||||
if (l != j) {
|
||||
t = m[l * n + j];
|
||||
for (int i = 0; i < n; i++) {
|
||||
m[l * n + i] -= m[j * n + i] * t;
|
||||
r[l * n + i] -= r[j * n + i] * t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inv[9] = -m[0] * m[9] * m[15] +
|
||||
m[0] * m[11] * m[13] +
|
||||
m[8] * m[1] * m[15] -
|
||||
m[8] * m[3] * m[13] -
|
||||
m[12] * m[1] * m[11] +
|
||||
m[12] * m[3] * m[9];
|
||||
|
||||
return 0;
|
||||
}
|
||||
inv[13] = m[0] * m[9] * m[14] -
|
||||
m[0] * m[10] * m[13] -
|
||||
m[8] * m[1] * m[14] +
|
||||
m[8] * m[2] * m[13] +
|
||||
m[12] * m[1] * m[10] -
|
||||
m[12] * m[2] * m[9];
|
||||
|
||||
Vector3::Vector3() {
|
||||
// Empty constructor, no overhead
|
||||
}
|
||||
inv[2] = m[1] * m[6] * m[15] -
|
||||
m[1] * m[7] * m[14] -
|
||||
m[5] * m[2] * m[15] +
|
||||
m[5] * m[3] * m[14] +
|
||||
m[13] * m[2] * m[7] -
|
||||
m[13] * m[3] * m[6];
|
||||
|
||||
Vector3::Vector3(const Vector3 &other) {
|
||||
memcpy(_v, other._v, sizeof(_v));
|
||||
inv[6] = -m[0] * m[6] * m[15] +
|
||||
m[0] * m[7] * m[14] +
|
||||
m[4] * m[2] * m[15] -
|
||||
m[4] * m[3] * m[14] -
|
||||
m[12] * m[2] * m[7] +
|
||||
m[12] * m[3] * m[6];
|
||||
|
||||
inv[10] = m[0] * m[5] * m[15] -
|
||||
m[0] * m[7] * m[13] -
|
||||
m[4] * m[1] * m[15] +
|
||||
m[4] * m[3] * m[13] +
|
||||
m[12] * m[1] * m[7] -
|
||||
m[12] * m[3] * m[5];
|
||||
|
||||
inv[14] = -m[0] * m[5] * m[14] +
|
||||
m[0] * m[6] * m[13] +
|
||||
m[4] * m[1] * m[14] -
|
||||
m[4] * m[2] * m[13] -
|
||||
m[12] * m[1] * m[6] +
|
||||
m[12] * m[2] * m[5];
|
||||
|
||||
inv[3] = -m[1] * m[6] * m[11] +
|
||||
m[1] * m[7] * m[10] +
|
||||
m[5] * m[2] * m[11] -
|
||||
m[5] * m[3] * m[10] -
|
||||
m[9] * m[2] * m[7] +
|
||||
m[9] * m[3] * m[6];
|
||||
|
||||
inv[7] = m[0] * m[6] * m[11] -
|
||||
m[0] * m[7] * m[10] -
|
||||
m[4] * m[2] * m[11] +
|
||||
m[4] * m[3] * m[10] +
|
||||
m[8] * m[2] * m[7] -
|
||||
m[8] * m[3] * m[6];
|
||||
|
||||
inv[11] = -m[0] * m[5] * m[11] +
|
||||
m[0] * m[7] * m[9] +
|
||||
m[4] * m[1] * m[11] -
|
||||
m[4] * m[3] * m[9] -
|
||||
m[8] * m[1] * m[7] +
|
||||
m[8] * m[3] * m[5];
|
||||
|
||||
inv[15] = m[0] * m[5] * m[10] -
|
||||
m[0] * m[6] * m[9] -
|
||||
m[4] * m[1] * m[10] +
|
||||
m[4] * m[2] * m[9] +
|
||||
m[8] * m[1] * m[6] -
|
||||
m[8] * m[2] * m[5];
|
||||
|
||||
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
|
||||
if (det == 0)
|
||||
return false;
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
r[i] = inv[i] * det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector3::Vector3(float x, float y, float z) {
|
||||
@ -87,10 +152,6 @@ void Vector3::normalize() {
|
||||
}
|
||||
}
|
||||
|
||||
Vector4::Vector4() {
|
||||
// Empty constructor, no overhead
|
||||
}
|
||||
|
||||
Vector4::Vector4(float x, float y, float z, float w) {
|
||||
_v[0] = x;
|
||||
_v[1] = y;
|
||||
@ -99,20 +160,12 @@ Vector4::Vector4(float x, float y, float z, float w) {
|
||||
}
|
||||
|
||||
Vector4::Vector4(const Vector3 &vec, float w) {
|
||||
_v[0] = vec.getX();
|
||||
_v[1] = vec.getY();
|
||||
_v[2] = vec.getZ();
|
||||
_v[0] = vec.X;
|
||||
_v[1] = vec.Y;
|
||||
_v[2] = vec.Z;
|
||||
_v[3] = w;
|
||||
}
|
||||
|
||||
Matrix4::Matrix4() {
|
||||
// Empty constructor, no overhead
|
||||
}
|
||||
|
||||
Matrix4::Matrix4(const Matrix4 &other) {
|
||||
memcpy(_m, other._m, sizeof(_m));
|
||||
}
|
||||
|
||||
TinyGL::Matrix4 Matrix4::identity() {
|
||||
Matrix4 a;
|
||||
a.fill(0);
|
||||
@ -126,29 +179,53 @@ TinyGL::Matrix4 Matrix4::identity() {
|
||||
TinyGL::Matrix4 Matrix4::transpose() const {
|
||||
Matrix4 a;
|
||||
|
||||
a.set(0, 0, this->get(0, 0));
|
||||
a.set(0, 1, this->get(1, 0));
|
||||
a.set(0, 2, this->get(2, 0));
|
||||
a.set(0, 3, this->get(3, 0));
|
||||
a.set(0, 0, this->_m[0][0]);
|
||||
a.set(0, 1, this->_m[1][0]);
|
||||
a.set(0, 2, this->_m[2][0]);
|
||||
a.set(0, 3, this->_m[3][0]);
|
||||
|
||||
a.set(1, 0, this->get(0, 1));
|
||||
a.set(1, 1, this->get(1, 1));
|
||||
a.set(1, 2, this->get(2, 1));
|
||||
a.set(1, 3, this->get(3, 1));
|
||||
a.set(1, 0, this->_m[0][1]);
|
||||
a.set(1, 1, this->_m[1][1]);
|
||||
a.set(1, 2, this->_m[2][1]);
|
||||
a.set(1, 3, this->_m[3][1]);
|
||||
|
||||
a.set(2, 0, this->get(0, 2));
|
||||
a.set(2, 1, this->get(1, 2));
|
||||
a.set(2, 2, this->get(2, 2));
|
||||
a.set(2, 3, this->get(3, 2));
|
||||
a.set(2, 0, this->_m[0][2]);
|
||||
a.set(2, 1, this->_m[1][2]);
|
||||
a.set(2, 2, this->_m[2][2]);
|
||||
a.set(2, 3, this->_m[3][2]);
|
||||
|
||||
a.set(3, 0, this->get(0, 3));
|
||||
a.set(3, 1, this->get(1, 3));
|
||||
a.set(3, 2, this->get(2, 3));
|
||||
a.set(3, 3, this->get(3, 3));
|
||||
a.set(3, 0, this->_m[0][3]);
|
||||
a.set(3, 1, this->_m[1][3]);
|
||||
a.set(3, 2, this->_m[2][3]);
|
||||
a.set(3, 3, this->_m[3][3]);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
void Matrix4::transpose()
|
||||
{
|
||||
Matrix4 tmp = *this;
|
||||
this->set(0, 0, tmp._m[0][0]);
|
||||
this->set(0, 1, tmp._m[1][0]);
|
||||
this->set(0, 2, tmp._m[2][0]);
|
||||
this->set(0, 3, tmp._m[3][0]);
|
||||
|
||||
this->set(1, 0, tmp._m[0][1]);
|
||||
this->set(1, 1, tmp._m[1][1]);
|
||||
this->set(1, 2, tmp._m[2][1]);
|
||||
this->set(1, 3, tmp._m[3][1]);
|
||||
|
||||
this->set(2, 0, tmp._m[0][2]);
|
||||
this->set(2, 1, tmp._m[1][2]);
|
||||
this->set(2, 2, tmp._m[2][2]);
|
||||
this->set(2, 3, tmp._m[3][2]);
|
||||
|
||||
this->set(3, 0, tmp._m[0][3]);
|
||||
this->set(3, 1, tmp._m[1][3]);
|
||||
this->set(3, 2, tmp._m[2][3]);
|
||||
this->set(3, 3, tmp._m[3][3]);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::inverseOrtho() const {
|
||||
Matrix4 a;
|
||||
|
||||
@ -198,36 +275,6 @@ Matrix4 Matrix4::rotation(float t, int u) {
|
||||
return a;
|
||||
}
|
||||
|
||||
Vector3 Matrix4::transform(const Vector3 &vector) const {
|
||||
return Vector3(
|
||||
vector.getX() * get(0, 0) + vector.getY() * get(0, 1) + vector.getZ() * get(0, 2) + get(0, 3),
|
||||
vector.getX() * get(1, 0) + vector.getY() * get(1, 1) + vector.getZ() * get(1, 2) + get(1, 3),
|
||||
vector.getX() * get(2, 0) + vector.getY() * get(2, 1) + vector.getZ() * get(2, 2) + get(2, 3));
|
||||
}
|
||||
|
||||
Vector3 Matrix4::transform3x3(const Vector3 &vector) const {
|
||||
return Vector3(
|
||||
vector.getX() * get(0, 0) + vector.getY() * get(0, 1) + vector.getZ() * get(0, 2),
|
||||
vector.getX() * get(1, 0) + vector.getY() * get(1, 1) + vector.getZ() * get(1, 2),
|
||||
vector.getX() * get(2, 0) + vector.getY() * get(2, 1) + vector.getZ() * get(2, 2));
|
||||
}
|
||||
|
||||
TinyGL::Vector4 Matrix4::transform3x4(const Vector4 &vector) const {
|
||||
return Vector4(
|
||||
vector.getX() * get(0, 0) + vector.getY() * get(0, 1) + vector.getZ() * get(0, 2) + get(0, 3),
|
||||
vector.getX() * get(1, 0) + vector.getY() * get(1, 1) + vector.getZ() * get(1, 2) + get(1, 3),
|
||||
vector.getX() * get(2, 0) + vector.getY() * get(2, 1) + vector.getZ() * get(2, 2) + get(2, 3),
|
||||
vector.getX() * get(3, 0) + vector.getY() * get(3, 1) + vector.getZ() * get(3, 2) + get(3, 3));
|
||||
}
|
||||
|
||||
Vector4 Matrix4::transform(const Vector4 &vector) const {
|
||||
return Vector4(
|
||||
vector.getX() * get(0, 0) + vector.getY() * get(0, 1) + vector.getZ() * get(0, 2) + vector.getW() * get(0, 3),
|
||||
vector.getX() * get(1, 0) + vector.getY() * get(1, 1) + vector.getZ() * get(1, 2) + vector.getW() * get(1, 3),
|
||||
vector.getX() * get(2, 0) + vector.getY() * get(2, 1) + vector.getZ() * get(2, 2) + vector.getW() * get(2, 3),
|
||||
vector.getX() * get(3, 0) + vector.getY() * get(3, 1) + vector.getZ() * get(3, 2) + vector.getW() * get(3, 3));
|
||||
}
|
||||
|
||||
bool Matrix4::IsIdentity() const {
|
||||
//NOTE: This might need to be implemented in a fault-tolerant way.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@ -242,4 +289,10 @@ bool Matrix4::IsIdentity() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Matrix4::invert()
|
||||
{
|
||||
Matrix4 source = *this;
|
||||
Matrix_Inv((float *)this->_m, (float *)source._m, 4);
|
||||
}
|
||||
|
||||
} // end of namespace TinyGL
|
||||
|
@ -3,26 +3,30 @@
|
||||
|
||||
namespace TinyGL {
|
||||
|
||||
#define X _v[0]
|
||||
#define Y _v[1]
|
||||
#define Z _v[2]
|
||||
#define W _v[3]
|
||||
|
||||
// Matrix & Vertex
|
||||
class Vector3 {
|
||||
public:
|
||||
Vector3();
|
||||
Vector3(const Vector3 &other);
|
||||
Vector3() { }
|
||||
Vector3(float x, float y, float z);
|
||||
|
||||
float getX() const { return _v[0]; }
|
||||
float getY() const { return _v[1]; }
|
||||
float getZ() const { return _v[2]; }
|
||||
//float getX() const { return _v[0]; }
|
||||
//float getY() const { return _v[1]; }
|
||||
//float getZ() const { return _v[2]; }
|
||||
|
||||
void setX(float val) { _v[0] = val; }
|
||||
void setY(float val) { _v[1] = val; }
|
||||
void setZ(float val) { _v[2] = val; }
|
||||
//void setX(float val) { _v[0] = val; }
|
||||
//void setY(float val) { _v[1] = val; }
|
||||
//void setZ(float val) { _v[2] = val; }
|
||||
|
||||
void normalize();
|
||||
|
||||
inline float getLength() const { return sqrt(_v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2]); }
|
||||
float getLength() const { return sqrt(_v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2]); }
|
||||
|
||||
inline static float dot(const Vector3 &a, const Vector3 &b) {
|
||||
static float dot(const Vector3 &a, const Vector3 &b) {
|
||||
return a._v[0] * b._v[0] + a._v[1] * b._v[1] + a._v[2] * b._v[2];
|
||||
}
|
||||
|
||||
@ -34,11 +38,6 @@ public:
|
||||
return _v[0] != other._v[0] || _v[1] != other._v[1] || _v[2] != other._v[2];
|
||||
}
|
||||
|
||||
Vector3 &operator=(const Vector3 &other) {
|
||||
memcpy(_v,other._v,sizeof(_v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector3 operator-() const {
|
||||
return Vector3(-_v[0],-_v[1],-_v[2]);
|
||||
}
|
||||
@ -75,21 +74,16 @@ public:
|
||||
_v[2] -= value;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
|
||||
float _v[3];
|
||||
};
|
||||
|
||||
class Vector4 {
|
||||
public:
|
||||
Vector4();
|
||||
Vector4() { }
|
||||
Vector4(const Vector3 &vec, float w);
|
||||
Vector4(float x, float y, float z, float w);
|
||||
|
||||
Vector4 &operator=(const Vector4 &other) {
|
||||
memcpy(_v,other._v,sizeof(_v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vector4 &other) const {
|
||||
return _v[0] == other._v[0] && _v[1] == other._v[1] && _v[2] == other._v[2] && _v[3] == other._v[3];
|
||||
}
|
||||
@ -142,33 +136,26 @@ public:
|
||||
return Vector3(_v[0],_v[1],_v[2]);
|
||||
}
|
||||
|
||||
float getX() const { return _v[0]; }
|
||||
float getY() const { return _v[1]; }
|
||||
float getZ() const { return _v[2]; }
|
||||
float getW() const { return _v[3]; }
|
||||
//float getX() const { return _v[0]; }
|
||||
//float getY() const { return _v[1]; }
|
||||
//float getZ() const { return _v[2]; }
|
||||
//float getW() const { return _v[3]; }
|
||||
|
||||
void setX(float val) { _v[0] = val; }
|
||||
void setY(float val) { _v[1] = val; }
|
||||
void setZ(float val) { _v[2] = val; }
|
||||
void setW(float val) { _v[3] = val; }
|
||||
//void setX(float val) { _v[0] = val; }
|
||||
//void setY(float val) { _v[1] = val; }
|
||||
//void setZ(float val) { _v[2] = val; }
|
||||
//void setW(float val) { _v[3] = val; }
|
||||
|
||||
private:
|
||||
float _v[4];
|
||||
};
|
||||
|
||||
class Matrix4 {
|
||||
public:
|
||||
Matrix4();
|
||||
Matrix4(const Matrix4 &other);
|
||||
Matrix4() { }
|
||||
|
||||
bool IsIdentity() const;
|
||||
|
||||
Matrix4 &operator=(const Matrix4 &other) {
|
||||
memcpy(_m,other._m,sizeof(_m));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix4 operator+(const Matrix4 &b) const {
|
||||
inline Matrix4 operator+(const Matrix4 &b) const {
|
||||
Matrix4 result;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
@ -178,7 +165,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4 operator-(const Matrix4 &b) const {
|
||||
inline Matrix4 operator-(const Matrix4 &b) const {
|
||||
Matrix4 result;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
@ -188,12 +175,11 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4 operator*(const Matrix4 &b) const {
|
||||
inline Matrix4 operator*(const Matrix4 &b) const {
|
||||
Matrix4 result;
|
||||
float s;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
s = 0.0;
|
||||
float s = 0.0;
|
||||
for (int k = 0; k < 4; k++)
|
||||
s += this->get(i,k) * b.get(k,j);
|
||||
result.set(i,j,s);
|
||||
@ -202,8 +188,17 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4 &operator*=(const Matrix4 &b) {
|
||||
*this = *this * b;
|
||||
inline Matrix4 &operator*=(const Matrix4 &b) {
|
||||
Matrix4 a = *this;
|
||||
float s;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
s = 0.0;
|
||||
for (int k = 0; k < 4; k++)
|
||||
s += a.get(i,k) * b.get(k,j);
|
||||
this->set(i,j,s);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -226,14 +221,45 @@ public:
|
||||
return _m[x][y];
|
||||
}
|
||||
|
||||
void invert();
|
||||
void transpose();
|
||||
|
||||
Matrix4 transpose() const;
|
||||
Matrix4 inverseOrtho() const;
|
||||
Matrix4 inverse() const;
|
||||
|
||||
Vector3 transform(const Vector3 &vector) const;
|
||||
Vector3 transform3x3(const Vector3 &vector) const; // Transform the vector as if this were a 3x3 matrix.
|
||||
Vector4 transform3x4(const Vector4 &vector) const; // Transform the vector as if this were a 3x4 matrix.
|
||||
Vector4 transform(const Vector4 &vector) const;
|
||||
inline Vector3 transform(const Vector3 &vector) const {
|
||||
return Vector3(
|
||||
vector.X * _m[0][0] + vector.Y * _m[0][1] + vector.Z * _m[0][2] + _m[0][3],
|
||||
vector.X * _m[1][0] + vector.Y * _m[1][1] + vector.Z * _m[1][2] + _m[1][3],
|
||||
vector.X * _m[2][0] + vector.Y * _m[2][1] + vector.Z * _m[2][2] + _m[2][3]);
|
||||
}
|
||||
|
||||
// Transform the vector as if this were a 3x3 matrix.
|
||||
inline Vector3 transform3x3(const Vector3 &vector) const {
|
||||
return Vector3(
|
||||
vector.X * _m[0][0] + vector.Y * _m[0][1] + vector.Z * _m[0][2],
|
||||
vector.X * _m[1][0] + vector.Y * _m[1][1] + vector.Z * _m[1][2],
|
||||
vector.X * _m[2][0] + vector.Y * _m[2][1] + vector.Z * _m[2][2]);
|
||||
}
|
||||
|
||||
// Transform the vector as if this were a 3x4 matrix.
|
||||
inline Vector4 transform3x4(const Vector4 &vector) const {
|
||||
return Vector4(
|
||||
vector.X * _m[0][0] + vector.Y * _m[0][1] + vector.Z * _m[0][2] + _m[0][3],
|
||||
vector.X * _m[1][0] + vector.Y * _m[1][1] + vector.Z * _m[1][2] + _m[1][3],
|
||||
vector.X * _m[2][0] + vector.Y * _m[2][1] + vector.Z * _m[2][2] + _m[2][3],
|
||||
vector.X * _m[3][0] + vector.Y * _m[3][1] + vector.Z * _m[3][2] + _m[3][3]);
|
||||
}
|
||||
|
||||
inline Vector4 transform(const Vector4 &vector) const {
|
||||
return Vector4(
|
||||
vector.X * _m[0][0] + vector.Y * _m[0][1] + vector.Z * _m[0][2] + vector.W * _m[0][3],
|
||||
vector.X * _m[1][0] + vector.Y * _m[1][1] + vector.Z * _m[1][2] + vector.W * _m[1][3],
|
||||
vector.X * _m[2][0] + vector.Y * _m[2][1] + vector.Z * _m[2][2] + vector.W * _m[2][3],
|
||||
vector.X * _m[3][0] + vector.Y * _m[3][1] + vector.Z * _m[3][2] + vector.W * _m[3][3]);
|
||||
}
|
||||
|
||||
private:
|
||||
float _m[4][4];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user