Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2009-08-12 12:03:18 +0000
committerStijn Buys <ingar@osirion.org>2009-08-12 12:03:18 +0000
commit183f0f0b905715f0d89b38174fdfd44641c1a79c (patch)
tree6cae553ac6284044002fb668c7991da27291825d /src/model/map.cc
parent8bf8afe68ca15c61b0dea1f5c1ef5fc7186dca0f (diff)
src/model filenames cleanup, parse .map texture coordinates, early loading of material textures
Diffstat (limited to 'src/model/map.cc')
-rw-r--r--src/model/map.cc1212
1 files changed, 0 insertions, 1212 deletions
diff --git a/src/model/map.cc b/src/model/map.cc
deleted file mode 100644
index 5d699e6..0000000
--- a/src/model/map.cc
+++ /dev/null
@@ -1,1212 +0,0 @@
-/*
- model/map.cc
- This file is part of the Osirion project and is distributed under
- the terms of the GNU General Public License version 2
-*/
-
-#include "auxiliary/functions.h"
-#include "filesystem/filesystem.h"
-#include "math/mathlib.h"
-#include "model/map.h"
-#include "model/material.h"
-#include "model/model.h"
-#include "model/vertexarray.h"
-#include "sys/sys.h"
-
-#include <sstream>
-#include <string>
-#include <cstring>
-
-namespace model
-{
-
-// function to test spawnflags
-inline bool spawnflag_isset(unsigned int spawnflags, unsigned int flag)
-{
- return ((spawnflags & flag) == flag);
-}
-
-// max geometry bounds
-const float MAX_BOUNDS = 16384;
-
-const float MIN_DELTA = 10e-10;
-
-MapFile::MapFile() : map_center(0,0,0)
-{
- mapfile_name.clear();
- map_brushes = 0;
- map_faces = 0;
- map_faces_detail = 0;
-
- warning_q2brush = false;
-}
-
-MapFile::~MapFile()
-{
- clear_materials();
-}
-
-void MapFile::clear_materials()
-{
- for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) {
- // delete list of primitives
- delete(*mit).second;
- }
- map_materials.clear();
-}
-
-bool MapFile::open(std::string const & mapname)
-{
- warning_q2brush = false;
- last_read_was_classname = false;
- last_read_was_key = false;
- key_current = "";
- value_current = "";
- classname_current = "";
- line_number = 0;
- parse_level = 0;
-
- clear_materials();
-
- mapfile_name.append(mapname);
- mapfile_name.append(".map");
-
- mapfile_ifs.open(mapfile_name);
- if (!mapfile_ifs.is_open()) {
- return false;
- }
- return true;
-}
-
-
-bool MapFile::got_classname() const
-{
- return last_read_was_classname;
-}
-
-bool MapFile::got_classname(const char * classnamelabel) const
-{
- return (last_read_was_classname && (classname_current.compare(classnamelabel) == 0));
-}
-
-bool MapFile::got_classend(const char * classnamelabel) const
-{
- return (last_read_was_classend && (classname_current.compare(classnamelabel) == 0));
-}
-
-bool MapFile::getline()
-{
- using math::Vector3f;
-
- last_read_was_classname = false;
- last_read_was_key = false;
- last_read_was_classend = false;
-
- key_current = "";
- value_current = "";
-
- if (!mapfile_ifs.is_open())
- return false;
-
- char data[1024];
- memset(data, 0, sizeof(data));
-
- if (mapfile_ifs.getline(data, 1023)) {
- line_number++;
- std::istringstream linestream(data);
- std::string firstword;
-
- if (linestream >> firstword) {
- if (!firstword.size()) {
- return true;
-
- } else if (firstword == "//") {
- return true;
-
- } else if (firstword == "{") {
- parse_level++;
-
- } else if (firstword == "}") {
- if ((parse_level == 2) && (planes.size())) {
- // end-of-brush
-
- // for every face
- for (std::vector<Plane *>::iterator face = planes.begin(); face != planes.end(); face++) {
- make_brushface((*face));
- }
-
- // clean planes
- for (std::vector<Plane *>::iterator it = planes.begin(); it != planes.end(); it++) {
- delete(*it);
- }
- planes.clear();
-
- map_brushes++;
-
- value_current.clear();
-
- } else if ((parse_level == 1)) {
- // end-of-class
- last_read_was_classend = true;
- }
-
- parse_level--;
-
- } else if (parse_level == 1) {
-
- if (firstword == "\"classname\"") {
- classname_current.clear();
-
- if (linestream >> classname_current) {
- if (classname_current.size() > 2) {
- classname_current.erase(0,1);
- classname_current.erase(classname_current.size()-1, 1);
- last_read_was_classname = true;
- } else {
- classname_current.clear();
- }
- }
-
- } else if ((firstword.size() > 2) && (firstword[0] == '\"') && (firstword[firstword.size()-1] == '\"')) {
-
- key_current.assign(firstword);
- key_current.erase(0,1);
- key_current.erase(key_current.size()-1, 1);
-
- value_current.clear();
- char c;
- while ((linestream.get(c)) && (c != '"'));
- while ((linestream.get(c)) && (c != '"'))
- value_current += c;
-
- last_read_was_key = true;
- }
-
- } else if (parse_level == 2) {
-
- if (firstword == "(") {
- // brush plane
-
- Vector3f p1, p2, p3;
- std::string tmp;
- std::string texture;
- int n = 0;
-
- linestream >> p1;
- linestream >> tmp; // )
- linestream >> tmp; // (
- linestream >> p2;
- linestream >> tmp; // )
- linestream >> tmp; // (
- linestream >> p3;
- linestream >> tmp; // )
- linestream >> texture;
-
- // 5 numbers (texture alignment?)
- for (int i=0; i < 5; i++)
- linestream >> tmp;
-
- // content flags ?
- if (!(linestream >> n))
- n = 0;
-
- Plane *plane = new Plane(p1, p2, p3);
- aux::to_lowercase(texture);
- plane->texture() = texture;
- if (n > 0)
- plane->detail() = true;
-
- // surface flags
- if (!(linestream >> n)) {
- n = 0;
- warning_q2brush = true;
- }
- plane->surface_flags() = n;
-
- planes.push_back(plane);
-
- value_current.clear();
- }
- }
- }
- } else {
-
- return false;
- }
-
- return true;
-}
-
-void MapFile::make_brushface(Plane *face)
-{
- using math::Vector3f;
-
- // ignore caulk
- if (face->texture() == "common/caulk") {
- return;
- }
-
- // FIXME clip should be parsed as collision blocks
- if (face->texture() == "common/clip") {
- return;
- }
-
- // statistics
- map_faces++;
- if (face->detail()) {
- map_faces_detail++;
- }
-
- // using suggestions from
- // http://www.flipcode.com/archives/Level_Editing.shtml
-
- // vertex list
- std::vector<math::Vector3f *> vl;
-
- // calculate initial vertices on the bounding box
-
- // check if the face is x-axis oriented
- if ((fabsf(face->normal().x) >= fabsf(face->normal().y)) && (fabsf(face->normal().x) >= fabsf(face->normal().z))) {
-
- if (face->normal().x > MIN_DELTA) {
- vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, -MAX_BOUNDS));
- vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, MAX_BOUNDS));
- vl.push_back(new math::Vector3f(0, MAX_BOUNDS, MAX_BOUNDS));
- vl.push_back(new math::Vector3f(0, MAX_BOUNDS, -MAX_BOUNDS));
- } else {
- vl.push_back(new math::Vector3f(0, MAX_BOUNDS, -MAX_BOUNDS));
- vl.push_back(new math::Vector3f(0, MAX_BOUNDS, MAX_BOUNDS));
- vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, MAX_BOUNDS));
- vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, -MAX_BOUNDS));
- }
- // calculate the x coordinate of each face vertex
- for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- (*it)->x = (-face->d() -
- face->normal().z * (*it)->z -
- face->normal().y * (*it)->y) /
- face->normal().x;
- }
- }
-
- // check if the face is y-axis oriented
- else if ((fabsf(face->normal().y) >= fabsf(face->normal().x)) && (fabsf(face->normal().y) >= fabsf(face->normal().z))) {
-
- if (face->normal().y > MIN_DELTA) {
- vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS));
- vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS));
- vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS));
- vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS));
- } else {
- vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS));
- vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS));
- vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS));
- vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS));
- }
-
- // calculate the x coordinate of each face vertex
- for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- (*it)->y = (-face->d() -
- face->normal().z * (*it)->z -
- face->normal().x * (*it)->x) /
- face->normal().y;
- }
- }
-
- // face must be z-axis oriented
- else {
-
- if (face->normal().z > MIN_DELTA) {
- vl.push_back(new Vector3f(-MAX_BOUNDS, -MAX_BOUNDS, 0));
- vl.push_back(new Vector3f(-MAX_BOUNDS, MAX_BOUNDS, 0));
- vl.push_back(new Vector3f(MAX_BOUNDS, MAX_BOUNDS, 0));
- vl.push_back(new Vector3f(MAX_BOUNDS, -MAX_BOUNDS, 0));
- } else {
- vl.push_back(new Vector3f(MAX_BOUNDS, -MAX_BOUNDS, 0));
- vl.push_back(new Vector3f(MAX_BOUNDS, MAX_BOUNDS, 0));
- vl.push_back(new Vector3f(-MAX_BOUNDS, MAX_BOUNDS, 0));
- vl.push_back(new Vector3f(-MAX_BOUNDS, -MAX_BOUNDS, 0));
- }
-
- // calculate the x coordinate of each face vertex
- for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- (*it)->z = (-face->d() -
- face->normal().x * (*it)->x -
- face->normal().y * (*it)->y) /
- face->normal().z;
- }
- }
-
-
- // intersect the face with every plane
- for (std::vector<Plane *>::iterator pit = planes.begin(); pit != planes.end(); pit++) {
-
- Plane *plane = (*pit);
- if (plane == face) {
- continue;
- }
-
- Vector3f fn = crossproduct(face->point(1)-face->point(0), face->point(2)-face->point(0));
- Vector3f pn = crossproduct(plane->point(1)-plane->point(0), plane->point(2)-plane->point(0));
-
- Vector3f t = crossproduct(fn, pn);
- if ((t.x == 0) && (t.y == 0) && (t.z == 0)) {
- continue;
- }
-
- // intersect face with plane
- for (int i=0; vl.size() - i > 0; i++) {
-
- Vector3f v(*vl.at(i));
-
- Vector3f next;
- if (vl.size() - i > 1) {
- next = *vl.at(i+1);
- } else {
- next = *vl.front();
- }
-
- Vector3f prev;
- if (i > 0) {
- prev = *vl.at(i-1);
- } else {
- prev = *vl.back();
- }
-
- if ((v.x*plane->normal().x + v.y*plane->normal().y + v.z*plane->normal().z +plane->d()) < MIN_DELTA) {
-
- // find current
- std::vector<Vector3f *>::iterator vit = vl.begin();
- while ((*vit) != vl.at(i)) {
- vit++;
- }
-
- // check if prev - v intersects with plane
- if ((prev.x*plane->normal().x + prev.y*plane->normal().y + prev.z*plane->normal().z + plane->d()) > MIN_DELTA) {
-
- // calculate intersection
- float t1 = -plane->normal().x * prev.x - plane->normal().y * prev.y - plane->normal().z * prev.z -plane->d();
- float t2 = (plane->normal().x * v.x - plane->normal().x * prev.x +
- plane->normal().y * v.y - plane->normal().y * prev.y +
- plane->normal().z * v.z - plane->normal().z * prev.z);
-
- Vector3f *s = new Vector3f;
-
- if (t2 == 0) {
- *s = v;
- } else {
- for (int j = 0; j < 3; j++)
- (*s)[j] = prev [j] + t1 * (v[j] - prev[j]) / t2;
- }
-
- vit = vl.insert(vit,s);
- vit++;
- i++;
- }
-
- // check if next - v intersects with plane
- if ((next.x*plane->normal().x + next.y*plane->normal().y + next.z*plane->normal().z + plane->d()) > MIN_DELTA) {
-
- // calculate intersection
- float t1 = -plane->normal().x * v.x - plane->normal().y * v.y - plane->normal().z * v.z -plane->d();
- float t2 = (plane->normal().x * next.x - plane->normal().x * v.x +
- plane->normal().y * next.y - plane->normal().y * v.y +
- plane->normal().z * next.z - plane->normal().z * v.z);
- //cout << "next t2 " << t2 << std::endl;
- Vector3f *s = new Vector3f;
-
- if (t2 == 0) {
- *s = v;
- } else {
- for (int j = 0; j < 3; j++)
- (*s)[j] = v [j] + t1 * (next[j] - v[j]) / t2;
- }
-
- vit = vl.insert(vit,s);
- vit++;
- i++;
- }
-
- // erase
- delete *vit;
- vl.erase(vit);
- i--;
- }
-
- }
- }
-
- if (vl.size() > 2) {
-
- Material *material = Material::find("textures/" + face->texture());
-
- if (!material) {
- material = new Material("textures/" + face->texture());
- Material::add(material);
- material->set_flags(Material::Texture);
- material->set_texture(material->name());
- }
-
- // find the list if primitives for the current material, allocate a new one if necessary
- Primitives *primitives = 0;
-
- Materials::iterator mit = map_materials.find(material);
- if (mit == map_materials.end()) {
- primitives = new Primitives(material);
- map_materials[material] = primitives;
- } else {
- primitives = (*mit).second;
- }
-
- // calculate bounding box
- for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- *(*it) *= SCALE;
- for (int i=0; i < 3; i++) {
- if (class_maxbbox[i] < (*(*it))[i])
- class_maxbbox[i] = (*(*it))[i];
-
- if (class_minbbox[i] > (*(*it))[i])
- class_minbbox[i] = (*(*it))[i];
- }
- }
-
-
-#ifndef HAVE_BULLET
-
- // Quads are disable to use model data for bullet physics
-
- // split polygon into quads
- while (vl.size() > 3) {
- std::vector<Vector3f *>::iterator v0 = vl.begin();
- std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin();
- std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin();
- ++vn1;
- std::vector<Vector3f *>::reverse_iterator vn2 = vl.rbegin();
- ++vn2;
- ++vn2;
-
- Vector3f n(face->normal()*-1);
- n.normalize();
-
- primitives->add_quad(*(*vn2), *(*vn1), *(*vn), *(*v0), n, face->detail());
- delete(*vn);
- delete(*vn1);
- vl.pop_back();
- vl.pop_back();
- }
-#endif
- // split polygon into triangles
- while (vl.size() > 2) {
- std::vector<Vector3f *>::iterator v0 = vl.begin();
- std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin();
- std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin();
- ++vn1;
-
- Vector3f n(face->normal()*-1);
- n.normalize();
-
- primitives->add_triangle(*(*vn1), *(*vn), *(*v0), n, face->detail());
- delete(*vn);
- vl.pop_back();
- }
- } else {
- con_debug << "Unresolved face!\n";
- }
-
- // clean up the vertex list
- for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- delete(*it);
- }
-
- vl.clear();
-}
-
-bool MapFile::got_key_string(const char * keylabel, std::string & valuestring)
-{
- if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
- valuestring.assign(value_current);
- return true;
- } else {
- return false;
- }
-}
-
-bool MapFile::got_key_vector3f(const char * keylabel, math::Vector3f & v)
-{
- if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
- std::istringstream is(value_current);
- float x, y, z;
- if ((is >> x) && (is >> y) && (is >> z)) {
- v = math::Vector3f(x,y,z);
- } else {
- v= math::Vector3f();
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool MapFile::got_key_float(const char * keylabel, float & f)
-{
- if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
- std::istringstream is(value_current);
- if (!(is >> f)) {
- f = 0;
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool MapFile::got_key_int(const char * keylabel, unsigned int & u)
-{
- if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
- std::istringstream is(value_current);
- if (!(is >> u)) {
- u = 0;
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool MapFile::got_key(const char * keylabel)
-{
- return (last_read_was_key && (key_current.compare(keylabel) == 0));
-}
-
-bool MapFile::got_key_angle(const char * keylabel, float & f)
-{
- if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
- std::istringstream is(value_current);
- if ((is >> f)) {
- f = math::degrees360f(f);
- } else {
- f = 0;
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool MapFile::got_key_color(const char * keylabel, math::Color & color)
-{
- if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
- std::istringstream is(value_current);
- float r, g, b;
- if ((is >> r) && (is >> g) && (is >> b)) {
- if ((r > 1) || (g > 1) || (b > 1)) {
- r /= 255;
- g /= 255;
- b /= 255;
- }
- color = math::Color(r, g, b);
- } else {
- color = math::Color();
- }
- return true;
- } else {
- return false;
- }
-}
-
-void MapFile::close()
-{
- mapfile_ifs.close();
-}
-
-void MapFile::clear_bbox()
-{
- for (int i=0; i < 3; i++) {
- class_minbbox[i] = MAX_BOUNDS;
- class_maxbbox[i] = -MAX_BOUNDS;
- }
-
- class_axis.clear();
- class_speed = 0;
-}
-
-void MapFile::load_worldspawn(Model *model)
-{
- if (!map_materials.size())
- return;
-
- // FIXME center in maps without brushes
- map_center = (class_minbbox + class_maxbbox) / 2.0f;
-
- model->model_minbbox = class_minbbox - map_center;
- model->model_maxbbox = class_maxbbox - map_center;
-
- model->model_radius = model->model_maxbbox.length();
-
- load_fragmentgroup(model, FragmentGroup::None);
-}
-
-void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
-{
- if (!VertexArray::instance() || VertexArray::instance()->overflow())
- return;
-
- if (!map_materials.size())
- return;
-
- FragmentGroup *group = new FragmentGroup();
-
- if (class_type == FragmentGroup::Rotate) {
- if (class_speed == 0) {
- // default rotation speed 45 degrees per second
- class_speed = 45.0f;
- }
- }
-
- if (class_type != FragmentGroup::None) {
- group->set_transform(true);
- }
-
- group->set_type(class_type);
- group->set_location((class_minbbox + class_maxbbox) / 2.0f - map_center);
- group->set_axis(class_axis);
- group->set_speed(class_speed);
-
- math::Vector3f group_center(map_center);
- if (group->transform()) {
- group_center += group->location();
- }
-
- for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) {
- // split the Primitives with this material into fragments
- Primitives *primitives = (*mit).second;
-
- // store triangles
- if (primitives->triangles().size()) {
- Fragment *fragment = new Fragment(Fragment::Triangles, primitives->material());
-
- // add structural triangles to the fragment
- for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) {
- Triangle *triangle = (*tris_it);
- if (!triangle->detail()) {
- size_t count = 0;
- count += fragment->add_vertex(triangle->v0()-group_center, triangle->normal(), false);
- count += fragment->add_vertex(triangle->v1()-group_center, triangle->normal(), false);
- count += fragment->add_vertex(triangle->v2()-group_center, triangle->normal(), false);
- if (count == 3)
- model->model_tris_count++;
- }
- }
-
- // add detail triangles to the fragment
- for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) {
- Triangle *triangle = (*tris_it);
- if (triangle->detail()) {
- size_t count = 0;
- count += fragment->add_vertex(triangle->v0()-group_center, triangle->normal(), true);
- count += fragment->add_vertex(triangle->v1()-group_center, triangle->normal(), true);
- count += fragment->add_vertex(triangle->v2()-group_center, triangle->normal(), true);
- if (count == 3) {
- model->model_tris_count++;
- model->model_tris_detail_count++;
- }
- }
- }
-
- // add the fragment to the group
- group->add_fragment(fragment);
- }
-
- // store quads
- if (primitives->quads().size()) {
- Fragment *fragment = new Fragment(Fragment::Quads, primitives->material());
-
- // add structural triangles to the fragment
- for (Primitives::Quads::iterator quad_it = primitives->quads().begin(); quad_it != primitives->quads().end(); quad_it++) {
- Quad *quad = (*quad_it);
- if (!quad->detail()) {
- size_t count = 0;
- count += fragment->add_vertex(quad->v0()-group_center, quad->normal(), false);
- count += fragment->add_vertex(quad->v1()-group_center, quad->normal(), false);
- count += fragment->add_vertex(quad->v2()-group_center, quad->normal(), false);
- count += fragment->add_vertex(quad->v3()-group_center, quad->normal(), false);
- if (count == 4)
- model->model_quad_count++;
- }
- }
-
- // add detail triangles to the fragment
- for (Primitives::Quads::iterator quad_it = primitives->quads().begin(); quad_it != primitives->quads().end(); quad_it++) {
- Quad *quad = (*quad_it);
- if (quad->detail()) {
- size_t count = 0;
- count += fragment->add_vertex(quad->v0()-group_center, quad->normal(), false);
- count += fragment->add_vertex(quad->v1()-group_center, quad->normal(), false);
- count += fragment->add_vertex(quad->v2()-group_center, quad->normal(), false);
- count += fragment->add_vertex(quad->v3()-group_center, quad->normal(), false);
- if (count == 4) {
- model->model_quad_count++;
- model->model_quad_detail_count++;
- }
- }
- }
-
- // add the fragment to the group
- group->add_fragment(fragment);
- }
-
- }
-
- // add the group to the model
- model->add_group(group);
-}
-
-void MapFile::unknown_value() const
-{
- con_warn << name() << " unknown value '" << value() << "' for '" << classname() << ":" << key() << "' at line " << line() << std::endl;
-}
-
-void MapFile::unknown_key() const
-{
- con_warn << name() << " unknown key '" << classname() << ":" << key() << "' at line " << line() << std::endl;
-}
-
-void MapFile::unknown_class() const
-{
- con_warn << name() << " unknown class '" << classname() << "' at line " << line() << std::endl;
-}
-
-Model * MapFile::load(std::string const &name)
-{
- // open the .map file
- MapFile mapfile;
-
- if (!mapfile.open(name)) {
- return 0;
- }
-
- Model *model = new Model(name);
- mapfile.clear_bbox();
-
- Dock *dock = 0;
- Particles *particles = 0;
- Flare *flare = 0;
- Light *light = 0;
- SubModel *submodel = 0;
-
- std::string modelname;
- math::Vector3f location;
-
- typedef std::list<SubModel *> SubModelList;
- SubModelList submodel_list;
-
- unsigned int u;
- float angle;
- float r, s;
- std::string str;
-
- while (mapfile.getline()) {
-
- if (mapfile.got_classname("worldspawn")) {
- mapfile.clear_bbox();
-
- } else if (mapfile.got_classend("worldspawn")) {
- mapfile.load_worldspawn(model);
- mapfile.clear_materials();
-
- } else if (mapfile.in_class("worldspawn")) {
-
- // worldspawn attributes
- if (mapfile.got_key("name")) {
- con_debug << " model name '" << name << "'" << std::endl;
-
- } else if (mapfile.got_key_int("enginesound", u)) {
- model->model_enginesound = u;
- continue;
-
- } else if (mapfile.got_key_int("impulsesound", u)) {
- model->model_impulsesound = u;
- continue;
-
- } else if (mapfile.got_key_color("enginecolor", model->model_enginecolor)) {
- continue;
-
- } else if (mapfile.got_key()) {
- mapfile.unknown_key();
-
- }
-
- } else if (mapfile.got_classname("func_door")) {
- mapfile.clear_bbox();
-
- } else if (mapfile.got_classend("func_door")) {
- mapfile.load_fragmentgroup(model, FragmentGroup::Door);
- mapfile.clear_materials();
-
- } else if (mapfile.in_class("func_door")) {
-
- } else if (mapfile.got_classname("func_group")) {
- mapfile.clear_bbox();
-
- } else if (mapfile.got_classend("func_group")) {
- mapfile.load_fragmentgroup(model, FragmentGroup::None);
- mapfile.clear_materials();
-
- } else if (mapfile.got_classname("func_rotate")) {
- mapfile.clear_bbox();
-
- } else if (mapfile.got_classend("func_rotate")) {
- mapfile.load_fragmentgroup(model, FragmentGroup::Rotate);
- mapfile.clear_materials();
-
- } else if (mapfile.in_class("func_rotate")) {
-
- if (mapfile.got_key_float("angle", angle)) {
- if (angle == ANGLEUP) {
- mapfile.class_axis.change_pitch(90.0f);
- } else if (angle == ANGLEDOWN) {
- mapfile.class_axis.change_pitch(-90.0f);
- } else {
- mapfile.class_axis.change_direction(angle);
- }
- } else if (mapfile.got_key_float("direction", angle)) {
- mapfile.class_axis.change_direction(angle);
-
- } else if (mapfile.got_key_float("pitch", angle)) {
- mapfile.class_axis.change_pitch(angle);
-
- } else if (mapfile.got_key_float("roll", angle)) {
- mapfile.class_axis.change_roll(angle);
-
- } else if (mapfile.got_key_float("speed", mapfile.class_speed)) {
- continue;
-
- } else if (mapfile.got_key()) {
- mapfile.unknown_key();
- }
-
- } else if (mapfile.got_classend()) {
- mapfile.clear_materials();
-
- } else if (mapfile.got_classname("light")) {
-
- // new light
- light = new Light();
- model->add_light(light);
-
- } else if (mapfile.classname().compare("light") == 0) {
-
- // light attributes
- if (mapfile.got_key_vector3f("origin", light->light_location)) {
- light->light_location *= SCALE;
- continue;
-
- } else if (mapfile.got_key_color("_color", light->light_color)) {
- continue;
-
- } else if (mapfile.got_key_int("spawnflags", u)) {
- light->light_strobe = spawnflag_isset(u, 1);
- light->light_entity = spawnflag_isset(u, 2);
-
- } else if (mapfile.got_key_float("light", light->light_radius)) {
- light->light_radius *= LIGHTSCALE;
-
- } else if (mapfile.got_key_float("radius", light->light_radius)) {
- light->light_radius *= LIGHTSCALE;
-
- } else if (mapfile.got_key_float("frequency", light->light_frequency)) {
- continue;
-
- } else if (mapfile.got_key_float("offset", light->light_offset)) {
- continue;
-
- } else if (mapfile.got_key_float("time", light->light_time)) {
- continue;
-
- } else if (mapfile.got_key_int("flare", light->light_flare)) {
- continue;
-
- } else if (mapfile.got_key()) {
- mapfile.unknown_key();
-
- }
-
- } else if (mapfile.got_classname("location_dock")) {
-
- // new docking location
- dock = new Dock();
- model->add_dock(dock);
-
- } else if (mapfile.classname().compare("location_dock") == 0) {
-
- // dock attributes
- if (mapfile.got_key_vector3f("origin", dock->dock_location)) {
- dock->dock_location *= SCALE;
- continue;
-
- } else if (mapfile.got_key_float("radius", dock->dock_radius)) {
- dock->dock_radius *= SCALE;
- continue;
-
- } else if (mapfile.got_key("angle")) {
- continue;
-
- } else if (mapfile.got_key()) {
- mapfile.unknown_key();
-
- }
-
- } else if (mapfile.got_classname("location_cannon")) {
- // new cannon
-
- } else if (mapfile.classname().compare("location_cannon") == 0) {
-
- } else if (mapfile.got_classname("location_turret")) {
- // new turret
-
- } else if (mapfile.classname().compare("location_turret") == 0) {
-
- } else if (mapfile.got_classname("location_cockpit")) {
- // cockpit location
-
- } else if (mapfile.classname().compare("location_cockpit") == 0) {
-
- } else if (mapfile.got_classname("fx_flare")) {
-
- // new flare
- flare = new Flare();
- model->add_flare(flare);
-
- } else if (mapfile.classname().compare("fx_flare") == 0) {
-
- // flare attributes
- if (mapfile.got_key_vector3f("origin", flare->light_location)) {
- flare->light_location *= SCALE;
- continue;
-
- } else if (mapfile.got_key_color("_color", flare->light_color)) {
- continue;
-
- } else if (mapfile.got_key_int("spawnflags", u)) {
- flare->light_strobe = spawnflag_isset(u, 1);
- flare->light_entity = spawnflag_isset(u, 2);
- flare->flare_engine = spawnflag_isset(u, 4);
-
- } else if (mapfile.got_key_float("radius", flare->light_radius)) {
- flare->light_radius *= LIGHTSCALE;
-
- } else if (mapfile.got_key_float("frequency", flare->light_frequency)) {
- continue;
-
- } else if (mapfile.got_key_float("offset", flare->light_offset)) {
- continue;
-
- } else if (mapfile.got_key_float("time", flare->light_time)) {
- continue;
-
- } else if (mapfile.got_key_int("flare", flare->light_flare)) {
- continue;
-
- } else if (mapfile.got_key_float("angle", angle)) {
- if (angle == ANGLEUP) {
- flare->flare_axis.change_pitch(90.0f);
- } else if (angle == ANGLEDOWN) {
- flare->flare_axis.change_pitch(-90.0f);
- } else {
- flare->flare_axis.change_direction(angle);
- }
- } else if (mapfile.got_key_float("direction", angle)) {
- flare->flare_axis.change_direction(angle);
-
- } else if (mapfile.got_key_float("pitch", angle)) {
- flare->flare_axis.change_pitch(angle);
-
- } else if (mapfile.got_key_float("roll", angle)) {
- flare->flare_axis.change_roll(angle);
-
- } else if (mapfile.got_key_string("cull", str)) {
-
- aux::to_lowercase(str);
- if (str.compare("none") == 0) {
- flare->flare_cull = CullNone;
- } else if (str.compare("back") == 0) {
- flare->flare_cull = CullBack;
- } else if (str.compare("front") == 0) {
- flare->flare_cull = CullFront;
- } else {
- mapfile.unknown_value();
- }
-
- } else if (mapfile.got_key()) {
- mapfile.unknown_key();
- }
-
- } else if (mapfile.got_classname("misc_model")) {
-
- // new submodel
- submodel = new SubModel();
- submodel_list.push_back(submodel);
-
- } else if (mapfile.classname().compare("misc_model") == 0) {
-
- // submodel attributes
- if (mapfile.got_key_vector3f("origin", location)) {
- submodel->set_location(location * SCALE);
- continue;
-
- } else if (mapfile.got_key_string("model", modelname)) {
-
- // remove extension
- if (modelname[modelname.size()-4] == '.') {
- modelname.erase(modelname.size()-4);
- }
-
- submodel->set_name(modelname);
- continue;
-
- } else if (mapfile.got_key_float("angle", angle)) {
- if (angle == ANGLEUP) {
- submodel->axis().change_pitch(90.0f);
- } else if (angle == ANGLEDOWN) {
- submodel->axis().change_pitch(-90.0f);
- } else {
- submodel->axis().change_direction(angle);
- }
-
- } else if (mapfile.got_key_float("modelscale", s)) {
- if (s) {
- submodel->set_scale(s);
- } else {
- submodel->set_scale(1.0f);
- }
- }
-
- } else if (mapfile.got_classname("fx_particles")) {
-
- // new particle system
- particles = new Particles();
- model->add_particles(particles);
-
- } else if (mapfile.classname().compare("fx_particles") == 0) {
-
- // particle system attributes
- if (mapfile.got_key_vector3f("origin", particles->particles_location)) {
- particles->particles_location *= SCALE;
- continue;
- } else if (mapfile.got_key_string("script", particles->particles_script)) {
- continue;
- } else if (mapfile.got_key_float("angle", angle)) {
- if (angle == ANGLEUP) {
- particles->particles_axis.change_pitch(90.0f);
- } else if (angle == ANGLEDOWN) {
- particles->particles_axis.change_pitch(-90.0f);
- } else {
- particles->particles_axis.change_direction(angle);
- }
- } else if (mapfile.got_key_float("direction", angle)) {
- particles->particles_axis.change_direction(angle);
-
- } else if (mapfile.got_key_float("pitch", angle)) {
- particles->particles_axis.change_pitch(angle);
-
- } else if (mapfile.got_key_float("roll", angle)) {
- particles->particles_axis.change_roll(angle);
-
- } else if (mapfile.got_key_int("spawnflags", u)) {
- particles->particles_entity = spawnflag_isset(u, 2);
- particles->particles_engine = spawnflag_isset(u, 4);
-
- } else if (mapfile.got_key_float("radius", r)) {
- particles->set_radius(r * LIGHTSCALE);
-
- } else if (mapfile.got_key_string("cull", str)) {
-
- aux::to_lowercase(str);
- if (str.compare("none") == 0) {
- particles->particles_cull = CullNone;
- } else if (str.compare("back") == 0) {
- particles->particles_cull = CullBack;
- } else if (str.compare("front") == 0) {
- particles->particles_cull = CullFront;
- } else {
- mapfile.unknown_value();
- }
-
- } else if (mapfile.got_key()) {
- mapfile.unknown_key();
- }
- } else if (mapfile.got_classname()) {
- mapfile.unknown_class();
- }
- }
-
- mapfile.close();
-
- // reposition docks, lights, flares and particles according to the model center
- for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) {
- (*lit)->light_location -= mapfile.map_center;
- }
-
- for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) {
- (*flit)->light_location -= mapfile.map_center;
- }
-
- for (Model::ParticleSystems::iterator pit = model->particles().begin(); pit != model->particles().end(); pit++) {
- (*pit)->particles_location -= mapfile.map_center;
- }
-
- for (Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) {
- (*dit)->dock_location -= mapfile.map_center;
- }
-
- // FIXME this will go wrong if a Rotate group is imported as submodel
- for (SubModelList::iterator smit = submodel_list.begin(); smit != submodel_list.end(); smit++) {
- submodel = (*smit);
- Model *submodel_model = 0;
-
- if (submodel->name().size()) {
- submodel_model = Model::load(submodel->name());
- }
-
- if (submodel_model) {
- // copy fragmentgroups
- for (Model::Groups::iterator git = submodel_model->groups().begin(); git != submodel_model->groups().end(); git++) {
- FragmentGroup *groupsrc = (*git);
- FragmentGroup *groupdst = new FragmentGroup();
-
- groupdst->set_transform(true);
- groupdst->set_type(groupsrc->type());
- groupdst->set_scale(groupsrc->scale() * submodel->scale());
- groupdst->set_speed(groupsrc->speed());
- groupdst->set_location(groupsrc->location() + (submodel->location() - mapfile.map_center));
- groupdst->set_axis(groupsrc->axis() * submodel->axis());
-
- // copy fragments
- for (FragmentGroup::iterator fit = groupsrc->begin(); fit != groupsrc->end(); fit++) {
- Fragment *fragmentdst = new Fragment(*(*fit));
- groupdst->add_fragment(fragmentdst);
- }
-
- if (groupdst->size()) {
- model->add_group(groupdst);
- } else {
- delete groupdst;
- }
- }
-
- con_debug << " imported submodel '" << submodel->name() << "'" << std::endl;
- }
-
- delete submodel;
-
- }
-
- con_debug << " " << mapfile.name() << " " << mapfile.map_brushes << " brushes " <<
- mapfile.map_faces << "/" << mapfile.map_faces_detail << " faces/detail " << std::endl;
- if (mapfile.warning_q2brush)
- con_warn << " quake2 style brushes detected" << std::endl;
-
- return model;
-}
-
-}
-