mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
250 lines
7.1 KiB
C++
250 lines
7.1 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// movegrid.h: Move grid
|
|
//
|
|
|
|
#include "movegrid.h"
|
|
#include "debuglines.h"
|
|
|
|
cMoveGrid::cMoveGrid(int x, int y, int z)
|
|
{
|
|
m_iXRes = x;
|
|
m_iYRes = y;
|
|
m_iZRes = z;
|
|
|
|
GridPoints = (gridpoint_t *)gi.Malloc(sizeof(gridpoint_t) * x * y * z);
|
|
}
|
|
|
|
cMoveGrid::~cMoveGrid()
|
|
{
|
|
gi.Free(GridPoints);
|
|
}
|
|
|
|
void cMoveGrid::SetMoveInfo(vmove_t *vm)
|
|
{
|
|
v = *vm;
|
|
}
|
|
|
|
void cMoveGrid::GetMoveInfo(vmove_t *vm)
|
|
{
|
|
*vm = v;
|
|
}
|
|
|
|
gridpoint_t *cMoveGrid::GetGridPoint(int x, int y, int z)
|
|
{
|
|
return &GridPoints[x * m_iZRes + y * m_iXRes + z];
|
|
}
|
|
|
|
void cMoveGrid::SetOrientation(const vec3_t *v)
|
|
{
|
|
for (int i = 0; i < 3; i++) {
|
|
VectorCopy(v[i], orientation[i]);
|
|
}
|
|
}
|
|
|
|
void cMoveGrid::CalculateBoxPoints(void)
|
|
{
|
|
int x, y, z;
|
|
int rx, ry, rz;
|
|
int xdelta, ydelta, zdelta;
|
|
Vector vBoxSize;
|
|
|
|
vBoxSize = Vector(v.maxs) - Vector(v.mins);
|
|
|
|
rx = (int)(vBoxSize.x / (float)m_iXRes);
|
|
ry = (int)(vBoxSize.y / (float)m_iYRes);
|
|
rz = (int)(vBoxSize.z / (float)m_iZRes);
|
|
|
|
xdelta = ydelta = zdelta = 0;
|
|
|
|
for (x = 0; x < m_iXRes; x++) {
|
|
for (y = 0; y < m_iYRes; y++) {
|
|
for (z = 0; z < m_iZRes; z++) {
|
|
gridpoint_t *gridPoint = GetGridPoint(x, y, z);
|
|
|
|
gridPoint->origin = Vector(xdelta - rx, ydelta - ry, zdelta + rz / 2.f);
|
|
zdelta += rz;
|
|
}
|
|
zdelta = 0;
|
|
ydelta += ry;
|
|
}
|
|
ydelta = 0;
|
|
xdelta += rx;
|
|
}
|
|
|
|
for (x = 0; x < m_iXRes; x++) {
|
|
for (y = 0; y < m_iYRes; y++) {
|
|
for (z = 0; z < m_iZRes; z++) {
|
|
Vector vTmp;
|
|
gridpoint_t *gridPoint = GetGridPoint(x, y, z);
|
|
|
|
MatrixTransformVector(gridPoint->origin, orientation, vTmp);
|
|
|
|
gridPoint->origin = vTmp;
|
|
gridPoint->vm = v;
|
|
gridPoint->vm.vs = &gridPoint->vs;
|
|
|
|
if (rx >= ry) {
|
|
Vector vec;
|
|
|
|
vec = Vector(-ry / 2.f, -ry / 2.f, -rz / 2.f);
|
|
vec.copyTo(gridPoint->vm.mins);
|
|
|
|
vec = Vector(ry / 2.f, ry / 2.f, rz / 2.f);
|
|
vec.copyTo(gridPoint->vm.maxs);
|
|
} else {
|
|
Vector vec;
|
|
|
|
vec = Vector(-rx / 2.f, -rx / 2.f, -rz / 2.f);
|
|
vec.copyTo(gridPoint->vm.mins);
|
|
|
|
vec = Vector(rx / 2.f, rx / 2.f, rz / 2.f);
|
|
vec.copyTo(gridPoint->vm.maxs);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void cMoveGrid::Move(void)
|
|
{
|
|
gridpoint_t *gridPoint;
|
|
int x, y, z;
|
|
Vector vBoxSize;
|
|
Vector old_origin;
|
|
float best;
|
|
float bx, by, bz;
|
|
Vector bestdelta;
|
|
|
|
old_origin = v.vs->origin;
|
|
vBoxSize = Vector(v.maxs) - Vector(v.mins);
|
|
|
|
CalculateBoxPoints();
|
|
|
|
for (x = 0; x < m_iXRes; x++) {
|
|
for (y = 0; y < m_iYRes; y++) {
|
|
for (z = 0; z < m_iZRes; z++) {
|
|
gridPoint = GetGridPoint(x, y, z);
|
|
|
|
gridPoint->origindelta = gridPoint->origin;
|
|
gridPoint->origin += old_origin;
|
|
gridPoint->origin.copyTo(gridPoint->vm.vs->origin);
|
|
|
|
G_DebugBBox(gridPoint->origin, gridPoint->vm.mins, gridPoint->vm.maxs, 1, 1, 0, 1);
|
|
|
|
VmoveSingle(&gridPoint->vm);
|
|
|
|
gridPoint->neworigin = gridPoint->vm.vs->origin;
|
|
gridPoint->changed = gridPoint->neworigin - gridPoint->origin;
|
|
gridPoint->newvel = gridPoint->vm.vs->velocity;
|
|
// set the ground entity
|
|
gridPoint->groundentity = NULL;
|
|
if (gridPoint->vm.vs->groundEntityNum != ENTITYNUM_NONE) {
|
|
gridPoint->groundentity = &g_entities[gridPoint->vm.vs->groundEntityNum];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
best = 99999;
|
|
bx = by = bz = 0;
|
|
|
|
for (x = 0; x < m_iXRes; x++) {
|
|
for (y = 0; y < m_iYRes; y++) {
|
|
for (z = 0; z < m_iZRes; z++) {
|
|
gridPoint = GetGridPoint(x, y, z);
|
|
float speed;
|
|
|
|
speed = (gridPoint->changed - gridPoint->origindelta).length();
|
|
if (speed < best) {
|
|
best = gridPoint->changed.length();
|
|
bx = x;
|
|
by = y;
|
|
bz = z;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
gridPoint = GetGridPoint(bx, by, bz);
|
|
bestdelta = gridPoint->neworigin - gridPoint->origindelta;
|
|
bestdelta.copyTo(v.vs->origin);
|
|
gridPoint->newvel.copyTo(v.vs->velocity);
|
|
}
|
|
|
|
qboolean cMoveGrid::CheckStuck(void)
|
|
{
|
|
int x;
|
|
int y;
|
|
int z;
|
|
trace_t trace;
|
|
|
|
for (x = 0; x < m_iXRes; x++) {
|
|
for (y = 0; y < m_iYRes; y++) {
|
|
for (z = 0; z < m_iZRes; z++) {
|
|
gi.trace(
|
|
&trace, v.vs->origin, v.mins, v.maxs, v.vs->origin, v.vs->entityNum, v.tracemask, false, false
|
|
);
|
|
|
|
if (trace.allsolid || trace.startsolid || trace.fraction == 0.0f) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void cMoveGrid::Archive(Archiver& arc)
|
|
{
|
|
int i;
|
|
|
|
arc.ArchiveInteger(&m_iXRes);
|
|
arc.ArchiveInteger(&m_iYRes);
|
|
arc.ArchiveInteger(&m_iZRes);
|
|
|
|
arc.ArchiveFloat(&v.frametime);
|
|
arc.ArchiveFloat(&v.desired_speed);
|
|
arc.ArchiveInteger(&v.tracemask);
|
|
arc.ArchiveInteger(&v.numtouch);
|
|
|
|
for (i = 0; i < ARRAY_LEN(v.touchents); i++) {
|
|
arc.ArchiveInteger(&v.touchents[i]);
|
|
}
|
|
arc.ArchiveVec3(v.mins);
|
|
arc.ArchiveVec3(v.maxs);
|
|
|
|
arc.ArchiveVec3(orientation[0]);
|
|
arc.ArchiveVec3(orientation[1]);
|
|
arc.ArchiveVec3(orientation[2]);
|
|
|
|
if (arc.Loading()) {
|
|
if (GridPoints) {
|
|
if (m_iXRes != 3 && m_iYRes != 3 && m_iZRes != 1) {
|
|
gi.Free(GridPoints);
|
|
GridPoints = (gridpoint_t *)gi.Malloc(sizeof(gridpoint_t) * m_iXRes * m_iYRes * m_iZRes);
|
|
}
|
|
}
|
|
}
|
|
}
|