void ModelOverlay::setProperties(const QVariantMap& properties) { auto origPosition = getWorldPosition(); auto origRotation = getWorldOrientation(); auto origDimensions = getDimensions(); auto origScale = getSNScale(); Base3DOverlay::setProperties(properties); auto scale = properties["scale"]; if (scale.isValid()) { setSNScale(vec3FromVariant(scale)); } auto dimensions = properties["dimensions"]; if (!dimensions.isValid()) { dimensions = properties["size"]; } if (dimensions.isValid()) { _scaleToFit = true; setDimensions(vec3FromVariant(dimensions)); } else if (scale.isValid()) { // if "scale" property is set but "dimensions" is not. // do NOT scale to fit. _scaleToFit = false; } if (origPosition != getWorldPosition() || origRotation != getWorldOrientation() || origDimensions != getDimensions() || origScale != getSNScale()) { _updateModel = true; } auto loadPriorityProperty = properties["loadPriority"]; if (loadPriorityProperty.isValid()) { _loadPriority = loadPriorityProperty.toFloat(); _model->setLoadingPriority(_loadPriority); } auto urlValue = properties["url"]; if (urlValue.isValid() && urlValue.canConvert<QString>()) { _url = urlValue.toString(); _updateModel = true; _isLoaded = false; _texturesLoaded = false; } auto texturesValue = properties["textures"]; if (texturesValue.isValid() && texturesValue.canConvert(QVariant::Map)) { _texturesLoaded = false; QVariantMap textureMap = texturesValue.toMap(); QMetaObject::invokeMethod(_model.get(), "setTextures", Qt::AutoConnection, Q_ARG(const QVariantMap&, textureMap)); }
AABox Volume3DOverlay::getBounds() const { auto extents = Extents{_localBoundingBox}; extents.rotate(getWorldOrientation()); extents.shiftBy(getWorldPosition()); return AABox(extents); }
bool WebEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, OctreeElementPointer& element, float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { glm::vec3 dimensions = getScaledDimensions(); glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); glm::quat inverseRot = glm::inverse(rotation); glm::vec3 localOrigin = inverseRot * (origin - position); glm::vec3 localVelocity = inverseRot * velocity; glm::vec3 localAcceleration = inverseRot * acceleration; if (findParabolaRectangleIntersection(localOrigin, localVelocity, localAcceleration, xyDimensions, parabolicDistance)) { float localIntersectionVelocityZ = localVelocity.z + localAcceleration.z * parabolicDistance; glm::vec3 forward = rotation * Vectors::FRONT; if (localIntersectionVelocityZ > 0.0f) { face = MIN_Z_FACE; surfaceNormal = forward; } else { face = MAX_Z_FACE; surfaceNormal = -forward; } return true; } else { return false; } }
Transform Shape3DOverlay::evalRenderTransform() { // TODO: handle registration point?? glm::vec3 position = getWorldPosition(); glm::vec3 dimensions = getDimensions(); glm::quat rotation = getWorldOrientation(); Transform transform; transform.setScale(dimensions); transform.setTranslation(position); transform.setRotation(rotation); return transform; }
bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { glm::vec3 dimensions = getScaledDimensions(); glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); // FIXME - should set face and surfaceNormal return findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance); }
bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { glm::vec3 dimensions = getScaledDimensions(); glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); rotation = EntityItem::getBillboardRotation(position, rotation, _billboardMode, EntityItem::getPrimaryViewFrustumPosition()); if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) { glm::vec3 forward = rotation * Vectors::FRONT; if (glm::dot(forward, direction) > 0.0f) { face = MAX_Z_FACE; surfaceNormal = -forward; } else { face = MIN_Z_FACE; surfaceNormal = forward; } return true; } else { return false; } }
bool GUIProgressBar::gatherGeometry(GeometryGather& gather) { if (shouldProcessGather(gather)) { auto fullMaterialName = getMaterialRoot() + material_; gather.changePriority(getRenderPriority()); gather.changeTransformation(getWorldTransform()); if (material_.length()) { auto overrideParameters = getMaterialOverrideParameters(fullMaterialName); gather.changeMaterial(fullMaterialName, overrideParameters); gather.addRectangle(getWidth() * fraction_, getHeight()); } else queueWindow(gather, getWidth() * fraction_, getHeight(), getBorderSize(), getFillColor(), getBorderColor()); auto fullBackgroundMaterialName = getMaterialRoot() + backgroundMaterial_; gather.changeTransformation(localToWorld(Vec3(getWidth() * fraction_, 0.0f)), getWorldOrientation()); if (backgroundMaterial_.length()) { auto overrideParameters = getMaterialOverrideParameters(fullBackgroundMaterialName); gather.changeMaterial(fullBackgroundMaterialName, overrideParameters); gather.addRectangle(getWidth() * (1.0f - fraction_), getHeight()); } else { queueWindow(gather, getWidth() * (1.0f - fraction_), getHeight(), getBorderSize(), getFillColor(), getBorderColor()); } } return true; }
// 节点更新时顺便更新触发器 void BoxTriggerObject::nodeUpdated(const Node *node) { m_entity->setPosition(getWorldPosition()); m_entity->setScale(getWorldScale()); m_entity->setOrientation(getWorldOrientation()); }
glm::mat4 PolyVoxEntityItem::voxelToWorldMatrix() const { glm::mat4 rotation = glm::mat4_cast(getWorldOrientation()); glm::mat4 translation = glm::translate(getWorldPosition()); return translation * rotation * voxelToLocalMatrix(); }