[Scummvm-cvs-logs] CVS: residual walkplane.h,1.7,1.8 walkplane.cpp,1.9,1.10 scene.h,1.16,1.17 scene.cpp,1.25,1.26 actor.cpp,1.27,1.28

Daniel Schepler dschepler at users.sourceforge.net
Fri Mar 26 01:40:00 CET 2004


Update of /cvsroot/scummvm/residual
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11917

Modified Files:
	walkplane.h walkplane.cpp scene.h scene.cpp actor.cpp 
Log Message:
Snap actors to walk boxes when appropriate.  This (apparently) fixes a
hang after taking the garage elevator back upstairs.


Index: walkplane.h
===================================================================
RCS file: /cvsroot/scummvm/residual/walkplane.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- walkplane.h	25 Mar 2004 15:43:05 -0000	1.7
+++ walkplane.h	26 Mar 2004 09:28:13 -0000	1.8
@@ -42,6 +42,8 @@
 	Vector3d projectToPlane(Vector3d point) const;
 	Vector3d projectToPuckVector(Vector3d v) const;
 
+	Vector3d closestPoint(Vector3d point) const;
+
 private:
 	int numVertices_, id_;
 

Index: walkplane.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/walkplane.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- walkplane.cpp	25 Mar 2004 15:43:05 -0000	1.9
+++ walkplane.cpp	26 Mar 2004 09:28:13 -0000	1.10
@@ -128,3 +128,37 @@
 	result.z() -= dot(normal_, v) / normal_.z();
 	return result;
 }
+
+// Find the closest point on the walkplane to the given point
+Vector3d Sector::closestPoint(Vector3d point) const {
+	// First try to project to the plane
+	Vector3d p2 = point;
+	p2 -= (dot(normal_, p2 - vertices_[0])) * normal_;
+	if (isPointInSector(p2))
+		return p2;
+
+	// Now try to project to some edge
+	for (int i = 0; i < numVertices_; i++) {
+		Vector3d edge = vertices_[i + 1] - vertices_[i];
+		Vector3d delta = point - vertices_[i];
+		float scalar = dot(delta, edge) / dot(edge, edge);
+		if (scalar >= 0 && scalar <= 1 &&
+		    delta.x() * edge.y() > delta.y() * edge.x())
+			// That last test is just whether the z-component
+			// of delta cross edge is positive; we don't
+			// want to return opposite edges.
+			return vertices_[i] + scalar * edge;
+	}
+
+	// Otherwise, just find the closest vertex
+	float minDist = (point - vertices_[0]).magnitude();
+	int index = 0;
+	for (int i = 1; i < numVertices_; i++) {
+		float currDist = (point - vertices_[i]).magnitude();
+		if (currDist < minDist) {
+			minDist = currDist;
+			index = i;
+		}
+	}
+	return vertices_[index];
+}

Index: scene.h
===================================================================
RCS file: /cvsroot/scummvm/residual/scene.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- scene.h	25 Mar 2004 09:33:17 -0000	1.16
+++ scene.h	26 Mar 2004 09:28:13 -0000	1.17
@@ -67,6 +67,7 @@
 			return NULL;
 	}
 	Sector *findPointSector(Vector3d p, int flags);
+	void findClosestSector(Vector3d p, Sector **sect, Vector3d *closestPt);
 
 	void addObjectState(ObjectState *s) {
 		states_.push_back(s);

Index: scene.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/scene.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- scene.cpp	26 Mar 2004 04:42:27 -0000	1.25
+++ scene.cpp	26 Mar 2004 09:28:13 -0000	1.26
@@ -189,6 +189,31 @@
 	return NULL;
 }
 
+void Scene::findClosestSector(Vector3d p, Sector **sect, Vector3d *closestPt) {
+	Sector *resultSect = NULL;
+	Vector3d resultPt = p;
+	float minDist;
+
+	for (int i = 0; i < numSectors_; i++) {
+		Sector *sector = sectors_ + i;
+		if ((sector->type() & 0x1000) == 0 ||
+		    ! sector->visible())
+			continue;
+		Vector3d closestPt = sector->closestPoint(p);
+		float thisDist = (closestPt - p).magnitude();
+		if (resultSect == NULL || thisDist < minDist) {
+			resultSect = sector;
+			resultPt = closestPt;
+			minDist = thisDist;
+		}
+	}
+
+	if (sect != NULL)
+		*sect = resultSect;
+	if (closestPt != NULL)
+		*closestPt = resultPt;
+}
+
 ObjectState *Scene::findState(const char *filename) {
 	for (StateList::iterator i = states_.begin(); i != states_.end();
 	     i++) {

Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/actor.cpp,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- actor.cpp	26 Mar 2004 04:42:27 -0000	1.27
+++ actor.cpp	26 Mar 2004 09:28:13 -0000	1.28
@@ -277,6 +277,13 @@
 }
 
 void Actor::update() {
+	// Snap actor to walkboxes if following them.  This might be
+	// necessary for example after activating/deactivating
+	// walkboxes, etc.
+	if (constrain_ && ! walking_) {
+		Engine::instance()->currScene()->findClosestSector(pos_, NULL, &pos_);
+	}
+
 	if (turning_) {
 		float turnAmt = Engine::instance()->perSecond(turnRate_);
 		float dyaw = destYaw_ - yaw_;
@@ -308,7 +315,7 @@
 			pos_ = destPos_;
 			walking_ = false;
 			turning_ = false;
-			}
+		}
 		else
 			pos_ += dir * walkAmt;
 





More information about the Scummvm-git-logs mailing list