Preliminary version of wall handling. Manny still gets stuck at walls,
but he now turns until he can move forward again.
This commit is contained in:
parent
9abc55fcfd
commit
932ccec21b
6 changed files with 116 additions and 9 deletions
62
actor.cpp
62
actor.cpp
|
@ -34,6 +34,7 @@
|
||||||
Actor::Actor(const char *name) :
|
Actor::Actor(const char *name) :
|
||||||
_name(name), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
_name(name), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
||||||
_pitch(0), _yaw(0), _roll(0), _walkRate(0), _turnRate(0),
|
_pitch(0), _yaw(0), _roll(0), _walkRate(0), _turnRate(0),
|
||||||
|
_reflectionAngle(80),
|
||||||
_visible(true), _lipSynch(NULL), _turning(false), _walking(false),
|
_visible(true), _lipSynch(NULL), _turning(false), _walking(false),
|
||||||
_restCostume(NULL), _restChore(-1),
|
_restCostume(NULL), _restChore(-1),
|
||||||
_walkCostume(NULL), _walkChore(-1), _walkedLast(false), _walkedCur(false),
|
_walkCostume(NULL), _walkChore(-1), _walkedLast(false), _walkedCur(false),
|
||||||
|
@ -98,16 +99,65 @@ void Actor::walkForward() {
|
||||||
std::sin(pitch_rad));
|
std::sin(pitch_rad));
|
||||||
Vector3d destPos = _pos + forwardVec * dist;
|
Vector3d destPos = _pos + forwardVec * dist;
|
||||||
|
|
||||||
if (!_constrain) {
|
if (! _constrain) {
|
||||||
_pos = destPos;
|
_pos += forwardVec * dist;
|
||||||
_walkedCur = true;
|
_walkedCur = true;
|
||||||
} else {
|
return;
|
||||||
Sector *sector = g_engine->currScene()->findPointSector(destPos, 0x1000);
|
}
|
||||||
if (sector != NULL) {
|
|
||||||
_pos = sector->projectToPlane(destPos);
|
if (dist < 0) {
|
||||||
|
dist = -dist;
|
||||||
|
forwardVec = -forwardVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sector *currSector = NULL, *prevSector = NULL;
|
||||||
|
Sector::ExitInfo ei;
|
||||||
|
|
||||||
|
g_engine->currScene()->findClosestSector(_pos, &currSector, &_pos);
|
||||||
|
if (currSector == NULL) { // Shouldn't happen...
|
||||||
|
_pos += forwardVec * dist;
|
||||||
_walkedCur = true;
|
_walkedCur = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (currSector != NULL) {
|
||||||
|
prevSector = currSector;
|
||||||
|
Vector3d puckVector = currSector->projectToPuckVector(forwardVec);
|
||||||
|
puckVector /= puckVector.magnitude();
|
||||||
|
currSector->getExitInfo(_pos, puckVector, &ei);
|
||||||
|
float exitDist = (ei.exitPoint - _pos).magnitude();
|
||||||
|
if (dist < exitDist) {
|
||||||
|
_pos += puckVector * dist;
|
||||||
|
_walkedCur = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
_pos = ei.exitPoint;
|
||||||
|
dist -= exitDist;
|
||||||
|
if (exitDist > 0.0001)
|
||||||
|
_walkedCur = true;
|
||||||
|
|
||||||
|
// Check for an adjacent sector which can continue
|
||||||
|
// the path
|
||||||
|
currSector = g_engine->currScene()->findPointSector(ei.exitPoint + 0.0001 * puckVector, 0x1000);
|
||||||
|
if (currSector == prevSector)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ei.angleWithEdge *= (180.0 / M_PI);
|
||||||
|
int turnDir = 1;
|
||||||
|
if (ei.angleWithEdge > 90) {
|
||||||
|
ei.angleWithEdge = 180 - ei.angleWithEdge;
|
||||||
|
ei.edgeDir = -ei.edgeDir;
|
||||||
|
turnDir = -1;
|
||||||
|
}
|
||||||
|
if (ei.angleWithEdge > _reflectionAngle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ei.angleWithEdge += 0.1;
|
||||||
|
float turnAmt = g_engine->perSecond(_turnRate);
|
||||||
|
if (turnAmt > ei.angleWithEdge)
|
||||||
|
turnAmt = ei.angleWithEdge;
|
||||||
|
_yaw += turnAmt * turnDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d Actor::puckVector() const {
|
Vector3d Actor::puckVector() const {
|
||||||
|
|
2
actor.h
2
actor.h
|
@ -66,6 +66,7 @@ public:
|
||||||
return _setName == name;
|
return _setName == name;
|
||||||
}
|
}
|
||||||
void walkForward();
|
void walkForward();
|
||||||
|
void setReflection(float angle) { _reflectionAngle = angle; }
|
||||||
Vector3d puckVector() const;
|
Vector3d puckVector() const;
|
||||||
void turn(int dir);
|
void turn(int dir);
|
||||||
|
|
||||||
|
@ -125,6 +126,7 @@ private:
|
||||||
float _walkRate, _turnRate;
|
float _walkRate, _turnRate;
|
||||||
|
|
||||||
bool _constrain; // Constrain to walkboxes
|
bool _constrain; // Constrain to walkboxes
|
||||||
|
float _reflectionAngle; // Maximum angle to turn by at walls
|
||||||
bool _visible;
|
bool _visible;
|
||||||
bool _lookingMode;
|
bool _lookingMode;
|
||||||
std::string _talkSoundName;
|
std::string _talkSoundName;
|
||||||
|
|
9
lua.cpp
9
lua.cpp
|
@ -457,6 +457,12 @@ static void WalkActorForward() {
|
||||||
act->walkForward();
|
act->walkForward();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SetActorReflection() {
|
||||||
|
Actor *act = check_actor(1);
|
||||||
|
float angle = luaL_check_number(2);
|
||||||
|
act->setReflection(angle);
|
||||||
|
}
|
||||||
|
|
||||||
static void GetActorPuckVector() {
|
static void GetActorPuckVector() {
|
||||||
Actor *act = check_actor(1);
|
Actor *act = check_actor(1);
|
||||||
Vector3d result = act->puckVector();
|
Vector3d result = act->puckVector();
|
||||||
|
@ -1584,7 +1590,6 @@ STUB_FUNC(SetActorWalkDominate)
|
||||||
STUB_FUNC(GetCameraActor)
|
STUB_FUNC(GetCameraActor)
|
||||||
STUB_FUNC(DriveActorTo)
|
STUB_FUNC(DriveActorTo)
|
||||||
STUB_FUNC(WalkActorVector)
|
STUB_FUNC(WalkActorVector)
|
||||||
STUB_FUNC(SetActorReflection)
|
|
||||||
STUB_FUNC(GetActorRect)
|
STUB_FUNC(GetActorRect)
|
||||||
STUB_FUNC(GetActorNodeLocation)
|
STUB_FUNC(GetActorNodeLocation)
|
||||||
STUB_FUNC(SetActorTimeScale)
|
STUB_FUNC(SetActorTimeScale)
|
||||||
|
@ -1924,6 +1929,8 @@ struct luaL_reg mainOpcodes[] = {
|
||||||
{ "PutActorInSet", PutActorInSet },
|
{ "PutActorInSet", PutActorInSet },
|
||||||
{ "WalkActorVector", WalkActorVector },
|
{ "WalkActorVector", WalkActorVector },
|
||||||
{ "WalkActorForward", WalkActorForward },
|
{ "WalkActorForward", WalkActorForward },
|
||||||
|
{ "SetActorReflection", SetActorReflection },
|
||||||
|
{ "GetActorPuckVector", GetActorPuckVector },
|
||||||
{ "DriveActorTo", DriveActorTo },
|
{ "DriveActorTo", DriveActorTo },
|
||||||
{ "WalkActorTo", WalkActorTo },
|
{ "WalkActorTo", WalkActorTo },
|
||||||
{ "WalkActorToAvoiding", WalkActorToAvoiding },
|
{ "WalkActorToAvoiding", WalkActorToAvoiding },
|
||||||
|
|
|
@ -125,6 +125,10 @@ inline Vector3d operator *(float s, const Vector3d& v) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Vector3d operator -(const Vector3d& v) {
|
||||||
|
return (-1.0f) * v;
|
||||||
|
}
|
||||||
|
|
||||||
inline Vector3d operator *(const Vector3d& v, float s) {
|
inline Vector3d operator *(const Vector3d& v, float s) {
|
||||||
return s * v;
|
return s * v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,3 +160,38 @@ Vector3d Sector::closestPoint(Vector3d point) const {
|
||||||
}
|
}
|
||||||
return _vertices[index];
|
return _vertices[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sector::getExitInfo(Vector3d start, Vector3d dir,
|
||||||
|
struct ExitInfo *result) {
|
||||||
|
start = projectToPlane(start);
|
||||||
|
dir = projectToPuckVector(dir);
|
||||||
|
|
||||||
|
// First find the edge the ray exits through: this is where
|
||||||
|
// the z-component of (v_i - start) x dir changes sign from
|
||||||
|
// positive to negative.
|
||||||
|
|
||||||
|
// First find a vertex such that the cross product has
|
||||||
|
// positive z-component.
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < _numVertices; i++) {
|
||||||
|
Vector3d delta = _vertices[i] - start;
|
||||||
|
if (delta.x() * dir.y() > delta.y() * dir.x())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now continue until the cross product has negative
|
||||||
|
// z-component.
|
||||||
|
while (i < _numVertices) {
|
||||||
|
i++;
|
||||||
|
Vector3d delta = _vertices[i] - start;
|
||||||
|
if (delta.x() * dir.y() <= delta.y() * dir.x())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->edgeDir = _vertices[i] - _vertices[i - 1];
|
||||||
|
result->angleWithEdge = angle(dir, result->edgeDir);
|
||||||
|
|
||||||
|
Vector3d edgeNormal(result->edgeDir.y(), -result->edgeDir.x(), 0);
|
||||||
|
result->exitPoint = start + (dot(_vertices[i] - start, edgeNormal) /
|
||||||
|
dot(dir, edgeNormal)) * dir;
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,15 @@ public:
|
||||||
|
|
||||||
Vector3d closestPoint(Vector3d point) const;
|
Vector3d closestPoint(Vector3d point) const;
|
||||||
|
|
||||||
|
// Interface to trace a ray to its exit from the polygon
|
||||||
|
struct ExitInfo {
|
||||||
|
Vector3d exitPoint;
|
||||||
|
float angleWithEdge;
|
||||||
|
Vector3d edgeDir;
|
||||||
|
};
|
||||||
|
void getExitInfo(Vector3d start, Vector3d dir,
|
||||||
|
struct ExitInfo *result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _numVertices, _id;
|
int _numVertices, _id;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue