I reached a point where I need to mess with matrices a little more than we were able to, so I started writing this module in order to throw it at garry and tell him to add it.
[B]THIS DOES ONLY WORK FOR GM13, I'M NOT GONNA COMPILE FOR GM12![/B]
List of functions:
[code]
VMatrix/Vector __add(VMatrix lhs, VMatrix/Vector rhs)
boolean __eq(VMatrix lhs, VMatrix rhs)
VMatrix __mul(VMatrix lhs, VMatrix rhs)
VMatrix __sub(VMatrix lhs, VMatrix rhs)
VMatrix __unm(VMatrix mat)
string __tostring(VMatrix mat)//Format: "[%.5f,\t%.5f,\t%.5f,\t%.5f]\n[%.5f,\t%.5f,\t%.5f,\t%.5f]\n[%.5f,\t%.5f,\t%.5f,\t%.5f]\n[%.5f,\t%.5f,\t%.5f,\t%.5f]",
VMatrix:Inverse()
VMatrix VMatrix:GetInverse()
boolean VMatrix:IsRotationMatrix()
boolean VMatrix:IsIdentity()
VMatrix:Identity()
VMatrix:Transpose()
VMatrix VMatrix:GetTranspose()
Vector VMatrix:GetForward()
Vector VMatrix:GetLeft()
Vector VMatrix:GetUp()
VMatrix:SetForward(Vector forw)
VMatrix:SetLeft(Vector left)
VMatrix:SetUp(Vector up)
VMatrix:Set(VMatrix source)--copy value from argument to self
VMatrix VMatrix:Copy()--returns a copy
VMatrix:SetField(int row, int column, double value)
double VMatrix:GetField(int row, int column)
table VMatrix:ToTable()--returns 2 dimensional table, see sample
VMatrix:FromTable(table)
[/code]
Testcode:
[lua]
require("matrix")
local m1 = Matrix()
local m2 = Matrix()
m1:Translate(Vector(1, 2, 3))
m2:Translate(Vector(10, 20, 30))
MsgN("Addition:\n", m1+m2)
MsgN("Multiplication:\n", m1*m2)
MsgN("Subtraction:\n", m1-m2)
MsgN("Equal:\n", m1 == m2)
MsgN("Negation:\n", -m1)
m1:SetField(1, 1, 23.3)
MsgN("G/SetField:\n", m1:GetField(1, 1))
m1:SetForward(Vector(1, 2, 3))
MsgN("G/SetForward:\n", m1:GetForward())
m1:SetLeft(Vector(10, 20, 30))
MsgN("G/SetLeft:\n", m1:GetLeft())
m1:SetUp(Vector(100, 200, 300))
MsgN("G/SetUp:\n", m1:GetUp())
m1:Set(m2)
MsgN("Set:\n", m1)
MsgN("Copy:\n", m1:Copy())
Msg("From/To Table:\n")
m1:FromTable(--broken
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
}
)
PrintTable(m1:ToTable())
[/lua]
[del]mat:FromTable is currently broken due to lack of functionality of garrys new interface.[/del] works now
[url=http://filesmelt.com/dl/gmsv_matrix2.dll]Binary Download[/url]
Source(Using BlackOps wrapper):
[code]
#include "ILuaModuleManager.h"
#include "mathlib\vmatrix.h"
#include "mathlib\vector.h"
GMOD_MODULE( Open, Close );
ILuaInterface* gLua = NULL;
ILuaObject* vectorMeta,* matrixMeta;
LUA_FUNCTION( lMatrix__add ) {
gLua->CheckType(1, Type::MATRIX);
gLua->CheckType(2, Type::MATRIX);
VMatrix* lhs = (VMatrix*)gLua->GetUserData(1);
VMatrix* rhs = (VMatrix*)gLua->GetUserData(2);
VMatrix* result = new VMatrix(*lhs+*rhs);
gLua->PushUserData(matrixMeta, result);
return 1;
}
LUA_FUNCTION( lMatrix__mul ) {
gLua->CheckType(1, Type::MATRIX);
int type = gLua->GetType(2);
switch(type) {
case Type::VECTOR: {
VMatrix* lhs = (VMatrix*)gLua->GetUserData(1);
Vector* rhs = (Vector*)gLua->GetUserData(2);
Vector* result = new Vector(*lhs**rhs);
gLua->PushUserData(vectorMeta, result);
return 1;
}
case Type::MATRIX: {
VMatrix* lhs = (VMatrix*)gLua->GetUserData(1);
VMatrix* rhs = (VMatrix*)gLua->GetUserData(2);
VMatrix* result = new VMatrix(*lhs**rhs);
gLua->PushUserData(matrixMeta, result);
return 1;
}
}
char err[80];
sprintf(err, "Invalid object to #2, (Vector or Matrix expected got %s)", gLua->GetTypeName(type));
gLua->Error(err);
return 0;
}
LUA_FUNCTION( lMatrix__sub ) {
gLua->CheckType(1, Type::MATRIX);
gLua->CheckType(2, Type::MATRIX);
VMatrix* lhs = (VMatrix*)gLua->GetUserData(1);
VMatrix* rhs = (VMatrix*)gLua->GetUserData(2);
VMatrix* result = new VMatrix(*lhs-*rhs);
gLua->PushUserData(matrixMeta, result);
return 1;
}
LUA_FUNCTION( lMatrix__eq ) {
gLua->CheckType(1, Type::MATRIX);
if(gLua->GetType(2) == Type::MATRIX) {
VMatrix* lhs = (VMatrix*)gLua->GetUserData(1);
VMatrix* rhs = (VMatrix*)gLua->GetUserData(2);
gLua->Push(*lhs == *rhs);
return 1;
}
gLua->Push(false);
return 1;
}
LUA_FUNCTION( lMatrix__unm ) {
gLua->CheckType(1, Type::MATRIX);
VMatrix* lhs = (VMatrix*)gLua->GetUserData(1);
VMatrix* result = new VMatrix(-*lhs);
gLua->PushUserData(matrixMeta, result);
return 1;
}
LUA_FUNCTION( lMatrix__tostring ) {
gLua->CheckType(1, Type::MATRIX);
VMatrix* mat = (VMatrix*)gLua->GetUserData(1);
vec_t(*vec_tMat)[4] = mat->m;
char ret[256];
sprintf(
ret,
"[%.5f,\t%.5f,\t%.5f,\t%.5f]\n[%.5f,\t%.5f,\t%.5f,\t%.5f]\n[%.5f,\t%.5f,\t%.5f,\t%.5f]\n[%.5f,\t%.5f,\t%.5f,\t%.5f]",
vec_tMat[0][0],
vec_tMat[0][1],
vec_tMat[0][2],
vec_tMat[0][3],
vec_tMat[1][0],
vec_tMat[1][1],
vec_tMat[1][2],
vec_tMat[1][3],
vec_tMat[2][0],
vec_tMat[2][1],
vec_tMat[2][2],
vec_tMat[2][3],
vec_tMat[3][0],
vec_tMat[3][1],
vec_tMat[3][2],
vec_tMat[3][3]
);
gLua->Push(ret);
return 1;
}
LUA_FUNCTION( lMatrixInverse ) {
gLua->CheckType(1, Type::MATRIX);
VMatrix* temp = ((VMatrix*)(gLua->GetUserData(1)));
gLua->Push(temp->InverseGeneral(*temp));
return 1;
}
LUA_FUNCTION( lMatrixGetInverse ) {
gLua->CheckType(1, Type::MATRIX);
VMatrix* retMat = new VMatrix();
if(!((VMatrix*)(gLua->GetUserData(1)))->InverseGeneral(*retMat)) {
gLua->PushNil();
return 1;
}
gLua->PushUserData(matrixMeta, retMat);
return 1;
}
LUA_FUNCTION( lMatrixIsRotationMatrix ) {
gLua->CheckType(1, Type::MATRIX);
((VMatrix*)(gLua->GetUserData(1)))->IsRotationMatrix();
return 0;
}
LUA_FUNCTION( lMatrixIsIdentity ) {
gLua->CheckType(1, Type::MATRIX);
gLua->Push(((VMatrix*)(gLua->GetUserData(1)))->IsIdentity());
return 1;
}
LUA_FUNCTION( lMatrixIdentity ) {
gLua->CheckType(1, Type::MATRIX);
((VMatrix*)(gLua->GetUserData(1)))->Identity();
return 0;
}
LUA_FUNCTION( lMatrixTranspose ) {
gLua->CheckType(1, Type::MATRIX);
VMatrix* temp = ((VMatrix*)(gLua->GetUserData(1)));
MatrixTranspose(*temp, *temp);
return 0;
}
LUA_FUNCTION( lMatrixGetTranspose ) {
gLua->CheckType(1, Type::MATRIX);
VMatrix* retMat = new VMatrix();
MatrixTranspose(*((VMatrix*)(gLua->GetUserData(1))), *retMat);
gLua->PushUserData(matrixMeta, retMat);
return 1;
}
LUA_FUNCTION( lMatrixGetField ) {
gLua->CheckType(1, Type::MATRIX);
gLua->CheckType(2, Type::NUMBER);
gLua->CheckType(3, Type::NUMBER);
int row = gLua->GetInteger(2);
if(row > 4 || row < 1)
gLua->Error("Invalid row");
int col = gLua->GetInteger(3);
if(col > 4 || col < 1)
gLua->Error("Invalid column");
VMatrix* mat = (VMatrix*)gLua->GetUserData(1);
gLua->Push(mat->m[row][col]);
return 1;
}
LUA_FUNCTION( lMatrixSetField ) {
gLua->CheckType(1, Type::MATRIX);
gLua->CheckType(2, Type::NUMBER);
gLua->CheckType(3, Type::NUMBER);
gLua->CheckType(4, Type::NUMBER);
int row = gLua->GetInteger(2);
if(row > 4 || row < 1)
gLua->Error("Invalid row");
int col = gLua->GetInteger(3);
if(col > 4 || col < 1)
gLua->Error("Invalid column");
VMatrix* mat = (VMatrix*)gLua->GetUserData(1);
mat->m[row][col] = gLua->GetFloat(4);
return 0;
}
#define createMatGetDir(dir)\
LUA_FUNCTION( lMatrixGet##dir ) {\
gLua->CheckType(1, Type::MATRIX);\
Vector* retVec = new Vector(((VMatrix*)gLua->GetUserData(1))->Get##dir ());\
gLua->PushUserData(vectorMeta, retVec);\
return 1;\
}
createMatGetDir(Forward);
createMatGetDir(Left);
createMatGetDir(Up);
#define createMatSetDir(dir)\
LUA_FUNCTION( lMatrixSet ## dir ) {\
gLua->CheckType(1, Type::MATRIX);\
gLua->CheckType(2, Type::VECTOR);\
VMatrix* mat = (VMatrix*)gLua->GetUserData(1);\
Vector* vec = (Vector*)gLua->GetUserData(2);\
mat->Set##dir(*vec);\
return 0;\
}
createMatSetDir(Forward);
createMatSetDir(Left);
createMatSetDir(Up);
LUA_FUNCTION( lMatrixSet ) {
gLua->CheckType(1, Type::MATRIX);
gLua->CheckType(2, Type::MATRIX);
MatrixCopy(*((VMatrix*)gLua->GetUserData(2)), *((VMatrix*)gLua->GetUserData(1)));
return 0;
}
LUA_FUNCTION( lMatrixCopy ) {
gLua->CheckTyp
They work perfect for me? Also useful
All numbers with more than 2 digits wrap into the line for me.
[QUOTE=Wizard of Ass;37591703]All numbers with more than 2 digits wrap into the line for me.[/QUOTE]
That happens sometimes, not every time. (to me, at least)
Updated, FromTable works now.
Updated.
Added:
Inverse
GetInverse
IsRotationMaMatrix
IsIdentity
Identity
Transpose
GetTranspose
See OP for more info.
[editline]18th September 2012[/editline]
Also changed source code container to code tags, garry broken code highlighter is pissing me off.
Another update, Ralle mentioned I manually created errors instead of type checking, hell know why I did that.
Sorry, you need to Log In to post a reply to this thread.