コード例 #1
0
ファイル: EmberEntity.cpp プロジェクト: Laefy/ember
float EmberEntity::getHeight(const WFMath::Point<2>& localPosition) const
{

	if (mHeightProvider) {
		float height = 0;
		if (mHeightProvider->getHeight(WFMath::Point<2>(localPosition.x(), localPosition.y()), height)) {
			return height;
		}
	}

	//A normal EmberEntity shouldn't know anything about the terrain, so we can't handle the area here.
	//Instead we just pass it on to the parent until we get to someone who knows how to handle this (preferably the terrain).
	if (getEmberLocation()) {

		WFMath::Point<2> adjustedLocalPosition(getPredictedPos().x(), getPredictedPos().y());

		WFMath::Vector<3> xVec = WFMath::Vector<3>(1.0, 0.0, 0.0).rotate(getOrientation());
		double theta = atan2(xVec.y(), xVec.x()); // rotation about Z
		WFMath::RotMatrix<2> rm;
		WFMath::Vector<2> adjustment(localPosition.x(), localPosition.y());
		adjustment.rotate(rm.rotation(theta));
		adjustedLocalPosition += adjustment;

		return getEmberLocation()->getHeight(adjustedLocalPosition) - getPredictedPos().z();
	}

	WFMath::Point<3> predictedPos = getPredictedPos();
	if (predictedPos.isValid()) {
		return predictedPos.z();
	} else {
		return 0.0f;
	}
}
コード例 #2
0
ファイル: PolygonPointMover.cpp プロジェクト: sajty/ember
void PolygonPointMover::move(const WFMath::Vector<3>& directionVector)
{
	if (directionVector.isValid()) {
		getActivePoint()->translate(WFMath::Vector<2>(directionVector.x(), directionVector.y()));
		mPolygon.updateRender();
	}
}
コード例 #3
0
void HeightMapFlatSegment::getHeightAndNormal(float x, float y, float& height, WFMath::Vector<3>& normal) const
{
  height = mHeight;
  normal.x() = 0;
  normal.y() = 0;
  normal.z() = 1;
}
コード例 #4
0
void Position2DAdapter::fillElementFromGui()
{
	WFMath::Vector<2> vector;
	if (mXWindow) {
		vector.x() = atof(mXWindow->getText().c_str()); 
	}
	if (mYWindow) {
		vector.y() = atof(mYWindow->getText().c_str()); 
	}
	mEditedElement = vector.toAtlas();
}
コード例 #5
0
void Steering::moveInDirection(const WFMath::Vector<2>& direction)
{
	WFMath::Vector<3> fullDirection(direction.x(), 0, direction.y());
	WFMath::Quaternion orientation;
	if (direction != WFMath::Vector<2>::ZERO()) {
		orientation.rotation(WFMath::Vector<3>(0, 0, 1), WFMath::Vector<3>(fullDirection).normalize(), WFMath::Vector<3>(0, 1, 0));
	}

	mAvatar.moveInDirection(fullDirection, orientation);
	mLastSentVelocity = direction;
	mExpectingServerMovement = true;
}
コード例 #6
0
ファイル: SoundService.cpp プロジェクト: sajty/ember
void SoundService::updateListenerPosition(const WFMath::Point<3>& pos, const WFMath::Vector<3>& direction, const WFMath::Vector<3>& up)
{
	if (!isEnabled()) {
		return;
	}

	alListener3f(AL_POSITION, pos.x(), pos.y(), pos.z());
	SoundGeneral::checkAlError("Setting the listener position.");

	//Set the direction of the listener.

	ALfloat aluVectors[6];
	aluVectors[0] = direction.x();
	aluVectors[1] = direction.y();
	aluVectors[2] = direction.z();
	aluVectors[3] = up.x();
	aluVectors[4] = up.y();
	aluVectors[5] = up.z();

	alListenerfv(AL_ORIENTATION, aluVectors);
	SoundGeneral::checkAlError("Setting the listener orientation.");
}
コード例 #7
0
ファイル: PolygonPointMover.cpp プロジェクト: sajty/ember
void PolygonPointMover::setPosition(const WFMath::Point<3>& position)
{
	if (position.isValid()) {
		//We need to offset into local space.
		Ogre::Vector3 posOffset = Ogre::Vector3::ZERO;
		if (getActivePoint()->getNode()->getParent()) {
			posOffset = getActivePoint()->getNode()->getParent()->_getDerivedPosition();
		}
		Ogre::Vector3 newPos = Convert::toOgre(position) - posOffset;
		newPos = getActivePoint()->getNode()->getParent()->_getDerivedOrientation().Inverse() * newPos;

		WFMath::Vector<3> translation = Convert::toWF<WFMath::Vector<3>>(newPos - getActivePoint()->getNode()->getPosition());
		//adjust it so that it moves according to the ground for example
		getActivePoint()->translate(WFMath::Vector<2>(translation.x(), translation.y()));
		mPolygon.updateRender();
	}
}
コード例 #8
0
ファイル: TerrainArea.cpp プロジェクト: Arsakes/ember
bool TerrainArea::parseArea()
{
	if (!mEntity.hasAttr("area")) {
		S_LOG_FAILURE("TerrainArea created for entity with no area attribute");
		return false;
	}

	const Atlas::Message::Element areaElem(mEntity.valueOfAttr("area"));

	if (!areaElem.isMap()) {
		S_LOG_FAILURE("TerrainArea element ('area') must be of map type.");
		return false;
	}

	const Atlas::Message::MapType& areaData(areaElem.asMap());

	int layer = 0;
	WFMath::Polygon<2> poly;
	TerrainAreaParser parser;
	if (parser.parseArea(areaData, poly, layer)) {
		if (!mArea) {
			mArea = new Mercator::Area(layer, false);
		} else {
			//A bit of an ugly hack here since the Mercator system doesn't support changing the layer. We need to swap the old area for a new one if the layer has changed.
			if (mArea->getLayer() != layer) {
				mOldArea = mArea;
				mArea = new Mercator::Area(layer, false);
			}
		}
		// transform polygon into terrain coords
		WFMath::Vector<3> xVec = WFMath::Vector<3>(1.0, 0.0, 0.0).rotate(mEntity.getOrientation());
		double theta = atan2(xVec.y(), xVec.x()); // rotation about Z

		WFMath::RotMatrix<2> rm;
		poly.rotatePoint(rm.rotation(theta), WFMath::Point<2>(0, 0));
		poly.shift(WFMath::Vector<2>(mEntity.getPosition().x(), mEntity.getPosition().y()));

		mArea->setShape(poly);

		return true;
	} else {
		return false;
	}
}
コード例 #9
0
Mercator::TerrainMod* InnerTranslatorImpl<ModT, ShapeT>::createInstance(const WFMath::Point<3>& pos, const WFMath::Quaternion& orientation)
{
	ShapeT<2> shape = this->mShape;

	if (!shape.isValid() || !pos.isValid()) {
		return nullptr;
	}

	if (orientation.isValid()) {
		/// rotation about Z axis
		WFMath::Vector<3> xVec = WFMath::Vector<3>(1.0, 0.0, 0.0).rotate(orientation);
		WFMath::CoordType theta = std::atan2(xVec.y(), xVec.x());
		WFMath::RotMatrix<2> rm;
		shape.rotatePoint(rm.rotation(theta), WFMath::Point<2>(0, 0));
	}

	shape.shift(WFMath::Vector<2>(pos.x(), pos.y()));
	float level = TerrainModTranslator::parsePosition(pos, this->mData);
	return new ModT<ShapeT>(level, shape);
}
コード例 #10
0
ファイル: TerrainArea.cpp プロジェクト: sajty/ember
bool TerrainArea::placeArea(WFMath::Polygon<2>& poly)
{
	//If the position if invalid we can't do anything with the area yet.
	if (!mEntity.getPosition().isValid()) {
		return false;
	}

	// transform polygon into terrain coords

	if (mEntity.getOrientation().isValid()) {
		WFMath::Vector<3> xVec = WFMath::Vector<3>(1.0, 0.0, 0.0).rotate(mEntity.getOrientation());
		double theta = atan2(xVec.y(), xVec.x()); // rotation about Z

		WFMath::RotMatrix<2> rm;
		poly.rotatePoint(rm.rotation(theta), WFMath::Point<2>(0, 0));
	}
	poly.shift(WFMath::Vector<2>(mEntity.getPosition().x(), mEntity.getPosition().y()));


	return true;
}
コード例 #11
0
ファイル: SoundSource.cpp プロジェクト: Arsakes/ember
void SoundSource::setVelocity(const WFMath::Vector<3>& vel)
{
	assert(vel.isValid());
	alSource3f(mALSource, AL_VELOCITY, vel.x(), vel.y(), vel.z());
	SoundGeneral::checkAlError("Setting sound source velocity.");
}
コード例 #12
0
void Steering::update()
{
	if (mSteeringEnabled) {
		if (mUpdateNeeded) {
			updatePath();
		}
		auto entity = mAvatar.getEntity();
		if (!mPath.empty()) {
			const auto& finalDestination = mPath.back();
			auto entity3dPosition = entity->getViewPosition();
			const WFMath::Point<2> entityPosition(entity3dPosition.x(), entity3dPosition.z());
			//First check if we've arrived at our actual destination.
			if (WFMath::Distance(WFMath::Point<2>(finalDestination.x(), finalDestination.z()), entityPosition) < 0.1f) {
				//We've arrived at our destination. If we're moving we should stop.
				if (mLastSentVelocity.isValid() && mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
					moveInDirection(WFMath::Vector<2>::ZERO());
				}
				stopSteering();
			} else {
				//We should send a move op if we're either not moving, or we've reached a waypoint, or we need to divert a lot.

				WFMath::Point<2> nextWaypoint(mPath.front().x(), mPath.front().z());
				if (WFMath::Distance(nextWaypoint, entityPosition) < 0.1f) {
					mPath.pop_front();
					nextWaypoint = WFMath::Point<2>(mPath.front().x(), mPath.front().z());
				}

				WFMath::Vector<2> velocity = nextWaypoint - entityPosition;
				WFMath::Point<2> destination;
				velocity.normalize();

				if (mPath.size() == 1) {
					//if the next waypoint is the destination we should send a "move to position" update to the server, to make sure that we stop when we've arrived.
					//otherwise, if there's too much lag, we might end up overshooting our destination and will have to double back
					destination = nextWaypoint;
				}

				//Check if we need to divert in order to avoid colliding.
				WFMath::Vector<2> newVelocity;
				bool avoiding = mAwareness.avoidObstacles(entityPosition, velocity * mSpeed, newVelocity);
				if (avoiding) {
					auto newMag = newVelocity.mag();
					auto relativeMag = mSpeed / newMag;

					velocity = newVelocity;
					velocity.normalize();
					velocity *= relativeMag;
					mUpdateNeeded = true;
				}

				bool shouldSend = false;
				if (velocity.isValid()) {
					if (mLastSentVelocity.isValid()) {
						//If the entity has stopped, and we're not waiting for confirmation to a movement request we've made, we need to start moving.
						if (!entity->isMoving() && !mExpectingServerMovement) {
							shouldSend = true;
						} else {
							auto currentTheta = std::atan2(mLastSentVelocity.y(), mLastSentVelocity.x());
							auto newTheta = std::atan2(velocity.y(), velocity.x());

							//If we divert too much from where we need to go we must adjust.
							if (std::abs(currentTheta - newTheta) > WFMath::numeric_constants<double>::pi() / 20) {
								shouldSend = true;
							}
						}
					} else {
						//If we've never sent a movement update before we should do that now.
						shouldSend = true;
					}
				}
				if (shouldSend) {
					//If we're moving to a certain destination and aren't avoiding anything we should tell the server to move to the destination.
					if (destination.isValid() && !avoiding) {
						moveToPoint(WFMath::Point<3>(destination.x(), entity3dPosition.y(), destination.y()));
					} else {
						moveInDirection(velocity);
					}
				}
			}
		} else {
			//We are steering, but the path is empty, which means we can't find any path. If we're moving we should stop movement.
			//But we won't stop steering; perhaps we'll find a path later.
			if (mLastSentVelocity.isValid() && mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
				moveInDirection(WFMath::Vector<2>::ZERO());
			}
		}
	}

}