Example #1
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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();
}
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());
}
Example #6
0
/** 
 * Generates a lookat matrix. For reference, see 
 * http://clb.demon.fi/MathGeoLib/docs/float3x3_LookAt.php 
 */
void Matrix<3, 3>::buildFromTargetDir(const Math::Vector3d &modelForward, const Math::Vector3d &targetDirection, 
						   const Math::Vector3d &modelUp, const Math::Vector3d &worldUp)
{
    Math::Vector3d modelRight = Math::Vector3d::crossProduct(modelUp, modelForward);
	modelRight.normalize();
	Math::Vector3d worldRight = Math::Vector3d::crossProduct(worldUp, targetDirection);
	worldRight.normalize();
	Math::Vector3d perpWorldUp = Math::Vector3d::crossProduct(targetDirection, worldRight);
	perpWorldUp.normalize();
	
	Math::Matrix3 m1;
	m1.getRow(0) << worldRight.x() << worldRight.y() << worldRight.z();
	m1.getRow(1) << perpWorldUp.x() << perpWorldUp.y() << perpWorldUp.z();
	m1.getRow(2) << targetDirection.x() << targetDirection.y() << targetDirection.z();
	m1.transpose();
	
	Math::Matrix3 m2;
	m2.getRow(0) << modelRight.x() << modelRight.y() << modelRight.z();
	m2.getRow(1) << modelUp.x() << modelUp.y() << modelUp.z();
	m2.getRow(2) << modelForward.x() << modelForward.y() << modelForward.z();
	
	this->operator=(m1 * m2);
}
Example #7
0
void SaveGame::writeVector3d(const Math::Vector3d &vec) {
	writeFloat(vec.x());
	writeFloat(vec.y());
	writeFloat(vec.z());
}
Example #8
0
void AnimationEmi::animate(Skeleton *skel, float delta) {
	_time += delta;
	if (_time > _duration) {
		_time = _duration;
	}

	for (int bone = 0; bone < _numBones; ++bone) {
		Bone &curBone = _bones[bone];
		if (!curBone._target)
			curBone._target = skel->getJointNamed(curBone._boneName);

		Math::Matrix4 &relFinal = curBone._target->_finalMatrix;
		Math::Quaternion &quatFinal = curBone._target->_finalQuat;

		if (curBone._rotations) {
			int keyfIdx = 0;
			Math::Quaternion quat;
			Math::Vector3d relPos = relFinal.getPosition();

			for (int curKeyFrame = 0; curKeyFrame < curBone._count; curKeyFrame++) {
				if (curBone._rotations[curKeyFrame]._time >= _time) {
					keyfIdx = curKeyFrame;
					break;
				}
			}

			if (keyfIdx == 0) {
				quat = curBone._rotations[keyfIdx]._quat;
			} else if (keyfIdx == curBone._count - 1) {
				quat = curBone._rotations[keyfIdx - 1]._quat;
			} else {
				float timeDelta = curBone._rotations[keyfIdx - 1]._time - curBone._rotations[keyfIdx]._time;
				float interpVal = (_time - curBone._rotations[keyfIdx]._time) / timeDelta;

				// Might be the other way around (keyfIdx - 1 slerped against keyfIdx)
				quat = curBone._rotations[keyfIdx]._quat.slerpQuat(curBone._rotations[keyfIdx - 1]._quat, interpVal);
			}
			quat.toMatrix(relFinal);
			quatFinal = quat;
			relFinal.setPosition(relPos);
		}

		if (curBone._translations) {
			int keyfIdx = 0;
			Math::Vector3d vec;

			for (int curKeyFrame = 0; curKeyFrame < curBone._count; curKeyFrame++) {
				if (curBone._translations[curKeyFrame]._time >= _time) {
					keyfIdx = curKeyFrame;
					break;
				}
			}

			if (keyfIdx == 0) {
				vec = curBone._translations[keyfIdx]._vec;
			} else if (keyfIdx == curBone._count - 1) {
				vec = curBone._translations[keyfIdx - 1]._vec;
			} else {
				float timeDelta = curBone._translations[keyfIdx - 1]._time - curBone._translations[keyfIdx]._time;
				float interpVal = (_time - curBone._translations[keyfIdx]._time) / timeDelta;

				vec.x() = curBone._translations[keyfIdx - 1]._vec.x() +
						  (curBone._translations[keyfIdx]._vec.x() - curBone._translations[keyfIdx - 1]._vec.x()) * interpVal;

				vec.y() = curBone._translations[keyfIdx - 1]._vec.y() +
						  (curBone._translations[keyfIdx]._vec.y() - curBone._translations[keyfIdx - 1]._vec.y()) * interpVal;

				vec.z() = curBone._translations[keyfIdx - 1]._vec.z() +
						  (curBone._translations[keyfIdx]._vec.z() - curBone._translations[keyfIdx - 1]._vec.z()) * interpVal;
			}
			relFinal.setPosition(vec);
		}
	}

}
void ResourceSerializer::syncAsVector3d(Math::Vector3d &value) {
	syncAsFloat(value.x());
	syncAsFloat(value.y());
	syncAsFloat(value.z());
}
Example #10
0
//------------------------------------------------------------------------------
void AudioInterface::setSourceVelocity( int iId, math::Vector3d iV )
{
	ALfloat v[3];
  v[0] = iV.x(); v[1] = iV.y(); v[2] = iV.z();
	alSourcefv( iId, AL_VELOCITY, v );
}
Example #11
0
//------------------------------------------------------------------------------
void AudioInterface::setSourceDirection( int iId, math::Vector3d iV )
{
	ALfloat d[3];
  d[0] = iV.x(); d[1] = iV.y(); d[2] = iV.z();
	alSourcefv( iId, AL_DIRECTION, d );
}
Example #12
0
void Head::lookAt(bool entering, const Math::Vector3d &point, float rate, const Math::Matrix4 &matrix) {
	if (_joint1Node) {
		float step = g_grim->getPerSecond(rate);
		float yawStep = step;
		float pitchStep = step / 3.f;
		if (!entering) {
			//animate yaw
			if (_headYaw > yawStep) {
				_headYaw -= yawStep;
			} else if (_headYaw < -yawStep) {
				_headYaw += yawStep;
			} else {
				_headYaw = 0;
			}
			//animate pitch
			if (_headPitch > pitchStep) {
				_headPitch -= pitchStep;
			} else if (_headPitch < -pitchStep) {
				_headPitch += pitchStep;
			} else {
				_headPitch = 0;
			}
			_joint1Node->_animYaw = _headYaw;
			Math::Angle pi = _headPitch / 3.f;
			_joint1Node->_animPitch += pi;
			_joint2Node->_animPitch += pi;
			_joint3Node->_animPitch += pi;
			_joint1Node->_animRoll = (_joint1Node->_animYaw.getDegrees() / 20.f) *
			_headPitch.getDegrees() / -5.f;

			if (_joint1Node->_animRoll > _maxRoll)
				_joint1Node->_animRoll = _maxRoll;
			if (_joint1Node->_animRoll < -_maxRoll)
				_joint1Node->_animRoll = -_maxRoll;
			return;
		}

		ModelNode *p = _joint3Node;
		while (p->_parent) {
			p = p->_parent;
		}
		p->setMatrix(matrix);
		p->update();

		Math::Vector3d v = point - _joint3Node->_matrix.getPosition();
		if (v.isZero()) {
			return;
		}

		float magnitude = sqrt(v.x() * v.x() + v.y() * v.y());
		float a = v.x() / magnitude;
		float b = v.y() / magnitude;
		float yaw;
		yaw = acos(a) * (180.0f / LOCAL_PI);
		if (b < 0.0f)
			yaw = 360.0f - yaw;

		Math::Angle bodyYaw = matrix.getYaw();
		p = _joint1Node->_parent;
		while (p) {
			bodyYaw += p->_yaw + p->_animYaw;
			p = p->_parent;
		}

		_joint1Node->_animYaw = (- 90 + yaw - bodyYaw);
		if (_joint1Node->_animYaw < -180.) {
			_joint1Node->_animYaw += 360;
		}
		if (_joint1Node->_animYaw > 180.) {
			_joint1Node->_animYaw -= 360;
		}

		if (_joint1Node->_animYaw > _maxYaw)
			_joint1Node->_animYaw = _maxYaw;
		if (_joint1Node->_animYaw < -_maxYaw)
			_joint1Node->_animYaw = -_maxYaw;

		float sqLenght = v.x() * v.x() + v.y() * v.y();
		float h;
		if (sqLenght > 0) {
			h = sqrt(sqLenght);
		} else {
			h = -sqrt(sqLenght);
		}
		magnitude = sqrt(v.z() * v.z() + h * h);
		a = h / magnitude;
		b = v.z() / magnitude;
		Math::Angle pitch;
		pitch = acos(a) * (180.0f / LOCAL_PI);

		if (b < 0.0f)
			pitch = 360.0f - pitch;

		if (pitch > 180)
			pitch -= 360;

		if (pitch > _maxPitch)
			pitch = _maxPitch;
		if (pitch < -_maxPitch)
			pitch = -_maxPitch;

		if ((_joint1Node->_animYaw > 0 && pitch < 0) || (_joint1Node->_animYaw < 0 && pitch > 0)) {
			pitch += _joint1Node->_animYaw / 10.f;
		} else {
			pitch -= _joint1Node->_animYaw / 10.f;
		}

		//animate pitch
		if (pitch - _headPitch > pitchStep)
			pitch = _headPitch + pitchStep;
		if (_headPitch - pitch > pitchStep)
			pitch = _headPitch - pitchStep;

		Math::Angle pi = pitch / 3.f;
		_joint1Node->_animPitch += pi;
		_joint2Node->_animPitch += pi;
		_joint3Node->_animPitch += pi;

		//animate yaw
		if (_joint1Node->_animYaw - _headYaw > yawStep)
			_joint1Node->_animYaw = _headYaw + yawStep;
		if (_headYaw - _joint1Node->_animYaw > yawStep)
			_joint1Node->_animYaw = _headYaw - yawStep;

		_joint1Node->_animRoll = (_joint1Node->_animYaw.getDegrees() / 20.f) *
		pitch.getDegrees() / -5.f;

		if (_joint1Node->_animRoll > _maxRoll)
			_joint1Node->_animRoll = _maxRoll;
		if (_joint1Node->_animRoll < -_maxRoll)
			_joint1Node->_animRoll = -_maxRoll;

		_headPitch = pitch;
		_headYaw = _joint1Node->_animYaw;
	}
}
Example #13
0
void GfxOpenGL::drawModel(Model *m) {
	glEnable(GL_DEPTH_TEST);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f,(GLfloat)_screenWidth/(GLfloat)_screenHeight,0.01f,10.0f);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glColor4ub(255, 255, 255, 255);

	gluLookAt( 0, 0, 1, 0, 0, 0, 0, 1, 0 );
	glPushMatrix();

	glTranslatef((_cameraX/(float)_screenWidth), -(_cameraY/(float)_screenHeight), (_cameraZ/(float)_screenHeight));
	glRotatef(_rotY, 1, 0, 0);
	glRotatef(_rotX, 0, 1, 0);

	for (uint j = 0; j < m->_numPolygons; j++) {
		Polygon *p = &m->_polygons[j];
		glBegin(GL_POLYGON);

		for (int i = 0; i < m->_polygons->_num; ++i) {
			uint32 vert = p->_data[i];
			if (vert > m->_numVerticies || vert == 0) {
				break;
			}

			glColor4ub(_palette->_palette[p->_colour]._r, _palette->_palette[p->_colour]._g, _palette->_palette[p->_colour]._b, 255);
			Vertex *v = &m->_verticies[vert];

			if (v->_bone == 0) {
				continue;
			}
			Math::Vector3d mv = v->getPos(m);

			Normal *n = &m->_normals[vert];

			glNormal3f(n->_x, n->_y, n->_z);
			glVertex3fv(mv.getData());

		}

		glEnd();

	}

	for (uint j = 0; j < m->_numPoints; j++) {
		Point *p = &m->_points[j];
		glColor4ub(_palette->_palette[p->_colour]._r, _palette->_palette[p->_colour]._g, _palette->_palette[p->_colour]._b, 255);

		Vertex *v1 = &m->_verticies[p->_v1];
		Math::Vector3d vec1 = v1->getPos(m);
		Vertex *v2 = &m->_verticies[p->_v2];
		Math::Vector3d vec2 = v2->getPos(m);

		glBegin(GL_LINES);
		glVertex3fv(vec1.getData());
		glVertex3fv(vec2.getData());
		glEnd();
	}

	for (uint j = 0; j < m->_numSpheres; j++) {
		Sphere *s = &m->_spheres[j];
		Vertex *v = &m->_verticies[s->_vertex];
		Math::Vector3d vec = v->getPos(m);

		glColor4ub(_palette->_palette[s->_colour]._r, _palette->_palette[s->_colour]._g, _palette->_palette[s->_colour]._b, 255);

		glPushMatrix();
		glTranslatef(vec.x(), vec.y(), vec.z());
		drawSphere(s->_size, 8, 8);
		glPopMatrix();
	}	

	glPopMatrix();

	glDisable(GL_DEPTH_TEST);
}
Example #14
0
bool Actor::handleCollisionWith(Actor *actor, CollisionMode mode, Math::Vector3d *vec) const {
	if (actor->_collisionMode == CollisionOff) {
		return false;
	}

	Model *model1 = getCurrentCostume()->getModel();
	Model *model2 = actor->getCurrentCostume()->getModel();

	Math::Vector3d p1 = _pos + model1->_insertOffset;
	Math::Vector3d p2 = actor->_pos + model2->_insertOffset;

	float size1 = model1->_radius * _collisionScale;
	float size2 = model2->_radius * actor->_collisionScale;

	CollisionMode mode1 = mode;
	CollisionMode mode2 = actor->_collisionMode;

	if (mode1 == CollisionSphere && mode2 == CollisionSphere) {
		Math::Vector3d pos = p1 + *vec;
		float distance = (pos - p2).getMagnitude();
		if (distance < size1 + size2) {
			// Move the destination point so that its distance from the
			// center of the circle is size1+size2.
			Math::Vector3d v = pos - p2;
			v.normalize();
			v *= size1 + size2;
			*vec = v + p2 - p1;

			collisionHandlerCallback(actor);
			return true;
		}
	} else if (mode1 == CollisionBox && mode2 == CollisionBox) {
		warning("Collision between box and box not implemented!");
		return false;
	} else {
		Math::Rect2d rect;

		Math::Vector3d bboxPos;
		Math::Vector3d size;
		float scale;
		Math::Vector3d pos;
		Math::Vector3d circlePos;
		Math::Angle yaw;

		Math::Vector2d circle;
		float radius;

		if (mode1 == CollisionBox) {
			pos = p1 + *vec;
			bboxPos = pos + model1->_bboxPos;
			size = model1->_bboxSize;
			scale = _collisionScale;
			yaw = _yaw;

			circle.setX(p2.x());
			circle.setY(p2.y());
			circlePos = p2;
			radius = size2;
		} else {
			pos = p2;
			bboxPos = p2 + model2->_bboxPos;
			size = model2->_bboxSize;
			scale = actor->_collisionScale;
			yaw = actor->_yaw;

			circle.setX(p1.x() + vec->x());
			circle.setY(p1.y() + vec->y());
			circlePos = p1;
			radius = size1;
		}

		rect._topLeft = Math::Vector2d(bboxPos.x(), bboxPos.y() + size.y());
		rect._topRight = Math::Vector2d(bboxPos.x() + size.x(), bboxPos.y() + size.y());
		rect._bottomLeft = Math::Vector2d(bboxPos.x(), bboxPos.y());
		rect._bottomRight = Math::Vector2d(bboxPos.x() + size.x(), bboxPos.y());

		rect.scale(scale);
		rect.rotateAround(Math::Vector2d(pos.x(), pos.y()), yaw);

		if (rect.intersectsCircle(circle, radius)) {
			Math::Vector2d center = rect.getCenter();
			// Draw a line from the center of the rect to the place the character
			// would go to.
			Math::Vector2d v = circle - center;
			v.normalize();

			Math::Segment2d edge;
			// That line intersects (usually) an edge
			rect.getIntersection(center, v, &edge);
			// Take the perpendicular of that edge
			Math::Line2d perpendicular = edge.getPerpendicular(circle);

			Math::Vector3d point;
			Math::Vector2d p;
			// If that perpendicular intersects the edge
			if (edge.intersectsLine(perpendicular, &p)) {
				Math::Vector2d direction = perpendicular.getDirection();
				direction.normalize();

				// Move from the intersection until we are at a safe distance
				Math::Vector2d point1(p - direction * radius);
				Math::Vector2d point2(p + direction * radius);

				if (center.getDistanceTo(point1) < center.getDistanceTo(point2)) {
					point = point2.toVector3d();
				} else {
					point = point1.toVector3d();
				}
			} else { //if not we're around a corner
				// Find the nearest vertex of the rect
				Math::Vector2d vertex = rect.getTopLeft();
				float distance = vertex.getDistanceTo(circle);

				Math::Vector2d other = rect.getTopRight();
				float otherDist = other.getDistanceTo(circle);
				if (otherDist < distance) {
					distance = otherDist;
					vertex = other;
				}

				other = rect.getBottomLeft();
				otherDist = other.getDistanceTo(circle);
				if (otherDist < distance) {
					distance = otherDist;
					vertex = other;
				}

				other = rect.getBottomRight();
				if (other.getDistanceTo(circle) < distance) {
					vertex = other;
				}

				// and move on a circle around it
				Math::Vector2d dst = circle - vertex;
				dst.normalize();
				dst = dst * radius;
				point = (vertex + dst).toVector3d();
			}

			float z = vec->z();
			*vec = point - circlePos;
			vec->z() = z;
			collisionHandlerCallback(actor);
			return true;
		}
	}

	return false;
}