示例#1
0
void SizeAdapter::fillElementFromGui()
{
	WFMath::AxisBox<3> axisBox;
	WFMath::Point<3> lowerPoint = axisBox.lowCorner();
	WFMath::Point<3> upperPoint = axisBox.highCorner();
	if (mWidgets.lowerXWindow) {
		lowerPoint.x() = atof(mWidgets.lowerXWindow->getText().c_str());
	}
	if (mWidgets.lowerYWindow) {
		lowerPoint.y() = atof(mWidgets.lowerYWindow->getText().c_str());
	}
	if (mWidgets.lowerZWindow) {
		lowerPoint.z() = atof(mWidgets.lowerZWindow->getText().c_str());
	}
	if (mWidgets.upperXWindow) {
		upperPoint.x() = atof(mWidgets.upperXWindow->getText().c_str());
	}
	if (mWidgets.upperYWindow) {
		upperPoint.y() = atof(mWidgets.upperYWindow->getText().c_str());
	}
	if (mWidgets.upperZWindow) {
		upperPoint.z() = atof(mWidgets.upperZWindow->getText().c_str());
	}
	axisBox.setCorners(lowerPoint, upperPoint);
	mEditedValue = axisBox.toAtlas();
}
示例#2
0
void SizeAdapter::updateInfo()
{
	WFMath::AxisBox<3> newBox;
	newBox.fromAtlas(getValue());

	std::stringstream ss;
	ss.precision(4);
	ss << "w: " << (newBox.highCorner().x() - newBox.lowCorner().x()) << " d: " << (newBox.highCorner().y() - newBox.lowCorner().y()) << " h: " << (newBox.highCorner().z() - newBox.lowCorner().z());
	mWidgets.infoWindow->setText(ss.str());
}
示例#3
0
文件: Jesus.cpp 项目: Arsakes/ember
ModelBlock::ModelBlock(Ogre::SceneNode* baseNode,const  Carpenter::BuildingBlock* buildingBlock, Model::Model* model, Construction* construction)
: mBuildingBlock(buildingBlock)
, mModel(model)
, mModelNode(0)
, mConstruction(construction)
{


	mNode = baseNode->createChildSceneNode(Convert::toOgre(buildingBlock->getPosition()), Convert::toOgre(buildingBlock->getOrientation()));


	mPointBillBoardSet = mNode->getCreator()->createBillboardSet( std::string("__construction_") + construction->getBluePrint()->getName() + "_" + buildingBlock->getName() + "_billboardset__" + mNode->getName());
	mPointBillBoardSet->setDefaultDimensions(1, 1);
	mPointBillBoardSet->setMaterialName("carpenter/flare");
	mPointBillBoardSet->setVisible(false);
//	Ogre::SceneNode* aNode = EmberOgre::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode();
	mNode->attachObject(mPointBillBoardSet);


	if (model) {
		JesusPickerObject* pickerObject = new JesusPickerObject(this, 0);
		model->setUserObject(pickerObject);


		mModelNode = mNode->createChildSceneNode();
		mModelNode->attachObject(model);
		model->setQueryFlags(Jesus::CM_MODELBLOCK);

		//only autoscale the model if we've not set the scale in the modeldefinition
		//TODO: it would of course be best if all models were correctly scaled and this code could be removed
		if (model->getDefinition()->getScale() == 0) {
			const Ogre::AxisAlignedBox ogreBoundingBox = model->getBoundingBox();
			const Ogre::Vector3 ogreMax = ogreBoundingBox.getMaximum();
			const Ogre::Vector3 ogreMin = ogreBoundingBox.getMinimum();


			const WFMath::AxisBox<3> wfBoundingBox = buildingBlock->getBuildingBlockSpec()->getBlockSpec()->getBoundingBox();
			const WFMath::Point<3> wfMax = wfBoundingBox.highCorner();
			const WFMath::Point<3> wfMin = wfBoundingBox.lowCorner();

			Ogre::Real scaleX;
			Ogre::Real scaleY;
			Ogre::Real scaleZ;

			scaleX = fabs((wfMax.x() - wfMin.x()) / (ogreMax.x - ogreMin.x));
			scaleY = fabs((wfMax.z() - wfMin.z()) / (ogreMax.y - ogreMin.y));
			scaleZ = fabs((wfMax.y() - wfMin.y()) / (ogreMax.z - ogreMin.z));

			mModelNode->setScale(scaleX, scaleY, scaleZ);
		}

	}

}
示例#4
0
//check intersection of an axis-aligned box with the terrain
bool Intersect(const Terrain &t, const WFMath::AxisBox<3> &bbox)
{
    float max, min=bbox.lowCorner()[2];
    int res = t.getResolution();

    //determine which segments are involved
    //usually will just be one
    int xlow  = (int) floor(bbox.lowCorner()[0] / res);
    int xhigh = (int) gridceil(bbox.highCorner()[0] / res);
    int ylow  = (int) floor(bbox.lowCorner()[1] / res);
    int yhigh = (int) gridceil(bbox.highCorner()[1] / res);

    //loop across all tiles covered by this bbox
    for (int x = xlow; x < xhigh; x++) {
        for (int y = ylow; y < yhigh; y++) {
            //check the bbox against the extent of each tile
            //as an early rejection
            Segment *thisSeg=t.getSegment(x,y);

            if (thisSeg)
                max=thisSeg->getMax();
            else
                max=Terrain::defaultLevel;

            if (max > min) {
	        //entity bbox overlaps with the extents of this tile
		//now check each tile point covered by the entity bbox
                
                //clip the points to be tested against the bbox
                int min_x = (int) floor(bbox.lowCorner()[0] - (x * res));
                if (min_x < 0) min_x = 0;

                int max_x = (int) gridceil(bbox.highCorner()[0] - (x * res));
                if (max_x > res) min_x = res;
                
                int min_y = (int) floor(bbox.lowCorner()[1] - (y * res));
                if (min_y < 0) min_y = 0;

                int max_y = (int) gridceil(bbox.highCorner()[1] - (y * res));
                if (max_y > res) min_y = res;

                //loop over each point and see if it is greater than the minimum
                //of the bbox. If all points are below, the the bbox does NOT
                //intersect. If a single point is above, then the bbox MIGHT 
                //intersect.
                for (int xpt = min_x; xpt <= max_x; xpt++) {
		    for (int ypt = min_y; ypt <= max_y; ypt++) {
			if (thisSeg) { 
        	            if (thisSeg->get(xpt,ypt) > min) return true;
			}
			else if (Terrain::defaultLevel > min) return true;
                    }
                }
            }
        }
    }
    return false;
}
示例#5
0
void SizeAdapter::updateGui(const ::Atlas::Message::Element& element)
{
	SelfUpdateContext context(*this);
	
	WFMath::AxisBox<3> axisBox;
	try {
		axisBox.fromAtlas(element.asList());
	} catch (...) {
		axisBox = WFMath::AxisBox<3>(WFMath::Point<3>(-0.5, -0.5, -0.5), WFMath::Point<3>(0.5, 0.5, 0.5));
	}
	if (mWidgets.lowerXWindow) {
		mWidgets.lowerXWindow->setText(ValueTypeHelper<float, std::string>::convert(axisBox.lowCorner().x()));
	}
	if (mWidgets.lowerYWindow) {
		mWidgets.lowerYWindow->setText(ValueTypeHelper<float, std::string>::convert(axisBox.lowCorner().y()));
	}
	if (mWidgets.lowerZWindow) {
		mWidgets.lowerZWindow->setText(ValueTypeHelper<float, std::string>::convert(axisBox.lowCorner().z()));
	}
	if (mWidgets.upperXWindow) {
		mWidgets.upperXWindow->setText(ValueTypeHelper<float, std::string>::convert(axisBox.highCorner().x()));
	}
	if (mWidgets.upperYWindow) {
		mWidgets.upperYWindow->setText(ValueTypeHelper<float, std::string>::convert(axisBox.highCorner().y()));
	}
	if (mWidgets.upperZWindow) {
		mWidgets.upperZWindow->setText(ValueTypeHelper<float, std::string>::convert(axisBox.highCorner().z()));
	}

	updateInfo();

}
示例#6
0
void SizeAdapter::updateGui(const ::Atlas::Message::Element& element)
{
	AdapterSelfUpdateContext context(*this);
	WFMath::AxisBox<3> axisBox;
	try {
		axisBox.fromAtlas(element.asList());
	} catch (...) {
		axisBox = WFMath::AxisBox<3>(WFMath::Point<3>(-0.5, -0.5, -0.5), WFMath::Point<3>(0.5, 0.5, 0.5));
	}
	if (mLowerXWindow) {
		mLowerXWindow->setText(toString(axisBox.lowCorner().x()));
	}
	if (mLowerYWindow) {
		mLowerYWindow->setText(toString(axisBox.lowCorner().y()));
	}
	if (mLowerZWindow) {
		mLowerZWindow->setText(toString(axisBox.lowCorner().z()));
	}
	if (mUpperXWindow) {
		mUpperXWindow->setText(toString(axisBox.highCorner().x()));
	}
	if (mUpperYWindow) {
		mUpperYWindow->setText(toString(axisBox.highCorner().y()));
	}
	if (mUpperZWindow) {
		mUpperZWindow->setText(toString(axisBox.highCorner().z()));
	}

	updateInfo();

}
示例#7
0
void Terrain::processSegments(const WFMath::AxisBox<2>& area,
        const std::function<void(Segment&, int, int)>& func) const
{
    int lx = I_ROUND(std::floor((area.lowCorner()[0]) / m_spacing));
    int lz = I_ROUND(std::floor((area.lowCorner()[1]) / m_spacing));
    int hx = I_ROUND(std::ceil((area.highCorner()[0]) / m_spacing));
    int hz = I_ROUND(std::ceil((area.highCorner()[1]) / m_spacing));

    for (int i = lx; i < hx; ++i) {
        for (int j = lz; j < hz; ++j) {
            Segment *s = getSegmentAtIndex(i, j);
            if (!s) {
                continue;
            }
            func(*s, i, j);
        }
    }
}
示例#8
0
bool SizeAdapter::_hasChanges()
{
	WFMath::AxisBox<3> newBox;
	try {
		newBox.fromAtlas(getValue());
	} catch (...) {
		return false;
	}

	try {
		WFMath::AxisBox<3> originalBox;
		originalBox.fromAtlas(mOriginalValue);
		return originalBox != newBox;
	} catch (...) {
		//We have an invalid original element, but a valid new element, so we'll consider ourselves changed
		return true;
	}
}
示例#9
0
/// \brief Determine the intersection between an axis aligned box and
/// this segment.
///
/// @param bbox axis aligned box to be tested.
/// @param lx lower x coordinate of intersection area.
/// @param hx upper x coordinate of intersection area.
/// @param ly lower y coordinate of intersection area.
/// @param hy upper y coordinate of intersection area.
/// @return true if the box intersects with this Segment, false otherwise.
bool Segment::clipToSegment(const WFMath::AxisBox<2> &bbox,
                            int &lx, int &hx, int &ly, int &hy) const
{
    lx = I_ROUND(bbox.lowCorner()[0]); 
    if (lx > m_res) return false;
    if (lx < 0) lx = 0;
    
    hx = I_ROUND(bbox.highCorner()[0]); 
    if (hx < 0) return false;
    if (hx > m_res) hx = m_res;
    
    ly = I_ROUND(bbox.lowCorner()[1]); 
    if (ly > m_res) return false;
    if (ly < 0) ly = 0;
    
    hy = I_ROUND(bbox.highCorner()[1]); 
    if (hy < 0) return false;
    if (hy > m_res) hy = m_res;

    return true;
}
示例#10
0
void ParticleSystem::setBBox(const WFMath::AxisBox<3>& bb)
{
  m_origin = Point3(0, 0, 0);
  m_posDeviation = Vector3(bb.highCorner().x(), bb.highCorner().y(), 0.0);
    
  double diameter = sqrt((bb.highCorner().x() - bb.lowCorner().x()) * 
    (bb.highCorner().y() - bb.lowCorner().y()));
  m_createPerSec = DRange(1200 * diameter, 1200 * diameter);
}
示例#11
0
bool SizeAdapter::slider_ValueChanged(const CEGUI::EventArgs& e)
{
	float value = mWidgets.scaler->getCurrentValue();
	WFMath::AxisBox<3> newBox;
	try {
		newBox.fromAtlas(mOriginalValue);
	} catch (...) {
		newBox = WFMath::AxisBox<3>(WFMath::Point<3>(-0.5f, -0.5f, -0.5f), WFMath::Point<3>(0.5, 0.5, 0.5));
	}
	WFMath::Point<3> lowerPoint = newBox.lowCorner();
	WFMath::Point<3> upperPoint = newBox.highCorner();
	lowerPoint.x() *= value;
	lowerPoint.y() *= value;
	lowerPoint.z() *= value;
	upperPoint.x() *= value;
	upperPoint.y() *= value;
	upperPoint.z() *= value;
	newBox.setCorners(lowerPoint, upperPoint);
	// 	newBox *= value;
	updateGui(newBox.toAtlas());
	return true;
}
示例#12
0
bool SnapToMovement::testSnapTo(const WFMath::Point<3>& position, const WFMath::Quaternion& orientation, WFMath::Vector<3>& adjustment, EmberEntity* snappedToEntity)
{
	try {
		for (std::vector<Ogre::SceneNode*>::iterator I = mDebugNodes.begin(); I != mDebugNodes.end(); ++I) {
			Ogre::SceneNode* node = *I;
			node->setVisible(false);
			Ogre::Entity* sphereEntity = static_cast<Ogre::Entity*> (node->getAttachedObject(0));
			sphereEntity->setMaterialName("/global/authoring/point");
		}
	} catch (const std::exception& ex) {
		S_LOG_WARNING("Error when setting up debug nodes for snapping." << ex);
	}

	std::vector<Ogre::SceneNode*>::iterator nodeIterator = mDebugNodes.begin();

	//Use an auto pointer to allow both for undefined values and automatic cleanup when exiting the method.
	std::auto_ptr<SnapPointCandidate> closestSnapping(0);

	WFMath::AxisBox<3> currentBbox = mEntity.getBBox();
	//Translate the bbox into a rotbox
	WFMath::RotBox<3> currentRotbox;
	currentRotbox.size() = currentBbox.highCorner() - currentBbox.lowCorner();
	currentRotbox.corner0() = currentBbox.lowCorner();
	currentRotbox.orientation().identity();
	currentRotbox.rotatePoint(orientation, WFMath::Point<3>(0, 0, 0));
	currentRotbox.shift(WFMath::Vector<3>(position));

	//See if we should visualize debug nodes for the moved entity
	for (size_t j = 0; j < currentRotbox.numCorners(); ++j) {
		WFMath::Point<3> currentPoint = currentRotbox.getCorner(j);
		if (currentPoint.isValid() && nodeIterator != mDebugNodes.end()) {

			Ogre::SceneNode* node = *nodeIterator;
			node->setPosition(Convert::toOgre(currentPoint));
			node->setVisible(true);
			nodeIterator++;
		}
	}

	//First find all entities which are close enough
	//Then try to do a snap movement based on the points of the eris bounding boxes. I.e. we only provide support for snapping one corner of a bounding box to another corner (for now).
	WFMath::Ball<3> boundingSphere = mEntity.getBBox().boundingSphere();
	Ogre::Sphere sphere(mNode._getDerivedPosition(), boundingSphere.radius() * 2);
	Ogre::SphereSceneQuery* query = mSceneManager.createSphereQuery(sphere);
	Ogre::SceneQueryResult& result = query->execute();
	for (Ogre::SceneQueryResultMovableList::const_iterator I = result.movables.begin(); I != result.movables.end(); ++I) {
		Ogre::MovableObject* movable = *I;
		if (movable->getUserAny().getType() == typeid(EmberEntityUserObject::SharedPtr)) {
			EmberEntityUserObject* anUserObject = Ogre::any_cast<EmberEntityUserObject::SharedPtr>(movable->getUserAny()).get();
			EmberEntity& entity = anUserObject->getEmberEntity();
			if (&entity != &mEntity && entity.hasBBox()) {
				//Ok, we have an entity which is close to our entity. Now check if any of the points of the bounding box is close.
				WFMath::AxisBox<3> bbox = entity.getBBox();
				if (bbox.isValid()) {
					WFMath::RotBox<3> rotbox;
					rotbox.size() = bbox.highCorner() - bbox.lowCorner();
					rotbox.corner0() = bbox.lowCorner();
					rotbox.orientation().identity();
					rotbox.rotatePoint(entity.getViewOrientation(), WFMath::Point<3>(0, 0, 0));
					rotbox.shift(WFMath::Vector<3>(entity.getViewPosition()));

					for (size_t i = 0; i < rotbox.numCorners(); ++i) {
						WFMath::Point<3> point = rotbox.getCorner(i);
						Ogre::SceneNode* currentNode(0);
						//If there is any unclaimed debug node left we'll use it to visualize the corner
						if (nodeIterator != mDebugNodes.end()) {
							currentNode = *nodeIterator;
							currentNode->setPosition(Convert::toOgre(point));
							currentNode->setVisible(true);
							nodeIterator++;
						}
						point.z() = 0;
						for (size_t j = 0; j < currentRotbox.numCorners(); ++j) {
							WFMath::Point<3> currentPoint = currentRotbox.getCorner(j);
							currentPoint.z() = 0;
							WFMath::CoordType distance = WFMath::Distance(currentPoint, point);
							if (distance <= mSnapThreshold) {
								if (currentNode) {
									Ogre::Entity* sphereEntity = static_cast<Ogre::Entity*> (currentNode->getAttachedObject(0));
									if (sphereEntity) {
										try {
											sphereEntity->setMaterialName("/global/authoring/point/moved");
										} catch (const std::exception& ex) {
											S_LOG_WARNING("Error when setting material for point." << ex);
										}
									}
								}
								if (!closestSnapping.get()) {
									closestSnapping = std::auto_ptr<SnapPointCandidate>(new SnapPointCandidate());
									closestSnapping->entity = &entity;
									closestSnapping->distance = distance;
									closestSnapping->adjustment = point - currentPoint;
								} else if (distance < closestSnapping->distance) {
									closestSnapping->entity = &entity;
									closestSnapping->distance = distance;
									closestSnapping->adjustment = point - currentPoint;
								}
							}
						}
					}
				}
			}
		}
	}
	mSceneManager.destroyQuery(query);
	if (closestSnapping.get()) {
		adjustment = closestSnapping->adjustment;
		snappedToEntity = closestSnapping->entity;
		return true;
	}
	return false;
}