Ejemplo n.º 1
0
void Actor::updateWalk() {
	if (_path.empty()) {
		return;
	}

	Math::Vector3d destPos = _path.back();
	Math::Vector3d dir = destPos - _pos;
	float dist = dir.getMagnitude();

	_walkedCur = true;
	float walkAmt = g_grim->getPerSecond(_walkRate);
	if (walkAmt >= dist) {
		_path.pop_back();
		if (_path.empty()) {
			_walking = false;
			_pos = destPos;
// It seems that we need to allow an already active turning motion to
// continue or else turning actors away from barriers won't work right
			_turning = false;
			return;
		}
	}

	destPos = handleCollisionTo(_pos, destPos);
	Math::Angle y = getYawTo(destPos);
	turnTo(_pitch, y, _roll);

	dir = destPos - _pos;
	dir.normalize();
	_pos += dir * walkAmt;
}
Ejemplo n.º 2
0
void Lua_V2::WorldToScreen() {
	lua_Object xObj = lua_getparam(1);
	lua_Object yObj = lua_getparam(2);
	lua_Object zObj = lua_getparam(3);
	if (!lua_isnumber(xObj) || !lua_isnumber(yObj) || !lua_isnumber(zObj)) {
		lua_pushnumber(0.0);
		lua_pushnumber(0.0);
		return;
	}

	float x = lua_getnumber(xObj);
	float y = lua_getnumber(yObj);
	float z = lua_getnumber(zObj);
	Math::Vector3d pos = Math::Vector3d(x, y, z);

	const Set::Setup *setup = g_emi->getCurrSet()->getCurrSetup();
	const Math::Vector3d interest = setup->_interest;
	const float roll = setup->_roll;
	const Math::Quaternion quat = Math::Quaternion(interest.x(), interest.y(), interest.z(), roll);
	Math::Matrix4 view = quat.toMatrix();
	view.transpose();

	pos -= setup->_pos;
	pos = view.getRotation() * pos;
	pos.z() = -pos.z();

	Math::Matrix4 proj = GfxBase::makeProjMatrix(setup->_fov, setup->_nclip, setup->_fclip);
	proj.transpose();
	Math::Vector4d screen = proj * Math::Vector4d(pos.x(), pos.y(), pos.z(), 1.0);
	screen /= screen.w();

	lua_pushnumber((screen.x() + 1) * 320);
	lua_pushnumber((1 - screen.y()) * 240);
}
Ejemplo n.º 3
0
void Lua_V1::SetSoundPosition() {
	Math::Vector3d pos;
	int minVolume = 10;
	int maxVolume = 127;
	float someParam = 0;
	int argId = 1;
	lua_Object paramObj;

	if (g_grim->getCurrSet()) {
		g_grim->getCurrSet()->getSoundParameters(&minVolume, &maxVolume);
	}

	lua_Object nameObj = lua_getparam(argId++);
	if (!lua_isnumber(nameObj) && !lua_isstring(nameObj))
		return;

	lua_Object actorObj = lua_getparam(argId++);
	if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKTAG('A','C','T','R')) {
		Actor *actor = getactor(actorObj);
		if (!actor)
			return;
		pos = actor->getPos();
	} else if (lua_isnumber(actorObj)) {
		float x = lua_getnumber(actorObj);
		float y = lua_getnumber(argId++);
		float z = lua_getnumber(argId++);
		pos.set(x, y, z);
	}

	paramObj = (int)lua_getparam(argId++);
	if (lua_isnumber(paramObj)) {
		minVolume = (int)lua_getnumber(paramObj);
		if (minVolume > 127)
			minVolume = 127;
	}
	paramObj = lua_getparam(argId++);
	if (lua_isnumber(paramObj)) {
		maxVolume = (int)lua_getnumber(paramObj);
		if (maxVolume > 127)
			maxVolume = 127;
		else if (maxVolume < minVolume)
			maxVolume = minVolume;
	}

	paramObj = lua_getparam(argId++);
	if (lua_isnumber(paramObj)) {
		someParam = (int)lua_getnumber(paramObj);
		if (someParam < 0.0)
			someParam = 0.0;
	}

	if (g_grim->getCurrSet()) {
		if (lua_isnumber(nameObj))
			error("SetSoundPosition: number is not yet supported");
		else {
			const char *soundName = lua_getstring(nameObj);
			g_grim->getCurrSet()->setSoundPosition(soundName, pos, minVolume, maxVolume);
		}
	}
}
Ejemplo n.º 4
0
void SoundTrack::updatePosition() {
    if (!_positioned)
        return;

    Set *set = g_grim->getCurrSet();
    Set::Setup *setup = set->getCurrSetup();
    Math::Vector3d cameraPos = setup->_pos;
    Math::Vector3d vector = _pos - cameraPos;
    float distance = vector.getMagnitude();
    _attenuation = MAX(0.0f, 1.0f - distance / (_volume * 100.0f / Audio::Mixer::kMaxChannelVolume));
    if (!isfinite(_attenuation)) {
        _attenuation = 0.0f;
    }

    Math::Matrix4 worldRot = setup->_rot;
    Math::Vector3d relPos = (_pos - setup->_pos);
    Math::Vector3d p(relPos);
    worldRot.inverseRotate(&p);
    float angle = atan2(p.x(), p.z());
    float pan = sin(angle);
    _balance = (int)(pan * 127.0f);

    if (_handle) {
        g_system->getMixer()->setChannelBalance(*_handle, _balance);
        g_system->getMixer()->setChannelVolume(*_handle, (byte)getEffectiveVolume());
    }
}
void ShaderRenderer::screenPosToDirection(const Common::Point screen, float &pitch, float &heading) {
  double x, y, z;

  x = screen.x;
  y = kOriginalHeight - screen.y;
  z = 0.9f;

  const Math::Vector2d tl = _viewport.getTopLeft();
  x = 2 * double(x - tl.getX()) / _viewport.getWidth() - 1.0f;
  y = 2 * double(y - tl.getY()) / _viewport.getHeight() - 1.0f;
  z = 2 * z - 1.0f;

  // Screen coords to 3D coords
  Math::Vector4d point = Math::Vector4d(x, y, z, 1.0f);
  point = _mvpMatrix * point;

  // 3D coords to polar coords
  Math::Vector3d v = Math::Vector3d(point.x(), point.y(), point.z());
  v.normalize();

  Math::Vector2d horizontalProjection = Math::Vector2d(v.x(), v.z());
  horizontalProjection.normalize();

  pitch = 90 - Math::Angle::arcCosine(v.y()).getDegrees();
  heading = Math::Angle::arcCosine(horizontalProjection.getY()).getDegrees();

  if (horizontalProjection.getX() > 0.0)
    heading = 360 - heading;
}
Ejemplo n.º 6
0
/* Given a position and a size this function calculates and pushes
 * the nearest point to that which will be valid if the boxes are
 * shrunk by the amount specified.
 */
void Lua_V1::GetShrinkPos() {
	lua_Object xObj = lua_getparam(1);
	lua_Object yObj = lua_getparam(2);
	lua_Object zObj = lua_getparam(3);
	lua_Object rObj = lua_getparam(4);

	if (!lua_isnumber(xObj) || !lua_isnumber(yObj) || !lua_isnumber(zObj) || !lua_isnumber(rObj))
		return;

	float x = lua_getnumber(xObj);
	float y = lua_getnumber(yObj);
	float z = lua_getnumber(zObj);
	float r = lua_getnumber(rObj);
	Math::Vector3d pos;
	pos.set(x, y, z);

	Sector* sector;
	g_grim->getCurrSet()->shrinkBoxes(r);
	g_grim->getCurrSet()->findClosestSector(pos, &sector, &pos);
	g_grim->getCurrSet()->unshrinkBoxes();

	if (sector) {
		lua_pushnumber(pos.x());
		lua_pushnumber(pos.y());
		lua_pushnumber(pos.z());
	} else {
		lua_pushnil();
	}
}
Ejemplo n.º 7
0
void Lua_V2::WalkActorToAvoiding() {
	lua_Object actorObj = lua_getparam(1);
	lua_Object actor2Obj = lua_getparam(2);
	lua_Object xObj = lua_getparam(3);
	lua_Object yObj = lua_getparam(4);
	lua_Object zObj = lua_getparam(5);

	if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
		return;

	if (!lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKTAG('A','C','T','R'))
		return;

	Math::Vector3d destVec;
	Actor *actor = getactor(actorObj);
	if (!lua_isnumber(xObj)) {
		if (!lua_isuserdata(xObj) || lua_tag(xObj) != MKTAG('A','C','T','R'))
			return;
		Actor *destActor = getactor(xObj);
		destVec = destActor->getPos();
	} else {
		float x = lua_getnumber(xObj);
		float y = lua_getnumber(yObj);
		float z = lua_getnumber(zObj);
		destVec.set(x, y, z);
	}

	// TODO: Make this actually avoid the second actor

	actor->walkTo(destVec);
}
Ejemplo n.º 8
0
void Lua_V2::GetActorPuckVector() {
	lua_Object actorObj = lua_getparam(1);
	lua_Object addObj = lua_getparam(2);

	if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
		lua_pushnil();
		return;
	}

	Actor *actor = getactor(actorObj);
	// Note: The wear chore of dumbshadow.cos is only started from Lua if
	// GetActorPuckVector returns a non-nil value. The original engine seems
	// to return nil for all actors that have never followed walkboxes.
	if (!actor || !actor->hasFollowedBoxes()) {
		lua_pushnil();
		return;
	}

	Math::Vector3d result = actor->getPuckVector();
	if (!lua_isnil(addObj))
		result += actor->getPos();

	lua_pushnumber(result.x());
	lua_pushnumber(result.y());
	lua_pushnumber(result.z());
}
Ejemplo n.º 9
0
// Find the closest point on the walkplane to the given point
Math::Vector3d Sector::getClosestPoint(const Math::Vector3d &point) const {
	// First try to project to the plane
	Math::Vector3d p2 = getProjectionToPlane(point);
	if (isPointInSector(p2))
		return p2;

	// Now try to project to some edge
	for (int i = 0; i < _numVertices; i++) {
		Math::Vector3d edge = _vertices[i + 1] - _vertices[i];
		Math::Vector3d delta = point - _vertices[i];
		float scalar = Math::Vector3d::dotProduct(delta, edge) / Math::Vector3d::dotProduct(edge, edge);
		Math::Vector3d cross = Math::Vector3d::crossProduct(delta, edge);
		if (scalar >= 0 && scalar <= 1 && cross.dotProduct(_normal) > 0)
			// 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]).getMagnitude();
	int index = 0;
	for (int i = 1; i < _numVertices; i++) {
		float currDist = (point - _vertices[i]).getMagnitude();
		if (currDist < minDist) {
			minDist = currDist;
			index = i;
		}
	}
	return _vertices[index];
}
Ejemplo n.º 10
0
Math::Vector3d Sector::getProjectionToPuckVector(const Math::Vector3d &v) const {
	if (_normal.z() == 0)
		error("Trying to walk along vertical plane");

	Math::Vector3d result = v;
	result.z() -= Math::Vector3d::dotProduct(_normal, v) / _normal.z();
	return result;
}
Ejemplo n.º 11
0
Command *Command::opIsItemNearPlace(const ResourceReference &itemRef, const ResourceReference &positionRef, int32 testDistance) {
	FloorPositionedItem *item = itemRef.resolve<FloorPositionedItem>();

	Math::Vector3d itemPostion = item->getPosition3D();
	Math::Vector3d testPosition = getObjectPosition(positionRef);

	return nextCommandIf(itemPostion.getDistanceTo(testPosition) < testDistance);
}
Ejemplo n.º 12
0
Math::Vector3d Sector::getProjectionToPlane(const Math::Vector3d &point) const {
	if (_normal.z() == 0)
		error("Trying to walk along vertical plane");

	// Formula: return p - (n . (p - v_0))/(n . k) k
	Math::Vector3d result = point;
	result.z() -= Math::Vector3d::dotProduct(_normal, point - _vertices[0]) / _normal.z();
	return result;
}
Ejemplo n.º 13
0
bool Sector::isPointInSector(const Math::Vector3d &point) const {
	// Calculate the distance of the point from the plane of the sector.
	// Return false if it isn't within a margin.
	if (_height < 9000.f) { // No need to check when height is 9999.
		// The plane has equation ax + by + cz + d = 0
		float a = _normal.x();
		float b = _normal.y();
		float c = _normal.z();
		float d = -_vertices[0].x() * a - _vertices[0].y() * b - _vertices[0].z() * c;

		float dist = (a * point.x() + b * point.y() + c * point.z() + d) /
					sqrt(a * a + b * b + c * c);
		// dist is positive if it is above the plain, negative if it is
		// below and 0 if it is on the plane.

		if (fabsf(dist) > _height + 0.01) // Add an error margin
			return false;
	}

	// On the plane, so check if it is inside the polygon.
	for (int i = 0; i < _numVertices; i++) {
		Math::Vector3d edge = _vertices[i + 1] - _vertices[i];
		Math::Vector3d delta = point - _vertices[i];
		if (edge.x() * delta.y() < edge.y() * delta.x())
			return false;
	}
	return true;
}
Ejemplo n.º 14
0
static Math::Vector3d directionToVector(float pitch, float heading) {
	Math::Vector3d v;

	float radHeading = Common::deg2rad(heading);
	float radPitch = Common::deg2rad(pitch);

	v.setValue(0, cos(radPitch) * cos(radHeading));
	v.setValue(1, sin(radPitch));
	v.setValue(2, cos(radPitch) * sin(radHeading));

	return v;
}
Ejemplo n.º 15
0
Math::Angle Actor::getYawTo(Actor *a) const {
	Math::Vector3d forwardVec = getSimplePuckVector();
	Math::Vector3d delta = a->getPos() - _pos;

	if (g_grim->getGameType() == GType_MONKEY4) {
		delta.y() = 0;
	} else {
		delta.z() = 0;
	}

	return Math::Vector3d::angle(forwardVec, delta);
}
Ejemplo n.º 16
0
float Sector::distanceToPoint(const Math::Vector3d &point) const {
	// The plane has equation ax + by + cz + d = 0
	float a = _normal.x();
	float b = _normal.y();
	float c = _normal.z();
	float d = -_vertices[0].x() * a - _vertices[0].y() * b - _vertices[0].z() * c;

	// dist is positive if it is above the plain, negative if it is
	// below and 0 if it is on the plane.
	float dist = (a * point.x() + b * point.y() + c * point.z() + d);
	dist /= sqrt(a * a + b * b + c * c);
	return dist;
}
Ejemplo n.º 17
0
Math::Vector3d Actor::getTangentPos(const Math::Vector3d &pos, const Math::Vector3d &dest) const {
	if (_collisionMode == CollisionOff) {
		return dest;
	}

	Model *model = getCurrentCostume()->getModel();
	Math::Vector3d p = _pos + model->_insertOffset;
	float size = model->_radius * _collisionScale;

	Math::Vector2d p1(pos.x(), pos.y());
	Math::Vector2d p2(dest.x(), dest.y());
	Math::Segment2d segment(p1, p2);

	// TODO: collision with Box
// 	if (_collisionMode == CollisionSphere) {
		Math::Vector2d center(p.x(), p.y());

		Math::Vector2d inter;
		float distance = segment.getLine().getDistanceTo(center, &inter);

		if (distance < size && segment.containsPoint(inter)) {
			Math::Vector2d v(inter - center);
			v.normalize();
			v *= size;
			v += center;

			return Math::Vector3d(v.getX(), v.getY(), dest.z());
		}
// 	} else {

// 	}

	return dest;
}
Ejemplo n.º 18
0
void Lua_V2::GetActorWorldPos() {
	lua_Object actorObj = lua_getparam(1);

	if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
		return;

	Actor *actor = getactor(actorObj);
	if (!actor)
		return;

	Math::Vector3d pos = actor->getWorldPos();
	lua_pushnumber(pos.x());
	lua_pushnumber(pos.y());
	lua_pushnumber(pos.z());
}
Ejemplo n.º 19
0
float Movement::computeAngleBetweenVectorsXYPlane(const Math::Vector3d &v1, const Math::Vector3d &v2) const {
	Math::Vector3d v1XY = v1;
	v1XY.z() = 0.0;

	Math::Vector3d v2XY = v2;
	v2XY.z() = 0.0;

	Math::Angle angle = Math::Vector3d::angle(v1XY, v2XY);
	Math::Vector3d cross = Math::Vector3d::crossProduct(v1XY, v2XY);
	if (cross.z() < 0) {
		angle = -angle;
	}

	return angle.getDegrees();
}
Ejemplo n.º 20
0
void BaseRenderer::screenPosToDirection(const Common::Point screen, float &pitch, float &heading) {
	// Screen coords to 3D coords
	Math::Vector3d obj;
	Math::gluMathUnProject(Math::Vector3d(screen.x, _system->getHeight() - screen.y, 0.9f), _mvpMatrix, frameViewport(), obj);

	// 3D coords to polar coords
	obj.normalize();

	Math::Vector2d horizontalProjection = Math::Vector2d(obj.x(), obj.z());
	horizontalProjection.normalize();

	pitch = 90 - Math::Angle::arcCosine(obj.y()).getDegrees();
	heading = Math::Angle::arcCosine(horizontalProjection.getY()).getDegrees();

	if (horizontalProjection.getX() > 0.0)
		heading = 360 - heading;
}
Ejemplo n.º 21
0
void TinyGLRenderer::screenPosToDirection(const Common::Point screen, float &pitch, float &heading) {
	// Screen coords to 3D coords
	Math::Vector3d obj;
	Math::gluMathUnProject<float, int>(Math::Vector3d(screen.x, kOriginalHeight - screen.y, 0.9),
		_cubeModelViewMatrix, _cubeProjectionMatrix, _cubeViewport, obj);

	// 3D coords to polar coords
	obj.normalize();

	Math::Vector2d horizontalProjection = Math::Vector2d(obj.x(), obj.z());
	horizontalProjection.normalize();

	pitch = 90 - Math::Angle::arcCosine(obj.y()).getDegrees();
	heading = Math::Angle::arcCosine(horizontalProjection.getY()).getDegrees();

	if (horizontalProjection.getX() > 0.0)
		heading = 360 - heading;
}
Ejemplo n.º 22
0
void Renderer::screenPosToDirection(const Common::Point screen, float &pitch, float &heading) {
	double x, y, z;

	// Screen coords to 3D coords
	gluUnProject(screen.x, kOriginalHeight - screen.y, 0.9, _cubeModelViewMatrix, _cubeProjectionMatrix, (GLint *)_cubeViewport, &x, &y, &z);

	// 3D coords to polar coords
	Math::Vector3d v = Math::Vector3d(x, y, z);
	v.normalize();

	Math::Vector2d horizontalProjection = Math::Vector2d(v.x(), v.z());
	horizontalProjection.normalize();

	pitch = 90 - Math::Angle::arcCosine(v.y()).getDegrees();
	heading = Math::Angle::arcCosine(horizontalProjection.getY()).getDegrees();

	if (horizontalProjection.getX() > 0.0)
		heading = 360 - heading;
}
Ejemplo n.º 23
0
void Lua_V1::GetSectorOppositeEdge() {
	lua_Object actorObj = lua_getparam(1);
	lua_Object nameObj = lua_getparam(2);

	if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
		return;

	if (!lua_isstring(nameObj)) {
		lua_pushnil();
		return;
	}

	Actor *actor = getactor(actorObj);
	const char *name = lua_getstring(nameObj);

	int numSectors = g_grim->getCurrSet()->getSectorCount();
	for (int i = 0; i < numSectors; i++) {
		Sector *sector = g_grim->getCurrSet()->getSectorBase(i);
		if (strmatch(sector->getName(), name)) {
			if (sector->getNumVertices() != 4)
				warning("GetSectorOppositeEdge(): cheat box with %d (!= 4) edges!", sector->getNumVertices());
			Math::Vector3d* vertices = sector->getVertices();
			Sector::ExitInfo e;

			sector->getExitInfo(actor->getPos(), -actor->getPuckVector(), &e);
			float frac = (e.exitPoint - vertices[e.edgeVertex + 1]).getMagnitude() / e.edgeDir.getMagnitude();
			e.edgeVertex -= 2;
			if (e.edgeVertex < 0)
				e.edgeVertex += sector->getNumVertices();
			Math::Vector3d edge = vertices[e.edgeVertex + 1] - vertices[e.edgeVertex];
			Math::Vector3d p = vertices[e.edgeVertex] + edge * frac;
			lua_pushnumber(p.x());
			lua_pushnumber(p.y());
			lua_pushnumber(p.z());

			return;
		}
	}

	lua_pushnil();
}
Ejemplo n.º 24
0
bool Sector::isPointInSector(const Math::Vector3d &point) const {
	// Calculate the distance of the point from the plane of the sector.
	// Return false if it isn't within a margin.
	if (_height < 9000.f) { // No need to check when height is 9999.

		float dist = distanceToPoint(point);

		if (fabsf(dist) > _height + 0.01) // Add an error margin
			return false;
	}

	// On the plane, so check if it is inside the polygon.
	for (int i = 0; i < _numVertices; i++) {
		Math::Vector3d edge = _vertices[i + 1] - _vertices[i];
		Math::Vector3d delta = point - _vertices[i];
		Math::Vector3d cross = Math::Vector3d::crossProduct(edge, delta);
		if (cross.dotProduct(_normal) < -0.000001f) // not "< 0.f" here, since the value could be something like -7.45058e-09 and it
			return false;                        // shuoldn't return. that was causing issue #610 (infinite loop in de.forklift_actor.dismount)
	}
	return true;
}
Ejemplo n.º 25
0
void Set::setSoundPosition(const char *soundName, const Math::Vector3d &pos, int minVol, int maxVol) {
	// TODO: The volume and pan needs to be updated when the setup changes.
	Math::Vector3d cameraPos = _currSetup->_pos;
	Math::Vector3d vector = pos - cameraPos;
	float distance = vector.getMagnitude();
	float diffVolume = maxVol - minVol;
	//This 8.f is a guess, so it may need some adjusting
	int newVolume = (int)(8.f * diffVolume / distance);
	newVolume += minVol;
	if (newVolume > _maxVolume)
		newVolume = _maxVolume;
	g_sound->setVolume(soundName, newVolume);

	Math::Vector3d cameraVector =_currSetup->_interest - _currSetup->_pos;
	Math::Vector3d up(0,0,1);
	Math::Vector3d right;
	cameraVector.normalize();
	float roll = -_currSetup->_roll * LOCAL_PI / 180.f;
	float cosr = cos(roll);
	// Rotate the up vector by roll.
	up = up * cosr + Math::Vector3d::crossProduct(cameraVector, up) * sin(roll) +
		cameraVector * Math::Vector3d::dotProduct(cameraVector, up) * (1 - cosr);
	right = Math::Vector3d::crossProduct(cameraVector, up);
	right.normalize();
	float angle = atan2(Math::Vector3d::dotProduct(vector, right),
						Math::Vector3d::dotProduct(vector, cameraVector));
	float pan = sin(angle);
	g_sound->setPan(soundName, (int)((pan + 1.f) / 2.f * 127.f + 0.5f));
}
Ejemplo n.º 26
0
void Sector::getExitInfo(const Math::Vector3d &s, const Math::Vector3d &dirVec, struct ExitInfo *result) const {
	Math::Vector3d start = getProjectionToPlane(s);
	Math::Vector3d dir = getProjectionToPuckVector(dirVec);

	// 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++) {
		Math::Vector3d delta = _vertices[i] - start;
		Math::Vector3d cross = Math::Vector3d::crossProduct(delta, dir);
		if (cross.dotProduct(_normal) > 0)
			break;
	}

	// Now continue until the cross product has negative
	// z-component.
	while (i < _numVertices) {
		i++;
		Math::Vector3d delta = _vertices[i] - start;
		Math::Vector3d cross = Math::Vector3d::crossProduct(delta, dir);
		if (cross.dotProduct(_normal) <= 0)
			break;
	}

	result->edgeDir = _vertices[i] - _vertices[i - 1];
	result->angleWithEdge = Math::Vector3d::angle(dir, result->edgeDir);
	result->edgeVertex = i - 1;

	Math::Vector3d edgeNormal = Math::Vector3d::crossProduct(result->edgeDir, _normal);
	float d = Math::Vector3d::dotProduct(dir, edgeNormal);
	// This is 0 for the albinizod monster in the at set
	if (!d)
		d = 1.f;
	result->exitPoint = start + (Math::Vector3d::dotProduct(_vertices[i] - start, edgeNormal) / d) * dir;
}
Ejemplo n.º 27
0
Math::Angle Actor::getYawTo(const Math::Vector3d &p) const {
	Math::Vector3d dpos = p - _pos;

	if (g_grim->getGameType() == GType_MONKEY4) {
		dpos.y() = dpos.z();
	}
	if (dpos.x() == 0 && dpos.y() == 0)
		return 0;
	else
		return Math::Angle::arcTangent2(-dpos.x(), dpos.y());
}
Ejemplo n.º 28
0
void Lua_V2::GetActorPuckVector() {
	lua_Object actorObj = lua_getparam(1);
	lua_Object addObj = lua_getparam(2);

	if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) {
		lua_pushnil();
		return;
	}

	Actor *actor = getactor(actorObj);
	if (!actor) {
		lua_pushnil();
		return;
	}

	Math::Vector3d result = actor->getPuckVector();
	if (!lua_isnil(addObj))
		result += actor->getPos();

	lua_pushnumber(result.x());
	lua_pushnumber(result.y());
	lua_pushnumber(result.z());
}
Ejemplo n.º 29
0
bool FloorFace::isPointInside(const Math::Vector3d &point) const {
	// Compute the barycentric coordinates of the point in the triangle
	float area = 1.0 / 2.0
			* (-_vertices[1].y() * _vertices[2].x()
					+ _vertices[0].y() * (-_vertices[1].x() + _vertices[2].x())
					+ _vertices[0].x() * (_vertices[1].y() - _vertices[2].y())
					+ _vertices[1].x() * _vertices[2].y());

	int32 sign = area < 0 ? -1 : 1;

	float s = (_vertices[0].y() * _vertices[2].x() - _vertices[0].x() * _vertices[2].y()
			+ (_vertices[2].y() - _vertices[0].y()) * point.x()
			+ (_vertices[0].x() - _vertices[2].x()) * point.y())
					* sign;

	float t = (_vertices[0].x() * _vertices[1].y() - _vertices[0].y() * _vertices[1].x()
			+ (_vertices[0].y() - _vertices[1].y()) * point.x()
			+ (_vertices[1].x() - _vertices[0].x()) * point.y())
					* sign;

	// Check the coordinates are in the triangle
	return s > 0 && t > 0 && (s + t) < 2.0 * area * sign;
}
Ejemplo n.º 30
0
void FloorFace::computePointHeight(Math::Vector3d &point) const {
	// Compute the barycentric coordinates of the point in the triangle
	float area = 1.0 / 2.0
			* (-_vertices[1].y() * _vertices[2].x()
					+ _vertices[0].y() * (-_vertices[1].x() + _vertices[2].x())
					+ _vertices[0].x() * (_vertices[1].y() - _vertices[2].y())
					+ _vertices[1].x() * _vertices[2].y());

	float s = (_vertices[0].y() * _vertices[2].x() - _vertices[0].x() * _vertices[2].y()
			+ (_vertices[2].y() - _vertices[0].y()) * point.x()
			+ (_vertices[0].x() - _vertices[2].x()) * point.y())
					/ (2.0 * area);

	float t = (_vertices[0].x() * _vertices[1].y() - _vertices[0].y() * _vertices[1].x()
			+ (_vertices[0].y() - _vertices[1].y()) * point.x()
			+ (_vertices[1].x() - _vertices[0].x()) * point.y())
					/ (2.0 * area);

	// Compute the Z coordinate of the point
	float pointZ = (1.0 - s - t) * _vertices[0].z() + s * _vertices[1].z() + t * _vertices[2].z();

	point.setValue(2, pointZ);
}