void matrix4_assign_rotation_for_pivot(Matrix4& matrix, const scene::INodePtr& node) { EditablePtr editable = Node_getEditable(node); // If the instance is editable, take the localpivot point into account, otherwise just apply the rotation if (editable != 0) { matrix4_assign_rotation(matrix, node->localToWorld().getMultipliedBy(editable->getLocalPivot())); } else { matrix4_assign_rotation(matrix, node->localToWorld()); } }
void ScaleSelected::visit(const scene::INodePtr& node) const { ITransformNodePtr transformNode = Node_getTransformNode(node); if(transformNode != 0) { ITransformablePtr transform = Node_getTransformable(node); if(transform != 0) { transform->setType(TRANSFORM_PRIMITIVE); transform->setScale(c_scale_identity); transform->setTranslation(c_translation_identity); transform->setType(TRANSFORM_PRIMITIVE); transform->setScale(m_scale); { EditablePtr editable = Node_getEditable(node); const Matrix4& localPivot = editable != 0 ? editable->getLocalPivot() : Matrix4::getIdentity(); Vector3 parent_translation; translation_for_pivoted_scale( parent_translation, m_scale, m_world_pivot, node->localToWorld().getMultipliedBy(localPivot), transformNode->localToParent().getMultipliedBy(localPivot) ); transform->setTranslation(parent_translation); } } } }
void RotateSelected::visit(const scene::INodePtr& node) const { ITransformNodePtr transformNode = Node_getTransformNode(node); if (transformNode) { // Upcast the instance onto a Transformable ITransformablePtr transformable = Node_getTransformable(node); if (transformable) { // The object is not scaled or translated explicitly // A translation might occur due to the rotation around a pivot point transformable->setType(TRANSFORM_PRIMITIVE); transformable->setScale(c_scale_identity); transformable->setTranslation(c_translation_identity); // Pass the rotation quaternion and the world pivot, // unless we're rotating each object around their own center transformable->setRotation(_rotation, _freeObjectRotation ? transformable->getUntransformedOrigin() : _worldPivot, node->localToWorld()); } } }
void ModelExporter::processLight(const scene::INodePtr& node) { // Export lights as small polyhedron static const double EXTENTS = 8.0; std::vector<model::ModelPolygon> polys; Vertex3f up(0, 0, EXTENTS); Vertex3f down(0, 0, -EXTENTS); Vertex3f north(0, EXTENTS, 0); Vertex3f south(0, -EXTENTS, 0); Vertex3f east(EXTENTS, 0, 0); Vertex3f west(-EXTENTS, 0, 0); // Upper semi-diamond polys.push_back(createPolyCCW(up, south, east)); polys.push_back(createPolyCCW(up, east, north)); polys.push_back(createPolyCCW(up, north, west)); polys.push_back(createPolyCCW(up, west, south)); // Lower semi-diamond polys.push_back(createPolyCCW(down, south, west)); polys.push_back(createPolyCCW(down, west, north)); polys.push_back(createPolyCCW(down, north, east)); polys.push_back(createPolyCCW(down, east, south)); Matrix4 exportTransform = node->localToWorld().getPremultipliedBy(_centerTransform); _exporter->addPolygons("lights/default", polys, exportTransform); }
void ScaleComponentSelected::visit(const scene::INodePtr& node) const { ITransformablePtr transform = Node_getTransformable(node); if(transform != 0) { Vector3 parent_translation; translation_for_pivoted_scale(parent_translation, m_scale, m_world_pivot, node->localToWorld(), Node_getTransformNode(node)->localToParent()); transform->setType(TRANSFORM_COMPONENT); transform->setScale(m_scale); transform->setTranslation(parent_translation); } }
void ModelExporter::processBrush(const scene::INodePtr& node) { IBrush* brush = Node_getIBrush(node); if (brush == nullptr) return; Matrix4 exportTransform = node->localToWorld().getPremultipliedBy(_centerTransform); for (std::size_t b = 0; b < brush->getNumFaces(); ++b) { const IFace& face = brush->getFace(b); const std::string& materialName = face.getShader(); if (!isExportableMaterial(materialName)) continue; const IWinding& winding = face.getWinding(); std::vector<model::ModelPolygon> polys; if (winding.size() < 3) { rWarning() << "Skipping face with less than 3 winding verts" << std::endl; continue; } // Create triangles for this winding for (std::size_t i = 1; i < winding.size() - 1; ++i) { model::ModelPolygon poly; poly.a = convertWindingVertex(winding[i + 1]); poly.b = convertWindingVertex(winding[i]); poly.c = convertWindingVertex(winding[0]); polys.push_back(poly); } _exporter->addPolygons(materialName, polys, exportTransform); } }
void ModelExporter::processPatch(const scene::INodePtr& node) { IPatch* patch = Node_getIPatch(node); if (patch == nullptr) return; const std::string& materialName = patch->getShader(); if (!isExportableMaterial(materialName)) return; PatchMesh mesh = patch->getTesselatedPatchMesh(); std::vector<model::ModelPolygon> polys; for (std::size_t h = 0; h < mesh.height - 1; ++h) { for (std::size_t w = 0; w < mesh.width - 1; ++w) { model::ModelPolygon poly; poly.a = convertPatchVertex(mesh.vertices[w + (h*mesh.width)]); poly.b = convertPatchVertex(mesh.vertices[w + 1 + (h*mesh.width)]); poly.c = convertPatchVertex(mesh.vertices[w + mesh.width + (h*mesh.width)]); polys.push_back(poly); poly.a = convertPatchVertex(mesh.vertices[w + 1 + (h*mesh.width)]); poly.b = convertPatchVertex(mesh.vertices[w + 1 + mesh.width + (h*mesh.width)]); poly.c = convertPatchVertex(mesh.vertices[w + mesh.width + (h*mesh.width)]); polys.push_back(poly); } } Matrix4 exportTransform = node->localToWorld().getPremultipliedBy(_centerTransform); _exporter->addPolygons(materialName, polys, exportTransform); }