Beispiel #1
0
Command *Command::opItemLookDirection(Script *script, const ResourceReference &itemRef, int32 direction, bool suspend) {
	FloorPositionedItem *item = itemRef.resolve<FloorPositionedItem>();

	Current *current = StarkGlobal->getCurrent();
	Camera *camera = current->getCamera();
	Math::Angle cameraAngle = camera->getHorizontalAngle();
	Math::Angle targetAngle = direction + cameraAngle;

	Math::Matrix3 rot;
	rot.buildAroundZ(-targetAngle);

	Math::Vector3d directionVector(1.0, 0.0, 0.0);
	rot.transformVector(&directionVector);

	Turn *movement = new Turn(item);
	movement->setTargetDirection(directionVector);
	movement->start();

	item->setMovement(movement);

	if (suspend) {
		script->suspend(item);
		item->setMovementSuspendedScript(script);
		return this; // Stay on the same command while suspended
	} else {
		return nextCommand();
	}
}
Beispiel #2
0
/* RotateVector takes a vector and rotates it around
 * the point (0,0,0) by the requested number of degrees.
 * This function is used to calculate the locations for
 * getting on and off of the Bone Wagon and for going up
 * and down the slide with the chain at the end of the world.
 */
void Lua_V1::RotateVector() {
	lua_Object vecObj = lua_getparam(1);
	lua_Object rotObj = lua_getparam(2);

	if (!lua_istable(vecObj) || !lua_istable(rotObj)) {
		lua_pushnil();
		return;
	}

	lua_pushobject(vecObj);
	lua_pushstring("x");
	float x = lua_getnumber(lua_gettable());
	lua_pushobject(vecObj);
	lua_pushstring("y");
	float y = lua_getnumber(lua_gettable());
	lua_pushobject(vecObj);
	lua_pushstring("z");
	float z = lua_getnumber(lua_gettable());
	Math::Vector3d vec(x, y, z);

	lua_pushobject(rotObj);
	lua_pushstring("x");
	Math::Angle pitch = lua_getnumber(lua_gettable());
	lua_pushobject(rotObj);
	lua_pushstring("y");
	Math::Angle yaw = lua_getnumber(lua_gettable());
	lua_pushobject(rotObj);
	lua_pushstring("z");
	Math::Angle roll = lua_getnumber(lua_gettable());

	Math::Matrix3 mat;
	mat.buildFromPitchYawRoll(pitch, yaw, roll);
	mat.transformVector(&vec);

	lua_Object resObj = lua_createtable();
	lua_pushobject(resObj);
	lua_pushstring("x");
	lua_pushnumber(vec.x());
	lua_settable();
	lua_pushobject(resObj);
	lua_pushstring("y");
	lua_pushnumber(vec.y());
	lua_settable();
	lua_pushobject(resObj);
	lua_pushstring("z");
	lua_pushnumber(vec.z());
	lua_settable();

	lua_pushobject(resObj);
}
Beispiel #3
0
Math::Transform
Camera::getViewMatrix ()
{		
  Math::Transform view;
  Vector3 at (m_camera.getBack ().x + m_camera.getPosition ().x, m_camera.getBack ().y + m_camera.getPosition ().y, m_camera.getBack ().z + m_camera.getPosition ().z);
  Vector3 eye (m_camera.getPosition ());
  Vector3 up (m_camera.getUp ());
  Vector3 back = eye - at;
  back.normalize ();
  Vector3 right = up.cross(back);
  right.normalize ();
  eye.negate ();
  Math::Matrix3 rotScale (right, up, back);
  rotScale.transpose ();
  view.setOrientation (rotScale);
  Vector3 translation =  rotScale * eye;
  //Vector3 translation = -eye;
  view.setPosition (translation);
  return view;
}
Beispiel #4
0
void Walk::onGameLoop() {
	if (!_path->hasSteps()) {
		// There is no path to the destination
		stop();
		return;
	}

	Resources::Floor *floor = StarkGlobal->getCurrent()->getFloor();

	// Get the target to walk to
	Math::Vector3d currentPosition = _item3D->getPosition3D();
	Math::Vector3d target = _path->computeWalkTarget(currentPosition);

	// Compute the direction to walk into
	Math::Vector3d direction = target - currentPosition;
	direction.z() = 0;
	direction.normalize();

	// Compute the angle with the current character direction
	Math::Vector3d currentDirection = _item3D->getDirectionVector();
	float directionDeltaAngle = computeAngleBetweenVectorsXYPlane(currentDirection, direction);

	// If the angle between the current direction and the new one is too high,
	// make the character turn on itself until the angle is low enough
	if (ABS(directionDeltaAngle) > getAngularSpeed() + 0.1f) {
		_turnDirection = directionDeltaAngle < 0 ? kTurnLeft : kTurnRight;
	} else {
		_turnDirection = kTurnNone;
	}

	float distancePerGameloop = computeDistancePerGameLoop();

	Math::Vector3d newPosition;
	if (_turnDirection == kTurnNone) {
		// Compute the new position using the distance per gameloop
		if (currentPosition.getDistanceTo(target) > distancePerGameloop) {
			newPosition = currentPosition + direction * distancePerGameloop;
		} else {
			newPosition = target;
		}
	} else {
		// The character does not change position when it is turning
		newPosition = currentPosition;
		direction = currentDirection;

		Math::Matrix3 rot;
		rot.buildAroundZ(_turnDirection == kTurnLeft ? -getAngularSpeed() : getAngularSpeed());
		rot.transformVector(&direction);
	}

	// Some scripts expect the character position to be the exact destination
	if (newPosition == _destination) {
		_reachedDestination = true;
		stop();
	}

	// Update the new position's height according to the floor
	int32 newFloorFaceIndex = floor->findFaceContainingPoint(newPosition);
	if (newFloorFaceIndex >= 0) {
		floor->computePointHeightInFace(newPosition, newFloorFaceIndex);
	} else {
		warning("Item %s is walking off the floor", _item->getName().c_str());
	}

	// Update the item's properties
	_item3D->setPosition3D(newPosition);
	if (direction.getMagnitude() != 0.0) {
		_item3D->setDirection(computeAngleBetweenVectorsXYPlane(direction, Math::Vector3d(1.0, 0.0, 0.0)));
	}
	if (newFloorFaceIndex >= 0) {
		// When unable to find the face containing the new position, keep the previous one
		// to prevent draw order glitches.
		_item3D->setFloorFaceIndex(newFloorFaceIndex);
	}

	changeItemAnim();
}
void PolyhedronColliderGeometry::UpdateMassAndLocalCentroid(const ResolutionMaterial &material, float &mass, Math::Matrix3 &unitInertiaTensor, Math::Vector3 &localCentroid)
{
	auto &verts = mAdjacency.Verts();
	auto &edges = mAdjacency.Edges();
	auto &faces = mAdjacency.Faces();
	const Math::Vector3 &c = mAdjacency.Centroid();

	mass = 0.0f;
	unitInertiaTensor.ZeroOut();
	localCentroid.ZeroOut();

	float totalVolume = 0.0f;
	for (auto &face : faces)
	{
		if (!face.active)
			continue;

		// grab face verts
		int e = face.edge;
		const Math::Vector3 &v0 = verts[edges[e].vert].position;
		e = edges[e].next;
		const Math::Vector3 &v1 = verts[edges[e].vert].position;
		e = edges[e].next;
		const Math::Vector3 &v2 = verts[edges[e].vert].position;

		// volume of tetrahedron formed by face & centroid (not divided by 6)
		const float tetrahedronVolume = std::fabs((v0 - c).Dot((v1 - c).Cross(v2 - c)));

		// accumulate volume
		totalVolume += tetrahedronVolume;

		// accumulate weighted centroid
		const Math::Vector3 tetrahedronCentroid = 0.25f * (c + v0 + v1 + v2);
		localCentroid += tetrahedronVolume * tetrahedronCentroid;
	}
	if (totalVolume == 0)
		totalVolume = 1;
	localCentroid /= totalVolume;
	
	//mass = material.mDensity * totalVolume / 6.0f;
	mass = mParent->Parent().mParent->cphy->mMass * totalVolume / 6.0f;
	

	// compute inertia tensor
	for (auto &face : faces)
	{
		if (!face.active)
			continue;

		// grab face verts
		int e = face.edge;
		const Math::Vector3 &v0 = verts[edges[e].vert].position;
		e = edges[e].next;
		const Math::Vector3 &v1 = verts[edges[e].vert].position;
		e = edges[e].next;
		const Math::Vector3 &v2 = verts[edges[e].vert].position;

		// accumulate inertia tensor
		unitInertiaTensor += UnitInertiaTensorTetrahedron(c, v0, v1, v2, localCentroid);
	}
}