1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/smn_vector.cpp Sun Mar 30 07:00:22 2008 +0000
1.3 @@ -0,0 +1,199 @@
1.4 +/**
1.5 + * vim: set ts=4 :
1.6 + * =============================================================================
1.7 + * SourceMod
1.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 + * =============================================================================
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify it under
1.12 + * the terms of the GNU General Public License, version 3.0, as published by the
1.13 + * Free Software Foundation.
1.14 + *
1.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 + * details.
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License along with
1.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 + *
1.23 + * As a special exception, AlliedModders LLC gives you permission to link the
1.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 + * by the Valve Corporation. You must obey the GNU General Public License in
1.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 + * this exception to all derivative works. AlliedModders LLC defines further
1.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 + * or <http://www.sourcemod.net/license.php>.
1.31 + *
1.32 + * Version: $Id$
1.33 + */
1.34 +
1.35 +#include "sm_globals.h"
1.36 +#include <vector.h>
1.37 +#if defined ORANGEBOX_BUILD
1.38 +#include <mathlib.h>
1.39 +#else
1.40 +#include <math_base.h>
1.41 +#endif
1.42 +
1.43 +#define SET_VECTOR(addr, vec) \
1.44 + addr[0] = sp_ftoc(vec.x); \
1.45 + addr[1] = sp_ftoc(vec.y); \
1.46 + addr[2] = sp_ftoc(vec.z);
1.47 +
1.48 +static cell_t GetVectorLength(IPluginContext *pContext, const cell_t *params)
1.49 +{
1.50 + cell_t *addr;
1.51 +
1.52 + pContext->LocalToPhysAddr(params[1], &addr);
1.53 +
1.54 + Vector source(sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2]));
1.55 +
1.56 + if (!params[2])
1.57 + {
1.58 + return sp_ftoc(source.Length());
1.59 + } else {
1.60 + return sp_ftoc(source.LengthSqr());
1.61 + }
1.62 +}
1.63 +
1.64 +static cell_t GetVectorDistance(IPluginContext *pContext, const cell_t *params)
1.65 +{
1.66 + cell_t *addr1, *addr2;
1.67 +
1.68 + pContext->LocalToPhysAddr(params[1], &addr1);
1.69 + pContext->LocalToPhysAddr(params[2], &addr2);
1.70 +
1.71 + Vector source(sp_ctof(addr1[0]), sp_ctof(addr1[1]), sp_ctof(addr1[2]));
1.72 + Vector dest(sp_ctof(addr2[0]), sp_ctof(addr2[1]), sp_ctof(addr2[2]));
1.73 +
1.74 + if (!params[3])
1.75 + {
1.76 + return sp_ftoc(source.DistTo(dest));
1.77 + } else {
1.78 + return sp_ftoc(source.DistToSqr(dest));
1.79 + }
1.80 +}
1.81 +
1.82 +static cell_t GetVectorDotProduct(IPluginContext *pContext, const cell_t *params)
1.83 +{
1.84 + cell_t *addr1, *addr2;
1.85 +
1.86 + pContext->LocalToPhysAddr(params[1], &addr1);
1.87 + pContext->LocalToPhysAddr(params[2], &addr2);
1.88 +
1.89 + Vector source(sp_ctof(addr1[0]), sp_ctof(addr1[1]), sp_ctof(addr1[2]));
1.90 + Vector dest(sp_ctof(addr2[0]), sp_ctof(addr2[1]), sp_ctof(addr2[2]));
1.91 +
1.92 + return sp_ftoc(source.Dot(dest));
1.93 +}
1.94 +
1.95 +static cell_t GetVectorCrossProduct(IPluginContext *pContext, const cell_t *params)
1.96 +{
1.97 + cell_t *addr1, *addr2, *set;
1.98 +
1.99 + pContext->LocalToPhysAddr(params[1], &addr1);
1.100 + pContext->LocalToPhysAddr(params[2], &addr2);
1.101 + pContext->LocalToPhysAddr(params[3], &set);
1.102 +
1.103 + Vector vec1(sp_ctof(addr1[0]), sp_ctof(addr1[1]), sp_ctof(addr1[2]));
1.104 + Vector vec2(sp_ctof(addr2[0]), sp_ctof(addr2[1]), sp_ctof(addr2[2]));
1.105 +
1.106 + Vector vec3 = vec1.Cross(vec2);
1.107 +
1.108 + SET_VECTOR(set, vec3);
1.109 +
1.110 + return 1;
1.111 +}
1.112 +
1.113 +static cell_t GetAngleVectors(IPluginContext *pContext, const cell_t *params)
1.114 +{
1.115 + cell_t *ang_addr;
1.116 +
1.117 + pContext->LocalToPhysAddr(params[1], &ang_addr);
1.118 +
1.119 + QAngle angle(sp_ctof(ang_addr[0]), sp_ctof(ang_addr[1]), sp_ctof(ang_addr[2]));
1.120 + Vector fwd, right, up;
1.121 +
1.122 + AngleVectors(angle, &fwd, &right, &up);
1.123 +
1.124 + cell_t *addr_fwd, *addr_right, *addr_up;
1.125 + pContext->LocalToPhysAddr(params[2], &addr_fwd);
1.126 + pContext->LocalToPhysAddr(params[3], &addr_right);
1.127 + pContext->LocalToPhysAddr(params[4], &addr_up);
1.128 +
1.129 + SET_VECTOR(addr_fwd, fwd);
1.130 + SET_VECTOR(addr_right, right);
1.131 + SET_VECTOR(addr_up, up);
1.132 +
1.133 + return 1;
1.134 +}
1.135 +
1.136 +static cell_t GetVectorAngles(IPluginContext *pContext, const cell_t *params)
1.137 +{
1.138 + cell_t *vec_addr;
1.139 +
1.140 + pContext->LocalToPhysAddr(params[1], &vec_addr);
1.141 +
1.142 + Vector vec(sp_ctof(vec_addr[0]), sp_ctof(vec_addr[1]), sp_ctof(vec_addr[2]));
1.143 + QAngle angle;
1.144 +
1.145 + VectorAngles(vec, angle);
1.146 +
1.147 + cell_t *ang_addr;
1.148 + pContext->LocalToPhysAddr(params[2], &ang_addr);
1.149 +
1.150 + SET_VECTOR(ang_addr, angle);
1.151 +
1.152 + return 1;
1.153 +}
1.154 +
1.155 +static cell_t GetVectorVectors(IPluginContext *pContext, const cell_t *params)
1.156 +{
1.157 + cell_t *vec_addr;
1.158 +
1.159 + pContext->LocalToPhysAddr(params[1], &vec_addr);
1.160 +
1.161 + Vector vec(sp_ctof(vec_addr[0]), sp_ctof(vec_addr[1]), sp_ctof(vec_addr[2]));
1.162 + Vector right, up;
1.163 +
1.164 + VectorVectors(vec, right, up);
1.165 +
1.166 + cell_t *addr_right, *addr_up;
1.167 + pContext->LocalToPhysAddr(params[2], &addr_right);
1.168 + pContext->LocalToPhysAddr(params[3], &addr_up);
1.169 +
1.170 + SET_VECTOR(addr_right, right);
1.171 + SET_VECTOR(addr_up, up);
1.172 +
1.173 + return 1;
1.174 +}
1.175 +
1.176 +static cell_t NormalizeVector(IPluginContext *pContext, const cell_t *params)
1.177 +{
1.178 + cell_t *addr;
1.179 +
1.180 + pContext->LocalToPhysAddr(params[1], &addr);
1.181 +
1.182 + Vector source(sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2]));
1.183 + float length = VectorNormalize(source);
1.184 +
1.185 + pContext->LocalToPhysAddr(params[2], &addr);
1.186 + SET_VECTOR(addr, source);
1.187 +
1.188 + return sp_ftoc(length);
1.189 +}
1.190 +
1.191 +REGISTER_NATIVES(vectorNatives)
1.192 +{
1.193 + {"GetAngleVectors", GetAngleVectors},
1.194 + {"GetVectorAngles", GetVectorAngles},
1.195 + {"GetVectorCrossProduct", GetVectorCrossProduct},
1.196 + {"GetVectorDistance", GetVectorDistance},
1.197 + {"GetVectorDotProduct", GetVectorDotProduct},
1.198 + {"GetVectorLength", GetVectorLength},
1.199 + {"GetVectorVectors", GetVectorVectors},
1.200 + {"NormalizeVector", NormalizeVector},
1.201 + {NULL, NULL}
1.202 +};