Пример #1
0
void Model::getTooltipAnchor(float &x, float &y, float &z) const {
	Common::TransformationMatrix pos = _absolutePosition;

	pos.translate(0.0, 0.0, _absoluteBoundBox.getHeight() + 0.5);

	pos.getPosition(x, y, z);
}
Пример #2
0
bool GraphicsManager::project(float x, float y, float z, float &sX, float &sY, float &sZ) {
	// This is our projection matrix
	Common::TransformationMatrix proj(_projection);


	// Generate the model matrix

	Common::TransformationMatrix model;

	float cPos[3];
	float cOrient[3];

	memcpy(cPos   , CameraMan.getPosition   (), 3 * sizeof(float));
	memcpy(cOrient, CameraMan.getOrientation(), 3 * sizeof(float));

	// Apply camera orientation
	model.rotate(-cOrient[0], 1.0f, 0.0f, 0.0f);
	model.rotate( cOrient[1], 0.0f, 1.0f, 0.0f);
	model.rotate(-cOrient[2], 0.0f, 0.0f, 1.0f);

	// Apply camera position
	model.translate(-cPos[0], -cPos[1], cPos[2]);


	Common::Vector3 coords(x, y, z);

	// Multiply them
	Common::Vector3 v(proj * model * coords);

	// Projection divide

	if (v._w == 0.0f)
		return false;

	float divider = 1.0f / v._w;
	v *= divider;

	// Viewport coordinates

	float view[4];

	view[0] = 0.0f;
	view[1] = 0.0f;
	view[2] = _width;
	view[3] = _height;


	sX = view[0] + view[2] * (v._x + 1.0f) / 2.0f;
	sY = view[1] + view[3] * (v._y + 1.0f) / 2.0f;
	sZ =                     (v._z + 1.0f) / 2.0f;

	sX -= view[2] / 2.0f;
	sY -= view[3] / 2.0f;
	return true;
}
Пример #3
0
void Model::calculateDistance() {
	if (_type == kModelTypeGUIFront) {
		_distance = _position[2];
		return;
	}


	Common::TransformationMatrix center = _absolutePosition;

	center.translate(_center[0], _center[1], _center[2]);


	const float cameraX =  CameraMan.getPosition()[0];
	const float cameraY =  CameraMan.getPosition()[1];
	const float cameraZ = -CameraMan.getPosition()[2];

	const float x = ABS(center.getX() - cameraX);
	const float y = ABS(center.getY() - cameraY);
	const float z = ABS(center.getZ() - cameraZ);


	_distance = x + y + z;
}
Пример #4
0
bool GraphicsManager::unproject(float x, float y,
                                float &x1, float &y1, float &z1,
                                float &x2, float &y2, float &z2) const {

	try {
		// Generate the inverse of the model matrix

		Common::TransformationMatrix model;

		float cPos[3];
		float cOrient[3];

		memcpy(cPos   , CameraMan.getPosition   (), 3 * sizeof(float));
		memcpy(cOrient, CameraMan.getOrientation(), 3 * sizeof(float));

		// Apply camera position
		model.translate(cPos[0], cPos[1], -cPos[2]);

		// Apply camera orientation
		model.rotate( cOrient[2], 0.0f, 0.0f, 1.0f);
		model.rotate(-cOrient[1], 0.0f, 1.0f, 0.0f);
		model.rotate( cOrient[0], 1.0f, 0.0f, 0.0f);


		// Multiply with the inverse of our projection matrix
		model *= _projectionInv;


		// Coordinates at the near and far clipping planes
		Common::Vector3 coordsNear, coordsFar;

		if (_projectType == kProjectTypePerspective) {
			/* With a perspective projection, the viewport runs from -1.0 to 0.0
			 * on the x and y axes, and the clipping planes are at 0.0 and 1.0. */

			const float view[4] = { 0.0f, 0.0f, (float) _width, (float) _height };
			const float zNear   = 0.0f;
			const float zFar    = 1.0f;

			coordsNear._x = ((2 * (x - view[0])) / (view[2])) - 1.0f;
			coordsNear._y = ((2 * (y - view[1])) / (view[3])) - 1.0f;
			coordsNear._z = (2 * zNear) - 1.0f;
			coordsNear._w = 1.0f;

			coordsFar._x = ((2 * (x - view[0])) / (view[2])) - 1.0f;
			coordsFar._y = ((2 * (y - view[1])) / (view[3])) - 1.0f;
			coordsFar._z = (2 * zFar) - 1.0f;
			coordsFar._w = 1.0f;

		} else if (_projectType == kProjectTypeOrthogonal) {
			/* With an orthogonal projection, the viewport runs from 0.0 to width
			 * on the x axis and from 0.0 to height on the y axis (which already
			 * matches the coordinates we were given), and the clipping planes are
			 * at -clipNear and -clipFar. */

			coordsNear._x = x;
			coordsNear._y = y;
			coordsNear._z = -_clipNear;
			coordsNear._w = 1.0f;

			coordsFar._x = x;
			coordsFar._y = y;
			coordsFar._z = -_clipFar;
			coordsFar._w = 1.0f;
		}

		// Unproject
		Common::Vector3 oNear(model * coordsNear);
		Common::Vector3 oFar (model * coordsFar );
		if ((oNear._w == 0.0f) || (oFar._w == 0.0f))
			return false; // TODO: check for close to 0.0f, not exactly 0.0f.


		// And return the values

		oNear._w = 1.0f / oNear._w;

		x1 = oNear._x * oNear._w;
		y1 = oNear._y * oNear._w;
		z1 = oNear._z * oNear._w;

		oFar._w = 1.0f / oFar._w;

		x2 = oFar._x * oFar._w;
		y2 = oFar._y * oFar._w;
		z2 = oFar._z * oFar._w;

	} catch (Common::Exception &e) {
		Common::printException(e, "WARNING: ");
		return false;
	} catch (...) {
		return false;
	}

	return true;
}
Пример #5
0
bool GraphicsManager::unproject(float x, float y,
                                float &x1, float &y1, float &z1,
                                float &x2, float &y2, float &z2) const {

	try {
		// Generate the inverse of the model matrix

		Common::TransformationMatrix model;

		float cPos[3];
		float cOrient[3];

		CameraMan.lock();
		memcpy(cPos   , CameraMan.getPosition   (), 3 * sizeof(float));
		memcpy(cOrient, CameraMan.getOrientation(), 3 * sizeof(float));
		CameraMan.unlock();

		// Apply camera position
		model.translate(cPos[0], cPos[1], -cPos[2]);

		// Apply camera orientation
		model.rotate( cOrient[2], 0.0, 0.0, 1.0);
		model.rotate(-cOrient[1], 0.0, 1.0, 0.0);
		model.rotate( cOrient[0], 1.0, 0.0, 0.0);


		// Multiply with the inverse of our projection matrix
		model *= _projectionInv;


		// Viewport coordinates

		float view[4];

		view[0] = 0.0;
		view[1] = 0.0;
		view[2] = _screen->w;
		view[3] = _screen->h;

		float zNear = 0.0;
		float zFar  = 1.0;


		// Generate a matrix for the coordinates at the near plane

		Common::Matrix coordsNear(4, 1);

		coordsNear(0, 0) = ((2 * (x - view[0])) / (view[2])) - 1.0;
		coordsNear(1, 0) = ((2 * (y - view[1])) / (view[3])) - 1.0;
		coordsNear(2, 0) = (2 * zNear) - 1.0;
		coordsNear(3, 0) = 1.0;



		// Generate a matrix for the coordinates at the far plane

		Common::Matrix coordsFar(4, 1);

		coordsFar(0, 0) = ((2 * (x - view[0])) / (view[2])) - 1.0;
		coordsFar(1, 0) = ((2 * (y - view[1])) / (view[3])) - 1.0;
		coordsFar(2, 0) = (2 * zFar) - 1.0;
		coordsFar(3, 0) = 1.0;


		// Unproject
		Common::Matrix oNear(model * coordsNear);
		Common::Matrix oFar (model * coordsFar );
		if ((oNear(3, 0) == 0.0) || (oNear(3, 0) == 0.0))
			return false;


		// And return the values

		oNear(3, 0) = 1.0 / oNear(3, 0);

		x1 = oNear(0, 0) * oNear(3, 0);
		y1 = oNear(1, 0) * oNear(3, 0);
		z1 = oNear(2, 0) * oNear(3, 0);

		oFar(3, 0) = 1.0 / oFar(3, 0);

		x2 = oFar(0, 0) * oFar(3, 0);
		y2 = oFar(1, 0) * oFar(3, 0);
		z2 = oFar(2, 0) * oFar(3, 0);

	} catch (Common::Exception &e) {
		Common::printException(e, "WARNING: ");
		return false;
	} catch (...) {
		return false;
	}

	return true;
}
Пример #6
0
bool GraphicsManager::project(float x, float y, float z, float &sX, float &sY, float &sZ) {
	// This is our projection matrix
	Common::Matrix proj = _projection;


	// Generate the model matrix

	Common::TransformationMatrix model;

	float cPos[3];
	float cOrient[3];

	CameraMan.lock();
	memcpy(cPos   , CameraMan.getPosition   (), 3 * sizeof(float));
	memcpy(cOrient, CameraMan.getOrientation(), 3 * sizeof(float));
	CameraMan.unlock();

	// Apply camera orientation
	model.rotate(-cOrient[0], 1.0, 0.0, 0.0);
	model.rotate( cOrient[1], 0.0, 1.0, 0.0);
	model.rotate(-cOrient[2], 0.0, 0.0, 1.0);

	// Apply camera position
	model.translate(-cPos[0], -cPos[1], cPos[2]);


	// Generate a matrix for the coordinates

	Common::Matrix coords(4, 1);

	coords(0, 0) = x;
	coords(1, 0) = y;
	coords(2, 0) = z;
	coords(3, 0) = 1.0;


	// Multiply them
	Common::Matrix v(proj * model * coords);


	// Projection divide

	if (v(3, 0) == 0.0)
		return false;

	v(0, 0) /= v(3, 0);
	v(1, 0) /= v(3, 0);
	v(2, 0) /= v(3, 0);

	// Viewport coordinates

	float view[4];

	view[0] = 0.0;
	view[1] = 0.0;
	view[2] = _screen->w;
	view[3] = _screen->h;


	sX = view[0] + view[2] * (v(0, 0) + 1.0) / 2.0;
	sY = view[1] + view[3] * (v(1, 0) + 1.0) / 2.0;
	sZ =                     (v(2, 0) + 1.0) / 2.0;

	sX -= view[2] / 2.0;
	sY -= view[3] / 2.0;
	return true;
}