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); } } }
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; } }
void WorldAttachment::getOffsetForContainedNode(const IEntityAttachment& attachment, const WFMath::Point<3>& localPosition, WFMath::Vector<3>& offset) { assert(localPosition.isValid()); assert(offset.isValid()); float height = 0; if (mTerrainManager.getHeight(WFMath::Point<2>(localPosition.x(), localPosition.y()), height)) { offset.z() = height - localPosition.z(); } }
TerrainDefPointStore TerrainParser::parseTerrain(const Atlas::Message::Element& terrain, const WFMath::Point<3>& offset) const { //_fpreset(); if (!terrain.isMap()) { S_LOG_FAILURE("Terrain is not a map"); } const Atlas::Message::MapType & tmap = terrain.asMap(); Atlas::Message::MapType::const_iterator I = tmap.find("points"); if (I == tmap.end()) { S_LOG_FAILURE("No terrain points"); } Terrain::TerrainDefPointStore pointStore; if (I->second.isList()) { // Legacy support for old list format. const Atlas::Message::ListType& plist = I->second.asList(); Atlas::Message::ListType::const_iterator J = plist.begin(); for (; J != plist.end(); ++J) { if (!J->isList()) { S_LOG_INFO("Non list in points"); continue; } const Atlas::Message::ListType & point = J->asList(); if (point.size() != 3) { S_LOG_INFO("Point without 3 nums."); continue; } Terrain::TerrainDefPoint defPoint(static_cast<int> (point[0].asNum() + offset.x()), static_cast<int> (point[1].asNum() + offset.y()), static_cast<float> (point[3].asNum() + offset.z())); pointStore.push_back(defPoint); } } else if (I->second.isMap()) { const Atlas::Message::MapType& plist = I->second.asMap(); Atlas::Message::MapType::const_iterator J = plist.begin(); for (; J != plist.end(); ++J) { if (!J->second.isList()) { S_LOG_INFO("Non list in points."); continue; } const Atlas::Message::ListType & point = J->second.asList(); if (point.size() != 3) { S_LOG_INFO("Point without 3 nums."); continue; } int x = static_cast<int> (point[0].asNum()); int y = static_cast<int> (point[1].asNum()); float z = point[2].asNum(); Terrain::TerrainDefPoint defPoint(x + offset.x(), y + offset.y(), z + offset.z()); pointStore.push_back(defPoint); } } else { S_LOG_FAILURE("Terrain is the wrong type"); } return pointStore; }
/** * @brief Parses the changes to the position of the mod * If no height data is given the supplied height will * be used. If however a "height" value is set, that will be used instead. * If no "height" value is set, but a "heightoffset" is present, that value * will be added to the supplied height. * @param pos Position of the mod, without any adjustments. * @param modElement Atlas data describing the mod * @return The adjusted height of the mod */ float TerrainModTranslator::parsePosition(const WFMath::Point<3> & pos, const MapType& modElement) { ///If the height is specified use that, else check for a height offset. If none is found, use the default height of the entity position MapType::const_iterator I = modElement.find("height"); if (I != modElement.end()) { const Element& modHeightElem = I->second; if (modHeightElem.isNum()) { return modHeightElem.asNum(); } } else { I = modElement.find("heightoffset"); if (I != modElement.end()) { const Element& modHeightElem = I->second; if (modHeightElem.isNum()) { float heightoffset = modHeightElem.asNum(); return pos.z() + heightoffset; } } } return pos.z(); }
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; }
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."); }
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; }
void SoundSource::setPosition(const WFMath::Point<3>& pos) { assert(pos.isValid()); alSource3f(mALSource, AL_POSITION, pos.x(), pos.y(), pos.z()); SoundGeneral::checkAlError("Setting sound source position."); }