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(); }
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(); }
//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; }
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); }
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()); }
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(); }
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); } } }
/// \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; }
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); } } }
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; }
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; }