forked from Mirrors/openclonk
the Trans_* mesh-transformation-functions are now implemented in the Engine instead of System.ocg
parent
ad1c2760b0
commit
fb1ee2f88f
|
@ -1,71 +0,0 @@
|
|||
/*--
|
||||
MeshTransformation.c
|
||||
Authors: ck
|
||||
|
||||
Some common transformation matrices, and a function to multiply them together to produce more complex transformations.
|
||||
--*/
|
||||
|
||||
|
||||
global func Trans_Identity()
|
||||
{
|
||||
return [1000, 0, 0, 0,
|
||||
0, 1000, 0, 0,
|
||||
0, 0, 1000, 0];
|
||||
}
|
||||
|
||||
global func Trans_Translate(int dx, int dy, int dz)
|
||||
{
|
||||
return [1000, 0, 0, dx,
|
||||
0, 1000, 0, dy,
|
||||
0, 0, 1000, dz];
|
||||
}
|
||||
|
||||
global func Trans_Scale(int sx, int sy, int sz)
|
||||
{
|
||||
if (sy == nil && sz == nil)
|
||||
sz = sy = sx;
|
||||
|
||||
return [sx, 0, 0, 0,
|
||||
0, sy, 0, 0,
|
||||
0, 0, sz, 0];
|
||||
}
|
||||
|
||||
global func Trans_Rotate(int angle, int rx, int ry, int rz)
|
||||
{
|
||||
var c = Cos(angle, 1000);
|
||||
var s = Sin(angle, 1000);
|
||||
var n = Sqrt(rx*rx + ry*ry + rz*rz);
|
||||
rx = 1000 * rx / n;
|
||||
ry = 1000 * ry / n;
|
||||
rz = 1000 * rz / n;
|
||||
|
||||
// Note that 0 <= rx,ry,rz,c,s <= 1000, so we don't overflow here.
|
||||
return [
|
||||
rx*rx*(1000-c)/1000000+c, rx*ry*(1000-c)/1000000-rz*s/1000, rx*rz*(1000-c)/1000000+ry*s/1000, 0,
|
||||
ry*rx*(1000-c)/1000000+rz*s/1000, ry*ry*(1000-c)/1000000+c, ry*rz*(1000-c)/1000000-rx*s/1000, 0,
|
||||
rz*rx*(1000-c)/1000000-ry*s/1000, ry*rz*(1000-c)/1000000+rx*s/1000, rz*rz*(1000-c)/1000000+c, 0];
|
||||
}
|
||||
|
||||
global func Trans_Mul(array lhs, array rhs)
|
||||
{
|
||||
if (!rhs)
|
||||
return lhs;
|
||||
|
||||
var result = [
|
||||
lhs[0]*rhs[0]/1000 + lhs[1]*rhs[4]/1000 + lhs[ 2]*rhs[ 8]/1000,
|
||||
lhs[0]*rhs[1]/1000 + lhs[1]*rhs[5]/1000 + lhs[ 2]*rhs[ 9]/1000,
|
||||
lhs[0]*rhs[2]/1000 + lhs[1]*rhs[6]/1000 + lhs[ 2]*rhs[10]/1000,
|
||||
lhs[0]*rhs[3]/1000 + lhs[1]*rhs[7]/1000 + lhs[ 2]*rhs[11]/1000 + lhs[3],
|
||||
|
||||
lhs[4]*rhs[0]/1000 + lhs[5]*rhs[4]/1000 + lhs[ 6]*rhs[ 8]/1000,
|
||||
lhs[4]*rhs[1]/1000 + lhs[5]*rhs[5]/1000 + lhs[ 6]*rhs[ 9]/1000,
|
||||
lhs[4]*rhs[2]/1000 + lhs[5]*rhs[6]/1000 + lhs[ 6]*rhs[10]/1000,
|
||||
lhs[4]*rhs[3]/1000 + lhs[5]*rhs[7]/1000 + lhs[ 6]*rhs[11]/1000 + lhs[7],
|
||||
|
||||
lhs[8]*rhs[0]/1000 + lhs[9]*rhs[4]/1000 + lhs[10]*rhs[ 8]/1000,
|
||||
lhs[8]*rhs[1]/1000 + lhs[9]*rhs[5]/1000 + lhs[10]*rhs[ 9]/1000,
|
||||
lhs[8]*rhs[2]/1000 + lhs[9]*rhs[6]/1000 + lhs[10]*rhs[10]/1000,
|
||||
lhs[8]*rhs[3]/1000 + lhs[9]*rhs[7]/1000 + lhs[10]*rhs[11]/1000 + lhs[11] ];
|
||||
|
||||
return Trans_Mul(result, ...);
|
||||
}
|
|
@ -154,6 +154,132 @@ C4Value C4AulDefFunc::Exec(C4PropList * p, C4Value pPars[], bool fPassErrors)
|
|||
|
||||
//=============================== C4Script Functions ====================================
|
||||
|
||||
#define MAKE_AND_RETURN_ARRAY(values) do { \
|
||||
C4ValueArray *matrix = new C4ValueArray(sizeof(values) / sizeof(*values)); \
|
||||
for (long i = 0; i < sizeof(values) / sizeof(*values); ++i) \
|
||||
(*matrix)[i] = C4VInt(values[i]); \
|
||||
return matrix; \
|
||||
} while (0)
|
||||
|
||||
static C4ValueArray *FnTrans_Identity(C4PropList * _this)
|
||||
{
|
||||
long values[] =
|
||||
{
|
||||
1000, 0, 0, 0,
|
||||
0, 1000, 0, 0,
|
||||
0, 0, 1000, 0
|
||||
};
|
||||
MAKE_AND_RETURN_ARRAY(values);
|
||||
}
|
||||
|
||||
static C4ValueArray *FnTrans_Translate(C4PropList * _this, long dx, long dy, long dz)
|
||||
{
|
||||
long values[] =
|
||||
{
|
||||
1000, 0, 0, dx,
|
||||
0, 1000, 0, dy,
|
||||
0, 0, 1000, dz
|
||||
};
|
||||
MAKE_AND_RETURN_ARRAY(values);
|
||||
}
|
||||
|
||||
static C4ValueArray *FnTrans_Scale(C4PropList * _this, long sx, long sy, long sz)
|
||||
{
|
||||
if (sy == 0 && sz == 0)
|
||||
sy = sz = sx;
|
||||
long values[] =
|
||||
{
|
||||
sx, 0, 0, 0,
|
||||
0, sy, 0, 0,
|
||||
0, 0, sz, 0
|
||||
};
|
||||
MAKE_AND_RETURN_ARRAY(values);
|
||||
}
|
||||
|
||||
static C4ValueArray *FnTrans_Rotate(C4PropList * _this, long angle, long rx, long ry, long rz)
|
||||
{
|
||||
long c = fixtoi(Cos(itofix(angle, 1)), 1000);
|
||||
long s = fixtoi(Sin(itofix(angle, 1)), 1000);
|
||||
|
||||
long sqrt_val = rx * rx + ry * ry + rz * rz;
|
||||
long n = long(sqrt(double(sqrt_val)));
|
||||
if (n * n < sqrt_val) n++;
|
||||
else if (n * n > sqrt_val) n--;
|
||||
|
||||
rx = (1000 * rx) / n;
|
||||
ry = (1000 * ry) / n;
|
||||
rz = (1000 * rz) / n;
|
||||
|
||||
long values[] =
|
||||
{
|
||||
rx*rx*(1000-c)/1000000+c, rx*ry*(1000-c)/1000000-rz*s/1000, rx*rz*(1000-c)/1000000+ry*s/1000, 0,
|
||||
ry*rx*(1000-c)/1000000+rz*s/1000, ry*ry*(1000-c)/1000000+c, ry*rz*(1000-c)/1000000-rx*s/1000, 0,
|
||||
rz*rx*(1000-c)/1000000-ry*s/1000, ry*rz*(1000-c)/1000000+rx*s/1000, rz*rz*(1000-c)/1000000+c, 0
|
||||
};
|
||||
MAKE_AND_RETURN_ARRAY(values);
|
||||
}
|
||||
|
||||
static C4Value FnTrans_Mul(C4PropList * _this, C4Value *pars)
|
||||
{
|
||||
const int32_t matrixSize = 12;
|
||||
long values[] =
|
||||
{
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
// Read all parameters
|
||||
bool first = true;
|
||||
for (int32_t i = 0; i < C4AUL_MAX_Par; i++)
|
||||
{
|
||||
C4Value Data = *(pars++);
|
||||
// No data given?
|
||||
if (!Data) break;
|
||||
C4ValueArray *factorArray = Data.getArray();
|
||||
if (!factorArray || factorArray->GetSize() != matrixSize) continue;
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
|
||||
for (int32_t c = 0; c < matrixSize; ++c)
|
||||
values[c] = (*factorArray)[c].getInt();
|
||||
continue;
|
||||
}
|
||||
|
||||
// multiply current matrix with new one
|
||||
long values_rhs[matrixSize], values_result[matrixSize];
|
||||
for (int32_t c = 0; c < matrixSize; ++c)
|
||||
values_rhs[c] = (*factorArray)[c].getInt();
|
||||
|
||||
// matrix multiplication
|
||||
values_result[ 0] = values[0]*values_rhs[0]/1000 + values[1]*values_rhs[4]/1000 + values[ 2]*values_rhs[ 8]/1000;
|
||||
values_result[ 1] = values[0]*values_rhs[1]/1000 + values[1]*values_rhs[5]/1000 + values[ 2]*values_rhs[ 9]/1000;
|
||||
values_result[ 2] = values[0]*values_rhs[2]/1000 + values[1]*values_rhs[6]/1000 + values[ 2]*values_rhs[10]/1000;
|
||||
values_result[ 3] = values[0]*values_rhs[3]/1000 + values[1]*values_rhs[7]/1000 + values[ 2]*values_rhs[11]/1000 + values[3];
|
||||
values_result[ 4] = values[4]*values_rhs[0]/1000 + values[5]*values_rhs[4]/1000 + values[ 6]*values_rhs[ 8]/1000;
|
||||
values_result[ 5] = values[4]*values_rhs[1]/1000 + values[5]*values_rhs[5]/1000 + values[ 6]*values_rhs[ 9]/1000;
|
||||
values_result[ 6] = values[4]*values_rhs[2]/1000 + values[5]*values_rhs[6]/1000 + values[ 6]*values_rhs[10]/1000;
|
||||
values_result[ 7] = values[4]*values_rhs[3]/1000 + values[5]*values_rhs[7]/1000 + values[ 6]*values_rhs[11]/1000 + values[7];
|
||||
values_result[ 8] = values[8]*values_rhs[0]/1000 + values[9]*values_rhs[4]/1000 + values[10]*values_rhs[ 8]/1000;
|
||||
values_result[ 9] = values[8]*values_rhs[1]/1000 + values[9]*values_rhs[5]/1000 + values[10]*values_rhs[ 9]/1000;
|
||||
values_result[10] = values[8]*values_rhs[2]/1000 + values[9]*values_rhs[6]/1000 + values[10]*values_rhs[10]/1000;
|
||||
values_result[11] = values[8]*values_rhs[3]/1000 + values[9]*values_rhs[7]/1000 + values[10]*values_rhs[11]/1000 + values[11];
|
||||
|
||||
for (int32_t c = 0; c < matrixSize; ++c)
|
||||
values[c] = values_result[c];
|
||||
}
|
||||
|
||||
// unlike in the other Trans_*-functions, we have to put the array into a C4Value manually here
|
||||
C4ValueArray *matrix = new C4ValueArray(sizeof(values) / sizeof(*values));
|
||||
for (long i = 0; i < sizeof(values) / sizeof(*values); ++i)
|
||||
(*matrix)[i] = C4VInt(values[i]);
|
||||
return C4VArray(matrix);
|
||||
}
|
||||
|
||||
#undef MAKE_AND_RETURN_ARRAY
|
||||
|
||||
static C4PropList * FnCreatePropList(C4PropList * _this, C4PropList * prototype)
|
||||
{
|
||||
return C4PropList::New(prototype);
|
||||
|
@ -631,6 +757,7 @@ C4ScriptFnDef C4ScriptFnMap[]=
|
|||
{ "Log", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnLog },
|
||||
{ "DebugLog", 1, C4V_Bool, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnDebugLog },
|
||||
{ "Format", 1, C4V_String, { C4V_String ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnFormat },
|
||||
{ "Trans_Mul", 1, C4V_Array, { C4V_Array ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any ,C4V_Any}, FnTrans_Mul},
|
||||
|
||||
{ NULL, 0, C4V_Nil, { C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil ,C4V_Nil}, 0 }
|
||||
};
|
||||
|
@ -684,6 +811,10 @@ void InitCoreFunctionMap(C4AulScriptEngine *pEngine)
|
|||
F(SortArray);
|
||||
F(SortArrayByProperty);
|
||||
F(SortArrayByArrayElement);
|
||||
F(Trans_Identity);
|
||||
F(Trans_Translate);
|
||||
F(Trans_Scale);
|
||||
F(Trans_Rotate);
|
||||
F(LocateFunc);
|
||||
F(FileWrite);
|
||||
|
||||
|
|
Loading…
Reference in New Issue