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) :
|
||||
_name(name), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
||||
_pitch(0), _yaw(0), _roll(0), _walkRate(0), _turnRate(0),
|
||||
_reflectionAngle(80),
|
||||
_visible(true), _lipSynch(NULL), _turning(false), _walking(false),
|
||||
_restCostume(NULL), _restChore(-1),
|
||||
_walkCostume(NULL), _walkChore(-1), _walkedLast(false), _walkedCur(false),
|
||||
|
@ -98,16 +99,65 @@ void Actor::walkForward() {
|
|||
std::sin(pitch_rad));
|
||||
Vector3d destPos = _pos + forwardVec * dist;
|
||||
|
||||
if (!_constrain) {
|
||||
_pos = destPos;
|
||||
if (! _constrain) {
|
||||
_pos += forwardVec * dist;
|
||||
_walkedCur = true;
|
||||
} else {
|
||||
Sector *sector = g_engine->currScene()->findPointSector(destPos, 0x1000);
|
||||
if (sector != NULL) {
|
||||
_pos = sector->projectToPlane(destPos);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
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 {
|
||||
|
|
2
actor.h
2
actor.h
|
@ -66,6 +66,7 @@ public:
|
|||
return _setName == name;
|
||||
}
|
||||
void walkForward();
|
||||
void setReflection(float angle) { _reflectionAngle = angle; }
|
||||
Vector3d puckVector() const;
|
||||
void turn(int dir);
|
||||
|
||||
|
@ -125,6 +126,7 @@ private:
|
|||
float _walkRate, _turnRate;
|
||||
|
||||
bool _constrain; // Constrain to walkboxes
|
||||
float _reflectionAngle; // Maximum angle to turn by at walls
|
||||
bool _visible;
|
||||
bool _lookingMode;
|
||||
std::string _talkSoundName;
|
||||
|
|
9
lua.cpp
9
lua.cpp
|
@ -457,6 +457,12 @@ static void WalkActorForward() {
|
|||
act->walkForward();
|
||||
}
|
||||
|
||||
static void SetActorReflection() {
|
||||
Actor *act = check_actor(1);
|
||||
float angle = luaL_check_number(2);
|
||||
act->setReflection(angle);
|
||||
}
|
||||
|
||||
static void GetActorPuckVector() {
|
||||
Actor *act = check_actor(1);
|
||||
Vector3d result = act->puckVector();
|
||||
|
@ -1584,7 +1590,6 @@ STUB_FUNC(SetActorWalkDominate)
|
|||
STUB_FUNC(GetCameraActor)
|
||||
STUB_FUNC(DriveActorTo)
|
||||
STUB_FUNC(WalkActorVector)
|
||||
STUB_FUNC(SetActorReflection)
|
||||
STUB_FUNC(GetActorRect)
|
||||
STUB_FUNC(GetActorNodeLocation)
|
||||
STUB_FUNC(SetActorTimeScale)
|
||||
|
@ -1924,6 +1929,8 @@ struct luaL_reg mainOpcodes[] = {
|
|||
{ "PutActorInSet", PutActorInSet },
|
||||
{ "WalkActorVector", WalkActorVector },
|
||||
{ "WalkActorForward", WalkActorForward },
|
||||
{ "SetActorReflection", SetActorReflection },
|
||||
{ "GetActorPuckVector", GetActorPuckVector },
|
||||
{ "DriveActorTo", DriveActorTo },
|
||||
{ "WalkActorTo", WalkActorTo },
|
||||
{ "WalkActorToAvoiding", WalkActorToAvoiding },
|
||||
|
|
|
@ -125,6 +125,10 @@ inline Vector3d operator *(float s, const Vector3d& v) {
|
|||
return result;
|
||||
}
|
||||
|
||||
inline Vector3d operator -(const Vector3d& v) {
|
||||
return (-1.0f) * v;
|
||||
}
|
||||
|
||||
inline Vector3d operator *(const Vector3d& v, float s) {
|
||||
return s * v;
|
||||
}
|
||||
|
|
|
@ -160,3 +160,38 @@ Vector3d Sector::closestPoint(Vector3d point) const {
|
|||
}
|
||||
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;
|
||||
|
||||
// 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:
|
||||
int _numVertices, _id;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue