//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============// // // Purpose: VScript functions, constants, etc. registered within the library itself. // // This is for things which don't have to depend on server/client and can be accessed // from anywhere. // // $NoKeywords: $ //=============================================================================// #include "vscript/ivscript.h" #include "tier1/tier1.h" #include <tier0/platform.h> #include "worldsize.h" #include <vstdlib/random.h> #include "vscript_bindings_math.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" //============================================================================= // // matrix3x4_t // //============================================================================= BEGIN_SCRIPTDESC_ROOT_NAMED( matrix3x4_t, "matrix3x4_t", "A 3x4 matrix transform." ) DEFINE_SCRIPT_CONSTRUCTOR() DEFINE_SCRIPTFUNC( Init, "Creates a matrix where the X axis = forward, the Y axis = left, and the Z axis = up." ) END_SCRIPTDESC(); //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ScriptConcatTransforms( HSCRIPT hMat1, HSCRIPT hMat2, HSCRIPT hOut ) { if (!hMat1 || !hMat2 || !hOut) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 ); matrix3x4_t *pOut = ToMatrix3x4( hOut ); ConcatTransforms( *pMat1, *pMat2, *pOut ); } void ScriptMatrixCopy( HSCRIPT hMat1, HSCRIPT hOut ) { if (!hMat1 || !hOut) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); matrix3x4_t *pOut = ToMatrix3x4( hOut ); MatrixCopy( *pMat1, *pOut ); } void ScriptMatrixInvert( HSCRIPT hMat1, HSCRIPT hOut ) { if (!hMat1 || !hOut) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); matrix3x4_t *pOut = ToMatrix3x4( hOut ); MatrixInvert( *pMat1, *pOut ); } void ScriptMatricesAreEqual( HSCRIPT hMat1, HSCRIPT hMat2 ) { if (!hMat1 || !hMat2) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 ); MatricesAreEqual( *pMat1, *pMat2 ); } const Vector& ScriptMatrixGetColumn( HSCRIPT hMat1, int column ) { static Vector outvec; outvec.Zero(); if (!hMat1) return outvec; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixGetColumn( *pMat1, column, outvec ); return outvec; } void ScriptMatrixSetColumn( const Vector& vecset, int column, HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixSetColumn( vecset, column, *pMat1 ); } void ScriptMatrixAngles( HSCRIPT hMat1, const QAngle& angset, const Vector& vecset ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixAngles( *pMat1, *const_cast<QAngle*>(&angset), *const_cast<Vector*>(&vecset) ); } void ScriptAngleMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); AngleMatrix( angset, vecset, *pMat1 ); } void ScriptAngleIMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); AngleIMatrix( angset, vecset, *pMat1 ); } void ScriptSetIdentityMatrix( HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); SetIdentityMatrix( *pMat1 ); } void ScriptSetScaleMatrix( float x, float y, float z, HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); SetScaleMatrix( x, y, z, *pMat1 ); } void ScriptMatrixScaleBy( float flScale, HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixScaleBy( flScale, *pMat1 ); } void ScriptMatrixScaleByZero( HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixScaleByZero( *pMat1 ); } const Vector& ScriptMatrixGetTranslation( HSCRIPT hMat1 ) { static Vector outvec; outvec.Zero(); if (!hMat1) return outvec; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixGetTranslation( *pMat1, outvec ); return outvec; } void ScriptMatrixSetTranslation( const Vector& vecset, HSCRIPT hMat1 ) { if (!hMat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); MatrixSetTranslation( vecset, *pMat1 ); } //============================================================================= // // Quaternion // //============================================================================= CScriptQuaternionInstanceHelper g_QuaternionScriptInstanceHelper; BEGIN_SCRIPTDESC_ROOT_NAMED( Quaternion, "Quaternion", "A quaternion." ) DEFINE_SCRIPT_CONSTRUCTOR() DEFINE_SCRIPT_INSTANCE_HELPER( &g_QuaternionScriptInstanceHelper ) DEFINE_SCRIPTFUNC_NAMED( ScriptInit, "Init", "Creates a quaternion with the given values." ) DEFINE_MEMBERVAR( "x", FIELD_FLOAT, "The quaternion's i axis component." ) DEFINE_MEMBERVAR( "y", FIELD_FLOAT, "The quaternion's j axis component." ) DEFINE_MEMBERVAR( "z", FIELD_FLOAT, "The quaternion's k axis component." ) DEFINE_MEMBERVAR( "w", FIELD_FLOAT, "The quaternion's scalar component." ) END_SCRIPTDESC(); //----------------------------------------------------------------------------- bool CScriptQuaternionInstanceHelper::ToString( void *p, char *pBuf, int bufSize ) { Quaternion *pQuat = ((Quaternion *)p); V_snprintf( pBuf, bufSize, "(Quaternion %p [%f %f %f %f])", (void*)pQuat, pQuat->x, pQuat->y, pQuat->z, pQuat->w ); return true; } bool CScriptQuaternionInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_t &variant ) { Quaternion *pQuat = ((Quaternion *)p); if ( strlen(pszKey) == 1 ) { switch (pszKey[0]) { case 'x': variant = pQuat->x; return true; case 'y': variant = pQuat->y; return true; case 'z': variant = pQuat->z; return true; case 'w': variant = pQuat->w; return true; } } return false; } bool CScriptQuaternionInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_t &variant ) { Quaternion *pQuat = ((Quaternion *)p); if ( strlen(pszKey) == 1 ) { switch (pszKey[0]) { case 'x': variant.AssignTo( &pQuat->x ); return true; case 'y': variant.AssignTo( &pQuat->y ); return true; case 'z': variant.AssignTo( &pQuat->z ); return true; case 'w': variant.AssignTo( &pQuat->w ); return true; } } return false; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ScriptQuaternionAdd( HSCRIPT hQuat1, HSCRIPT hQuat2, HSCRIPT hOut ) { if (!hQuat1 || !hQuat2 || !hOut) return; Quaternion *pQuat1 = ToQuaternion( hQuat1 ); Quaternion *pQuat2 = ToQuaternion( hQuat2 ); Quaternion *pOut = ToQuaternion( hOut ); QuaternionAdd( *pQuat1, *pQuat2, *pOut ); } void ScriptMatrixQuaternion( HSCRIPT hMat1, HSCRIPT hQuat1 ) { if (!hMat1 || !hQuat1) return; matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); Quaternion *pQuat1 = ToQuaternion( hQuat1 ); MatrixQuaternion( *pMat1, *pQuat1 ); } void ScriptQuaternionMatrix( HSCRIPT hQuat1, HSCRIPT hMat1 ) { if (!hQuat1 || !hMat1) return; Quaternion *pQuat1 = ToQuaternion( hQuat1 ); matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 ); QuaternionMatrix( *pQuat1, *pMat1 ); } QAngle ScriptQuaternionAngles( HSCRIPT hQuat1 ) { if (!hQuat1) return QAngle(); Quaternion *pQuat1 = ToQuaternion( hQuat1 ); QAngle angles; QuaternionAngles( *pQuat1, angles ); return angles; } //============================================================================= // // Misc. Vector/QAngle functions // //============================================================================= const Vector& ScriptAngleVectors( const QAngle &angles ) { static Vector forward; AngleVectors( angles, &forward ); return forward; } const QAngle& ScriptVectorAngles( const Vector &forward ) { static QAngle angles; VectorAngles( forward, angles ); return angles; } const Vector& ScriptVectorRotate( const Vector &in, HSCRIPT hMat ) { if (ToMatrix3x4(hMat) == NULL) return vec3_origin; static Vector out; VectorRotate( in, *ToMatrix3x4(hMat), out ); return out; } const Vector& ScriptVectorIRotate( const Vector &in, HSCRIPT hMat ) { if (ToMatrix3x4(hMat) == NULL) return vec3_origin; static Vector out; VectorIRotate( in, *ToMatrix3x4(hMat), out ); return out; } const Vector& ScriptVectorTransform( const Vector &in, HSCRIPT hMat ) { if (ToMatrix3x4(hMat) == NULL) return vec3_origin; static Vector out; VectorTransform( in, *ToMatrix3x4( hMat ), out ); return out; } const Vector& ScriptVectorITransform( const Vector &in, HSCRIPT hMat ) { if (ToMatrix3x4(hMat) == NULL) return vec3_origin; static Vector out; VectorITransform( in, *ToMatrix3x4( hMat ), out ); return out; } const Vector& ScriptCalcClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point ) { static Vector outvec; CalcClosestPointOnAABB( mins, maxs, point, outvec ); return outvec; } const Vector& ScriptCalcClosestPointOnLine( const Vector &point, const Vector &vLineA, const Vector &vLineB ) { static Vector outvec; CalcClosestPointOnLine( point, vLineA, vLineB, outvec ); return outvec; } float ScriptCalcDistanceToLine( const Vector &point, const Vector &vLineA, const Vector &vLineB ) { return CalcDistanceToLine( point, vLineA, vLineB ); } const Vector& ScriptCalcClosestPointOnLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB ) { static Vector outvec; CalcClosestPointOnLineSegment( point, vLineA, vLineB, outvec ); return outvec; } float ScriptCalcDistanceToLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB ) { return CalcDistanceToLineSegment( point, vLineA, vLineB ); } inline float ScriptExponentialDecay( float decayTo, float decayTime, float dt ) { return ExponentialDecay( decayTo, decayTime, dt ); } void RegisterMathBaseBindings( IScriptVM *pVM ) { ScriptRegisterConstantNamed( pVM, ((float)(180.f / M_PI_F)), "RAD2DEG", "" ); ScriptRegisterConstantNamed( pVM, ((float)(M_PI_F / 180.f)), "DEG2RAD", "" ); ScriptRegisterFunction( pVM, RandomFloat, "Generate a random floating point number within a range, inclusive." ); ScriptRegisterFunction( pVM, RandomInt, "Generate a random integer within a range, inclusive." ); //ScriptRegisterFunction( pVM, Approach, "Returns a value which approaches the target value from the input value with the specified speed." ); ScriptRegisterFunction( pVM, ApproachAngle, "Returns an angle which approaches the target angle from the input angle with the specified speed." ); ScriptRegisterFunction( pVM, AngleDiff, "Returns the degrees difference between two yaw angles." ); //ScriptRegisterFunction( pVM, AngleDistance, "Returns the distance between two angles." ); ScriptRegisterFunction( pVM, AngleNormalize, "Clamps an angle to be in between -360 and 360." ); ScriptRegisterFunction( pVM, AngleNormalizePositive, "Clamps an angle to be in between 0 and 360." ); ScriptRegisterFunction( pVM, AnglesAreEqual, "Checks if two angles are equal based on a given tolerance value." ); // // matrix3x4_t // pVM->RegisterClass( GetScriptDescForClass( matrix3x4_t ) ); ScriptRegisterFunctionNamed( pVM, ScriptFreeMatrixInstance, "FreeMatrixInstance", "Frees an allocated matrix instance." ); ScriptRegisterFunctionNamed( pVM, ScriptConcatTransforms, "ConcatTransforms", "Concatenates two transformation matrices into another matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixCopy, "MatrixCopy", "Copies a matrix to another matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixInvert, "MatrixInvert", "Inverts a matrix and copies the result to another matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatricesAreEqual, "MatricesAreEqual", "Checks if two matrices are equal." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixGetColumn, "MatrixGetColumn", "Gets the column of a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixSetColumn, "MatrixSetColumn", "Sets the column of a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixAngles, "MatrixAngles", "Gets the angles and position of a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptAngleMatrix, "AngleMatrix", "Sets the angles and position of a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptAngleIMatrix, "AngleIMatrix", "Sets the inverted angles and position of a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptSetIdentityMatrix, "SetIdentityMatrix", "Turns a matrix into an identity matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptSetScaleMatrix, "SetScaleMatrix", "Builds a scale matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixScaleBy, "MatrixScaleBy", "Scales a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixScaleByZero, "MatrixScaleByZero", "Scales a matrix by zero." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixGetTranslation, "MatrixGetTranslation", "Gets a matrix's translation." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixSetTranslation, "MatrixSetTranslation", "Sets a matrix's translation." ); // // Quaternion // pVM->RegisterClass( GetScriptDescForClass( Quaternion ) ); ScriptRegisterFunctionNamed( pVM, ScriptFreeQuaternionInstance, "FreeQuaternionInstance", "Frees an allocated quaternion instance." ); ScriptRegisterFunctionNamed( pVM, ScriptQuaternionAdd, "QuaternionAdd", "Adds two quaternions together into another quaternion." ); ScriptRegisterFunctionNamed( pVM, ScriptMatrixQuaternion, "MatrixQuaternion", "Converts a matrix to a quaternion." ); ScriptRegisterFunctionNamed( pVM, ScriptQuaternionMatrix, "QuaternionMatrix", "Converts a quaternion to a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptQuaternionAngles, "QuaternionAngles", "Converts a quaternion to angles." ); // // Misc. Vector/QAngle functions // ScriptRegisterFunctionNamed( pVM, ScriptAngleVectors, "AngleVectors", "Turns an angle into a direction vector." ); ScriptRegisterFunctionNamed( pVM, ScriptVectorAngles, "VectorAngles", "Turns a direction vector into an angle." ); ScriptRegisterFunctionNamed( pVM, ScriptVectorRotate, "VectorRotate", "Rotates a vector with a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptVectorIRotate, "VectorIRotate", "Rotates a vector with the inverse of a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptVectorTransform, "VectorTransform", "Transforms a vector with a matrix." ); ScriptRegisterFunctionNamed( pVM, ScriptVectorITransform, "VectorITransform", "Transforms a vector with the inverse of a matrix." ); ScriptRegisterFunction( pVM, CalcSqrDistanceToAABB, "Returns the squared distance to a bounding box." ); ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnAABB, "CalcClosestPointOnAABB", "Returns the closest point on a bounding box." ); ScriptRegisterFunctionNamed( pVM, ScriptCalcDistanceToLine, "CalcDistanceToLine", "Returns the distance to a line." ); ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnLine, "CalcClosestPointOnLine", "Returns the closest point on a line." ); ScriptRegisterFunctionNamed( pVM, ScriptCalcDistanceToLineSegment, "CalcDistanceToLineSegment", "Returns the distance to a line segment." ); ScriptRegisterFunctionNamed( pVM, ScriptCalcClosestPointOnLineSegment, "CalcClosestPointOnLineSegment", "Returns the closest point on a line segment." ); ScriptRegisterFunction( pVM, SimpleSplineRemapVal, "remaps a value in [startInterval, startInterval+rangeInterval] from linear to spline using SimpleSpline" ); ScriptRegisterFunction( pVM, SimpleSplineRemapValClamped, "remaps a value in [startInterval, startInterval+rangeInterval] from linear to spline using SimpleSpline" ); ScriptRegisterFunction( pVM, Bias, "The curve is biased towards 0 or 1 based on biasAmt, which is between 0 and 1." ); ScriptRegisterFunction( pVM, Gain, "Gain is similar to Bias, but biasAmt biases towards or away from 0.5." ); ScriptRegisterFunction( pVM, SmoothCurve, "SmoothCurve maps a 0-1 value into another 0-1 value based on a cosine wave" ); ScriptRegisterFunction( pVM, SmoothCurve_Tweak, "SmoothCurve peaks at flPeakPos, flPeakSharpness controls the sharpness of the peak" ); ScriptRegisterFunctionNamed( pVM, ScriptExponentialDecay, "ExponentialDecay", "decayTo is factor the value should decay to in decayTime" ); }