예제 #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
void Steering::setAwareness()
{
	//If we are loitering we should stop that now.
	delete mLoitering;
	mLoitering = nullptr;

	const auto entityViewPosition = mAvatar.getEntity()->getViewPosition();

	WFMath::Point<2> destination2d(mViewDestination.x(), mViewDestination.z());
	WFMath::Point<2> entityPosition2d(entityViewPosition.x(), entityViewPosition.z());

	WFMath::Vector<2> direction(destination2d - entityPosition2d);
	auto theta = std::atan2(direction.y(), direction.x()); // rotation about Y
	WFMath::RotMatrix<2> rm;
	rm.rotation(theta);

	WFMath::Point<2> start = entityPosition2d;
	start -= WFMath::Vector<2>(mPadding, mPadding);

	WFMath::Vector<2> size(direction.mag() + (mPadding * 2), mPadding * 2);

	WFMath::RotBox<2> area;
	area.size() = size;
	area.corner0() = start;
	area.orientation() = WFMath::RotMatrix<2>().identity();
	area.rotatePoint(rm, entityPosition2d);

	mAwareness.setAwarenessArea(area, WFMath::Segment<2>(entityPosition2d, destination2d));

}
예제 #3
0
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;
	}
}
예제 #4
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);
}
예제 #5
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;
}