📄 q_shared.c
字号:
o = value;
while (*s != '\\' && *s)
{
if (!*s)
return;
*o++ = *s++;
}
*o = 0;
if (!strcmp (key, pkey) )
{
strcpy (start, s); // remove this part
return;
}
if (!*s)
return;
}
}
/*
==================
Info_Validate
Some characters are illegal in info strings because they
can mess up the server's parsing
==================
*/
#ifdef SIN
qboolean Info_Validate (const char *s)
#else
qboolean Info_Validate (char *s)
#endif
{
if (strstr (s, "\""))
return false;
if (strstr (s, ";"))
return false;
return true;
}
#ifdef SIN
void Info_SetValueForKey (char *s, const char *key, const char *value)
#else
void Info_SetValueForKey (char *s, char *key, char *value)
#endif
{
char newi[MAX_INFO_STRING], *v;
int c;
int maxsize = MAX_INFO_STRING;
if (strstr (key, "\\") || strstr (value, "\\") )
{
Com_Printf ("Can't use keys or values with a \\\n");
return;
}
if (strstr (key, ";") )
{
Com_Printf ("Can't use keys or values with a semicolon\n");
return;
}
if (strstr (key, "\"") || strstr (value, "\"") )
{
Com_Printf ("Can't use keys or values with a \"\n");
return;
}
if (strlen(key) > MAX_INFO_KEY-1 || strlen(value) > MAX_INFO_KEY-1)
{
Com_Printf ("Keys and values must be < 64 characters.\n");
return;
}
Info_RemoveKey (s, key);
if (!value || !strlen(value))
return;
Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value);
if (strlen(newi) + strlen(s) > maxsize)
{
Com_Printf ("Info string length exceeded\n");
return;
}
// only copy ascii values
s += strlen(s);
v = newi;
while (*v)
{
c = *v++;
c &= 127; // strip high bits
if (c >= 32 && c < 127)
*s++ = c;
}
*s = 0;
}
//====================================================================
void MatrixTransformVector
(
vec3_t in,
float mat[ 3 ][ 3 ],
vec3_t out
)
{
out[ 0 ] = in[ 0 ] * mat[ 0 ][ 0 ] + in[ 1 ] * mat[ 1 ][ 0 ] + in[ 2 ] * mat[ 2 ][ 0 ];
out[ 1 ] = in[ 0 ] * mat[ 0 ][ 1 ] + in[ 1 ] * mat[ 1 ][ 1 ] + in[ 2 ] * mat[ 2 ][ 1 ];
out[ 2 ] = in[ 0 ] * mat[ 0 ][ 2 ] + in[ 1 ] * mat[ 1 ][ 2 ] + in[ 2 ] * mat[ 2 ][ 2 ];
}
void Matrix4TransformVector
(
vec3_t in,
float mat[ 4 ][ 4 ],
vec3_t out
)
{
out[ 0 ] = in[ 0 ] * mat[ 0 ][ 0 ] + in[ 1 ] * mat[ 1 ][ 0 ] + in[ 2 ] * mat[ 2 ][ 0 ] + mat[ 3 ][ 0 ];
out[ 1 ] = in[ 0 ] * mat[ 0 ][ 1 ] + in[ 1 ] * mat[ 1 ][ 1 ] + in[ 2 ] * mat[ 2 ][ 1 ] + mat[ 3 ][ 1 ];
out[ 2 ] = in[ 0 ] * mat[ 0 ][ 2 ] + in[ 1 ] * mat[ 1 ][ 2 ] + in[ 2 ] * mat[ 2 ][ 2 ] + mat[ 3 ][ 2 ];
}
void VectorsToEulerAngles
(
vec3_t forward,
vec3_t right,
vec3_t up,
vec3_t ang
)
{
double theta;
double cp;
double sp;
sp = forward[ 2 ];
// cap off our sin value so that we don't get any NANs
if ( sp > 1.0 )
{
sp = 1.0;
}
if ( sp < -1.0 )
{
sp = -1.0;
}
theta = -asin( sp );
cp = cos( theta );
if ( cp > 8192 * FLT_EPSILON )
{
ang[ 0 ] = theta * 180 / M_PI;
ang[ 1 ] = atan2( forward[ 1 ], forward[ 0 ] ) * 180 / M_PI;
ang[ 2 ] = atan2( -right[ 2 ], up[ 2 ] ) * 180 / M_PI;
}
else
{
ang[ 0 ] = theta * 180 / M_PI;
ang[ 1 ] = -atan2( right[ 0 ], right[ 1 ] ) * 180 / M_PI;
ang[ 2 ] = 0;
}
}
void MatrixToEulerAngles
(
float mat[ 3 ][ 3 ],
vec3_t ang
)
{
double theta;
double cp;
double sp;
sp = mat[ 0 ][ 2 ];
// cap off our sin value so that we don't get any NANs
if ( sp > 1.0 )
{
sp = 1.0;
}
if ( sp < -1.0 )
{
sp = -1.0;
}
theta = -asin( sp );
cp = cos( theta );
if ( cp > 8192 * FLT_EPSILON )
{
ang[ 0 ] = theta * 180 / M_PI;
ang[ 1 ] = atan2( mat[ 0 ][ 1 ], mat[ 0 ][ 0 ] ) * 180 / M_PI;
ang[ 2 ] = atan2( mat[ 1 ][ 2 ], mat[ 2 ][ 2 ] ) * 180 / M_PI;
}
else
{
ang[ 0 ] = theta * 180 / M_PI;
ang[ 1 ] = -atan2( mat[ 1 ][ 0 ], mat[ 1 ][ 1 ] ) * 180 / M_PI;
ang[ 2 ] = 0;
}
}
void TransposeMatrix
(
float in[ 3 ][ 3 ],
float out[ 3 ][ 3 ]
)
{
out[ 0 ][ 0 ] = in[ 0 ][ 0 ];
out[ 0 ][ 1 ] = in[ 1 ][ 0 ];
out[ 0 ][ 2 ] = in[ 2 ][ 0 ];
out[ 1 ][ 0 ] = in[ 0 ][ 1 ];
out[ 1 ][ 1 ] = in[ 1 ][ 1 ];
out[ 1 ][ 2 ] = in[ 2 ][ 1 ];
out[ 2 ][ 0 ] = in[ 0 ][ 2 ];
out[ 2 ][ 1 ] = in[ 1 ][ 2 ];
out[ 2 ][ 2 ] = in[ 2 ][ 2 ];
}
void OrthoNormalize
(
float mat[3][3]
)
{
VectorNormalize( mat[ 0 ] );
CrossProduct( mat[ 0 ], mat[ 1 ], mat[ 2 ] );
VectorNormalize( mat[ 2 ] );
CrossProduct( mat[ 2 ], mat[ 0 ], mat[ 1 ] );
VectorNormalize( mat[ 1 ] );
}
float NormalizeQuat
(
float q[ 4 ]
)
{
float length, ilength;
length = q[ 0 ] * q[ 0 ] + q[ 1 ] * q[ 1 ] + q[ 2 ] * q[ 2 ] + q[ 3 ] * q[ 3 ];
length = sqrt( length );
if ( length )
{
ilength = 1 / length;
q[ 0 ] *= ilength;
q[ 1 ] *= ilength;
q[ 2 ] *= ilength;
q[ 3 ] *= ilength;
}
return length;
}
void MatToQuat
(
float srcMatrix[ 3 ][ 3 ],
float destQuat[ 4 ]
)
{
double trace, s;
int i, j, k;
static int next[3] = {Y, Z, X};
trace = srcMatrix[X][X] + srcMatrix[Y][Y]+ srcMatrix[Z][Z];
if (trace > 0.0)
{
s = sqrt(trace + 1.0);
destQuat[W] = s * 0.5;
s = 0.5 / s;
destQuat[X] = (srcMatrix[Z][Y] - srcMatrix[Y][Z]) * s;
destQuat[Y] = (srcMatrix[X][Z] - srcMatrix[Z][X]) * s;
destQuat[Z] = (srcMatrix[Y][X] - srcMatrix[X][Y]) * s;
}
else
{
i = X;
if (srcMatrix[Y][Y] > srcMatrix[X][X])
i = Y;
if (srcMatrix[Z][Z] > srcMatrix[i][i])
i = Z;
j = next[i];
k = next[j];
s = sqrt( (srcMatrix[i][i] - (srcMatrix[j][j]+srcMatrix[k][k])) + 1.0 );
destQuat[i] = s * 0.5;
s = 0.5 / s;
destQuat[W] = (srcMatrix[k][j] - srcMatrix[j][k]) * s;
destQuat[j] = (srcMatrix[j][i] + srcMatrix[i][j]) * s;
destQuat[k] = (srcMatrix[k][i] + srcMatrix[i][k]) * s;
}
}
void AnglesToMat
(
float ang[ 3 ],
float mat[ 3 ][ 3 ]
)
{
AngleVectors( ang, mat[ 0 ], mat[ 1 ], mat[ 2 ] );
VectorNegate( mat[ 1 ], mat[ 1 ] );
}
void RotateAxis
(
float axis[ 3 ],
float angle,
float q[ 4 ]
)
{
float sin_a;
float inv_sin_a;
float cos_a;
float r;
r = angle * M_PI / 360;
sin_a = sin( r );
if ( fabs( sin_a ) > 0.00000001 )
{
inv_sin_a = 1 / sin_a;
}
else
{
inv_sin_a = 0;
}
cos_a = cos( r );
q[ X ] = axis[ 0 ] * inv_sin_a;
q[ Y ] = axis[ 1 ] * inv_sin_a;
q[ Z ] = axis[ 2 ] * inv_sin_a;
q[ W ] = cos_a;
}
void MultQuat
(
float q1[ 4 ],
float q2[ 4 ],
float out[ 4 ]
)
{
out[ 0 ] = q1[X]*q2[X] - q1[Y]*q2[Y] - q1[Z]*q2[Z] - q1[W]*q2[W];
out[ 1 ] = q1[X]*q2[Y] + q1[Y]*q2[X] + q1[Z]*q2[W] - q1[W]*q2[Z];
out[ 2 ] = q1[X]*q2[Z] - q1[Y]*q2[W] + q1[Z]*q2[X] + q1[W]*q2[Y];
out[ 3 ] = q1[X]*q2[W] + q1[Y]*q2[Z] - q1[Z]*q2[Y] + q1[W]*q2[X];
}
void QuatToMat
(
float q[ 4 ],
float m[ 3 ][ 3 ]
)
{
float wx, wy, wz;
float xx, yy, yz;
float xy, xz, zz;
float x2, y2, z2;
x2 = q[ X ] + q[ X ];
y2 = q[ Y ] + q[ Y ];
z2 = q[ Z ] + q[ Z ];
xx = q[ X ] * x2;
xy = q[ X ] * y2;
xz = q[ X ] * z2;
yy = q[ Y ] * y2;
yz = q[ Y ] * z2;
zz = q[ Z ] * z2;
wx = q[ W ] * x2;
wy = q[ W ] * y2;
wz = q[ W ] * z2;
m[ 0 ][ 0 ] = 1.0 - ( yy + zz );
m[ 0 ][ 1 ] = xy - wz;
m[ 0 ][ 2 ] = xz + wy;
m[ 1 ][ 0 ] = xy + wz;
m[ 1 ][ 1 ] = 1.0 - ( xx + zz );
m[ 1 ][ 2 ] = yz - wx;
m[ 2 ][ 0 ] = xz - wy;
m[ 2 ][ 1 ] = yz + wx;
m[ 2 ][ 2 ] = 1.0 - ( xx + yy );
}
#define DELTA 1e-6
void SlerpQuaternion
(
float from[ 4 ],
float to[ 4 ],
float t,
float res[ 4 ]
)
{
float to1[ 4 ];
double omega, cosom, sinom, scale0, scale1;
cosom = from[ X ] * to[ X ] + from[ Y ] * to[ Y ] + from[ Z ] * to[ Z ] + from[ W ] * to [ W ];
if ( cosom < 0.0 )
{
cosom = -cosom;
to1[ X ] = -to[ X ];
to1[ Y ] = -to[ Y ];
to1[ Z ] = -to[ Z ];
to1[ W ] = -to[ W ];
}
else if
(
( from[ X ] == to[ X ] ) &&
( from[ Y ] == to[ Y ] ) &&
( from[ Z ] == to[ Z ] ) &&
( from[ W ] == to[ W ] )
)
{
// equal case, early exit
res[ X ] = to[ X ];
res[ Y ] = to[ Y ];
res[ Z ] = to[ Z ];
res[ W ] = to[ W ];
return;
}
else
{
to1[ X ] = to[ X ];
to1[ Y ] = to[ Y ];
to1[ Z ] = to[ Z ];
to1[ W ] = to[ W ];
}
if ( ( 1.0 - cosom ) > DELTA )
{
omega = acos( cosom );
sinom = sin( omega );
scale0 = sin( ( 1.0 - t ) * omega ) / sinom;
scale1 = sin( t * omega ) / sinom;
}
else
{
scale0 = 1.0 - t;
scale1 = t;
}
res[ X ] = scale0 * from[ X ] + scale1 * to1[ X ];
res[ Y ] = scale0 * from[ Y ] + scale1 * to1[ Y ];
res[ Z ] = scale0 * from[ Z ] + scale1 * to1[ Z ];
res[ W ] = scale0 * from[ W ] + scale1 * to1[ W ];
}
#if 0
void EulerToQuat
(
float ang[ 3 ],
float q[ 4 ]
)
{
float cr, cp, cy;
float sr, sp, sy;
float cpcy, spsy;
float spcy, cpsy;
float r;
r = M_PI / 360;
// calculate trig identities
cr = cos( -ang[ ROLL ] * r );
cp = cos( -ang[ PITCH ] * r );
cy = cos( -ang[ YAW ] * r );
sr = sin( -ang[ ROLL ] * r );
sp = sin( -ang[ PITCH ] * r );
sy = sin( -ang[ YAW ] * r );
cpcy = cp * cy;
spsy = sp * sy;
spcy = sp * cy;
cpsy = cp * sy;
q[ W ] = cr * cpcy + sr * spsy;
q[ X ] = sr * cpcy - cr * spsy;
q[ Y ] = cr * spcy + sr * cpsy;
q[ Z ] = cr * cpsy - sr * spcy;
}
#endif
#if 0
float x_axis[ 3 ] = { 1, 0, 0 };
float y_axis[ 3 ] = { 0, 1, 0 };
float z_axis[ 3 ] = { 0, 0, 1 };
void EulerToQuat
(
float ang[ 3 ],
float q[ 4 ]
)
{
float qx[ 4 ];
float qy[ 4 ];
float qz[ 4 ];
RotateAxis( x_axis, ang[ 0 ], qx );
RotateAxis( y_axis, ang[ 1 ], qy );
RotateAxis( z_axis, ang[ 2 ], qz );
//MultQuat( qx, qy, q );
//MultQuat( qz, q, q );
NormalizeQuat( q );
RotateAxis( y_axis, ang[ 0 ], q );
NormalizeQuat( q );
}
#endif
#if 0
#define EulFrmS 0
#define EulFrmR 1
#define EulFrm(ord) ( ( unsigned )( ord ) & 1 )
#define EulRepNo 0
#define EulRepYes 1
#define EulRep(ord) ( ( ( unsigned )( ord ) >> 1 ) & 1 )
#define EulParEven 0
#define EulParOdd 1
#define EulPar(ord) ( ( ( unsigned )( ord ) >> 2 ) & 1 )
#define EulSafe "\000\001\002\000"
#define EulNext "\001\002\000\001"
#define EulGetOrd( ord, i, j, k, h, n, s, f ) \
{ \
unsigned o = ord; \
\
f = o & 1; \
o >>=1; \
s = o & 1; \
o >>= 1; \
n = o & 1; \
o >>= 1; \
i = EulSafe[ o & 3 ]; \
j = EulNext[ i + n ]; \
k = EulNext[ i + 1 - n ]; \
h = s ? k : i; \
}
#define EulOrd( i, p, r, f ) (((((((i)<<1)+(p))<<1)+(r))<<1)+(f))
void EulFromMatrix
(
float m[ 3 ][ 3 ],
vec3_t ea
)
{
int i, j, k, h, n, s, f;
int order;
order = EulOrd( X, EulParOdd, EulRepYES, EulFrmS );
EulGetOrd( order, i, j, k, h, n, s, f );
if ( s == EulRepYes )
{
double sy;
sy = sqrt( m[ i ][ j ] * m[ i ][ j ] + m[ i ][ k ] * m[ i ][ k ] );
if ( sy > 16 * FLT_EPSILON )
{
ea[ 0 ] = atan2( m[ i ][ j ], m[ i ][ k ] );
ea[ 1 ] = atan2( sy, m[ i ][ i ] );
ea[ 2 ] = atan2( m[ j ][ i ], -m[ k ][ i ] );
}
else
{
ea[ 0 ] = atan2( -m[ j ][ k ], m[ j ][ j ] );
ea[ 1 ] = atan2( sy, m[ i ][ i ] );
ea[ 2 ] = 0;
}
}
else
{
double cy;
cy = sqrt( m[ i ][ i ] * m[ i ][ i ] + m[ j ][ i ] * m[ j ][ i ] );
if ( cy > 16 * FLT_EPSILON )
{
ea[ 0 ] = atan2( m[ k ][ j ], m[ k ][ k ] );
ea[ 1 ] = atan2( -m[ k ][ i ], cy );
ea[ 2 ] = atan2( m[ j ][ i ], m[ i ][ i ] );
}
else
{
ea[ 0 ] = atan2( -m[ j ][ k ], m[ j ][ j ] );
ea[ 1 ] = atan2( -m[ k ][ i ], cy );
ea[ 2 ] = 0;
}
}
if ( n == EulParOdd )
{
ea[ 0 ] = -ea[ 0 ];
ea[ 1 ] = -ea[ 1 ];
ea[ 2 ] = -ea[ 2 ];
}
if ( f = EulFrmR )
{
float t;
t = ea[ 0 ];
ea[ 0 ] = ea[ 2 ];
ea[ 2 ] = t;
}
ea[ 0 ] *= 180 / M_PI;
ea[ 1 ] *= 180 / M_PI;
ea[ 2 ] *= 180 / M_PI;
}
void EulerToQuat
(
float angles[ 3 ],
float q[ 4 ]
)
{
float ang[ 3 ];
float ti, tj, th;
float ci, cj, ch;
float si, sj, sh;
float cc, cs, sc, ss;
float r;
int i, j, k, h, n, s, f, w;
//w = EulOrd( X, EulParOdd, EulRepNo, EulFrmR );
//w = EulOrd( Y, EulParOdd, EulRepNo, EulFrmR );
w = EulOrd( Z, EulParOdd, EulRepNo, EulFrmR );
//w = EulOrd( Z, EulParOdd, EulRepNo, EulFrmS );
EulGetOrd( w, i, j, k, h, n, s, f );
ang[ 0 ] = angles[ 0 ];
ang[ 1 ] = angles[ 1 ];
ang[ 2 ] = angles[ 2 ];
if ( f == EulFrmR )
{
float t;
t = ang[ X ];
ang[ X ] = ang[ Z ];
ang[ Z ] = t;
}
if ( n == EulParOdd )
{
ang[ Y ] = -ang[ Y ];
}
r = M_PI / 360;
ti = ang[ 0 ] * r;
tj = ang[ 1 ] * r;
th = ang[ 2 ] * r;
ci = cos( ti ); cj = cos( tj ); ch = cos( th );
si = sin( ti ); sj = sin( tj ); sh = sin( th );
cc = ci * ch; cs = ci * sh; sc = si * sh; ss = si * sh;
if ( s == EulRepYes )
{
q[ X ] = cj * ( cs + sc );
q[ Y ] = cj * ( cc + ss );
q[ Z ] = cj * ( cs - sc );
q[ W ] = cj * ( cc - ss );
}
else
{
q[ X ] = cj * sc - sj * cs;
q[ Y ] = cj * ss + sj * cc;
q[ Z ] = cj * cs - sj * sc;
q[ W ] = cj * cc + sj * ss;
}
if ( n == EulParOdd )
{
q[ j ] = -q[ j ];
}
NormalizeQuat( q );
}
#endif
#if 1
void EulerToQuat
(
float ang[ 3 ],
float q[ 4 ]
)
{
float mat[ 3 ][ 3 ];
AnglesToMat( ang, mat );
MatToQuat( mat, q );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -