Пример #1
0
        void Brush::rebuildGeometry() {
            delete m_geometry;
            m_geometry = new BrushGeometry(m_worldBounds);

            // sort the faces by the weight of their plane normals like QBSP does
            Model::FaceList sortedFaces = m_faces;
            std::sort(sortedFaces.begin(), sortedFaces.end(), Model::Face::WeightOrder(Planef::WeightOrder(true)));
            std::sort(sortedFaces.begin(), sortedFaces.end(), Model::Face::WeightOrder(Planef::WeightOrder(false)));

            FaceSet droppedFaces;
            bool success = m_geometry->addFaces(sortedFaces, droppedFaces);
            assert(success);

            for (FaceSet::iterator it = droppedFaces.begin(); it != droppedFaces.end(); ++it) {
                Face* face = *it;
                face->setBrush(NULL);
                m_faces.erase(std::remove(m_faces.begin(), m_faces.end(), face), m_faces.end());
                delete face;
            }

            for (FaceList::iterator it = m_faces.begin(); it != m_faces.end(); ++it) {
                Face* face = *it;
                face->invalidateTexAxes();
                face->invalidateVertexCache();
            }

            if (m_entity != NULL)
                m_entity->invalidateGeometry();
        }
Пример #2
0
 SplitFacesCommand::SplitFacesCommand(Model::MapDocument& document, const wxString& name, const Model::FaceList& faces, const Vec3f& delta) :
 SnapshotCommand(Command::MoveVertices, document, name),
 m_delta(delta) {
     Model::FaceList::const_iterator it, end;
     for (it = faces.begin(), end = faces.end(); it != end; ++it) {
         const Model::Face& face = **it;
         Model::FaceInfo faceInfo = face.faceInfo();
         Model::Brush* brush = face.brush();
         
         BrushFaceMapInsertResult result = m_brushFaces.insert(BrushFaceMapEntry(brush, faceInfo));
         assert(result.second);
         m_brushes.push_back(brush);
     }
 }
Пример #3
0
        Model::Brush* MapParser::parseBrush(const BBox& worldBounds, Utility::ProgressIndicator* indicator) {
            Token token = m_tokenizer.nextToken();
            if (token.type() == TokenType::Eof)
                return NULL;
            
            expect(TokenType::OBrace | TokenType::CBrace, token);
            if (token.type() == TokenType::CBrace)
                return NULL;
            
            const size_t firstLine = token.line();
            Model::FaceList faces;
            
            while ((token = m_tokenizer.nextToken()).type() != TokenType::Eof) {
                switch (token.type()) {
                    case TokenType::OParenthesis: {
                        m_tokenizer.pushToken(token);
                        Model::Face* face = parseFace(worldBounds);
                        if (face != NULL)
                            faces.push_back(face);
                        break;
                    }
                    case TokenType::CBrace: {
                        if (indicator != NULL) indicator->update(static_cast<int>(token.position()));
                        
                        Model::Brush* brush = new Model::Brush(worldBounds);

                        // sort the faces by the weight of their plane normals like QBSP does
                        Model::FaceList sortedFaces = faces;
                        std::sort(sortedFaces.begin(), sortedFaces.end(), Model::Face::WeightOrder(Plane::WeightOrder(true)));
                        std::sort(sortedFaces.begin(), sortedFaces.end(), Model::Face::WeightOrder(Plane::WeightOrder(false)));
                        
                        Model::FaceList::iterator faceIt = sortedFaces.begin();
                        Model::FaceList::iterator faceEnd = sortedFaces.end();
                        while (faceIt != faceEnd) {
                            Model::Face* face = *faceIt++;
                            if (!brush->addFace(face)) {
                                m_console.warn("Skipping malformed brush at line %i", firstLine);
                                delete brush;
                                brush = NULL;
                                break;
                            }
                        }
                        
                        // if something went wrong, we must delete all faces that have not been added to the brush yet
                        if (faceIt != faceEnd)
                            Utility::deleteAll(sortedFaces, faceIt);
                        
                        if (brush != NULL) {
                            brush->setFilePosition(firstLine, token.line() - firstLine);
                            if (!brush->closed())
                                m_console.warn("Non-closed brush at line %i", firstLine);
                        }
                        return brush;
                    }
                    default: {
                        Utility::deleteAll(faces);
                        throw MapParserException(token, TokenType::OParenthesis | TokenType::CParenthesis);
                    }
                }
            }
            
            return NULL;
        }