Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/model/map.cc')
-rw-r--r--src/model/map.cc705
1 files changed, 360 insertions, 345 deletions
diff --git a/src/model/map.cc b/src/model/map.cc
index 220c723..8260f10 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -10,170 +10,55 @@
#include "model/light.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>
-namespace model {
+namespace model
+{
// function to test spawnflags
-inline bool spawnflag_isset(unsigned int spawnflags, unsigned int flag) {
+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;
-
-Model * Map::load(std::string const &name)
-{
- // open the .map file
- Map mapfile;
-
- if (!mapfile.open(name)) {
- return 0;
- }
-
- Model *model = new Model(name);
- Light *light = 0;
- Flare *flare = 0;
- Engine *engine = 0;
-
- unsigned int u;
-
- while (mapfile.getline()) {
-
- if (mapfile.got_classname("worldspawn")) {
-
- // new wordspawn
-
- } else if (mapfile.classname().compare("worldspawn") == 0 ) {
-
- // worldspawn attributes
- if (mapfile.got_key_int("enginesound", u)) {
- model->model_enginesound = u;
- continue;
- }
-
- } 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 /= 100.0f;
- } 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_classname("target_flare")) {
-
- // new flare
- flare = new Flare();
- model->add_flare(flare);
-
- } else if (mapfile.classname().compare("target_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);
-
- } else if (mapfile.got_key_float("radius", flare->light_radius)) {
- flare->light_radius /= 100.0f;
-
- } else if (mapfile.got_key_float("frequency", flare->light_frequency)) {
- continue;
+// scaling factor when loading .map geometry
+const float SCALE = 1.0f / 1024.0f;
- } 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", flare->flare_angle)) {
- flare->flare_angle = math::degrees360f(flare->flare_angle);
- continue;
-
- }
-
- } else if (mapfile.got_classname("target_engine")) {
- // new engine
- engine = new Engine();
- model->add_engine(engine);
-
- } else if (mapfile.classname().compare("target_engine") == 0 ) {
- // engine attributes
-
- if (mapfile.got_key_vector3f("origin", engine->engine_location)) {
- engine->engine_location *= SCALE;
- continue;
-
- } else if (mapfile.got_key_color("_color", engine->engine_color)) {
- continue;
+const float MIN_DELTA = 10e-10;
- } else if (mapfile.got_key_float("radius", engine->engine_radius)) {
- engine->engine_radius /= 100.0f;
- continue;
+Map::Map()
+{
+ mapfile_name.clear();
+}
- } else if (mapfile.got_key_int("flare", engine->engine_flare)) {
- continue;
+Map::~Map()
+{
+ clear_materials();
+}
- } else if (mapfile.got_key_color("_color", engine->engine_color)) {
- continue;
- }
- }
+void Map::clear_materials()
+{
+ for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) {
+ // delete list of primitives
+ delete(*mit).second;
}
-
- mapfile.close();
-
- mapfile.load_fragments(model);
-
- return model;
+ map_materials.clear();
+
+ map_brushes = 0;
+ map_faces = 0;
+ map_faces_detail = 0;
}
-Map::Map() {}
-
-Map::~Map() {}
-
-bool Map::open(std::string const & name) {
+bool Map::open(std::string const & name)
+{
last_read_was_classname = false;
last_read_was_key = false;
@@ -182,13 +67,14 @@ bool Map::open(std::string const & name) {
classname_current = "";
line_number = 0;
parse_level = 0;
- brushes = 0;
-
+
+ clear_materials();
+
mapfile_name.assign("maps/");
mapfile_name.append(name);
mapfile_name.append(".map");
- filesystem::File *f = filesystem::open(mapfile_name.c_str());
+ filesystem::File *f = filesystem::open(mapfile_name.c_str());
if (!f) {
con_warn << "Could not open " << mapfile_name << std::endl;
return false;
@@ -203,33 +89,36 @@ bool Map::open(std::string const & name) {
con_warn << "Could not stream " << fn << "!\n";
return false;
}
-
+
return true;
}
-bool Map::got_classname() const {
+bool Map::got_classname() const
+{
return last_read_was_classname;
}
-bool Map::got_classname(const char * classnamelabel) const {
+bool Map::got_classname(const char * classnamelabel) const
+{
return (last_read_was_classname && (classname_current.compare(classnamelabel) == 0));
}
-bool Map::getline() {
+bool Map::getline()
+{
using math::Vector3f;
-
+
char data[1024];
-
+
last_read_was_classname = false;
last_read_was_key = false;
-
+
key_current = "";
value_current = "";
-
+
if (!mapfile_ifs.is_open())
return false;
-
+
if (mapfile_ifs.getline(data, 1023)) {
line_number++;
std::istringstream linestream(data);
@@ -238,13 +127,13 @@ bool Map::getline() {
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) && (classname_current == "worldspawn")) {
// brush
@@ -253,24 +142,24 @@ bool Map::getline() {
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();
-
- brushes++;
+
+ map_brushes++;
}
value_current.clear();
}
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);
@@ -280,24 +169,24 @@ bool Map::getline() {
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 == "(") && (classname_current == "worldspawn")) {
// brush plane
if (VertexArray::instance()) {
@@ -319,21 +208,21 @@ bool Map::getline() {
// 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);
plane->texture() = texture;
if (n > 0)
plane->detail() = true;
-
+
// surface flags
if (!(linestream >> n))
n = 0;
plane->surface_flags() = n;
-
+
planes.push_back(plane);
}
value_current.clear();
@@ -341,10 +230,10 @@ bool Map::getline() {
}
}
} else {
-
+
return false;
}
-
+
return true;
}
@@ -361,7 +250,13 @@ void Map::make_brushface(Plane *face)
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
@@ -372,7 +267,7 @@ void Map::make_brushface(Plane *face)
// 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 >= 0) {
vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, -MAX_BOUNDS));
vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, MAX_BOUNDS));
@@ -395,7 +290,7 @@ void Map::make_brushface(Plane *face)
// 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 >= 0) {
vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS));
vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS));
@@ -419,7 +314,7 @@ void Map::make_brushface(Plane *face)
// face must be z-axis oriented
else {
-
+
if (face->normal().z >= 0) {
vl.push_back(new Vector3f(-MAX_BOUNDS, -MAX_BOUNDS, 0));
vl.push_back(new Vector3f(-MAX_BOUNDS, MAX_BOUNDS, 0));
@@ -461,7 +356,7 @@ void Map::make_brushface(Plane *face)
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);
@@ -492,7 +387,7 @@ void Map::make_brushface(Plane *face)
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) {
@@ -509,7 +404,7 @@ void Map::make_brushface(Plane *face)
// 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 +
@@ -543,72 +438,84 @@ void Map::make_brushface(Plane *face)
// default material is none
unsigned int material = 0;
-
+
// default color makrs unknown textures hot pink
math::Color color(1.0f, 0.0, 1.0f, 1.0f);
-
+
// translate texture names to color and material
- if (face->texture() == "colors/white") {
+ if (face->texture().compare("colors/white") == 0) {
color.assign(1.0f);
- } else if (face->texture() == "colors/grey90") {
+ } else if (face->texture().compare("colors/grey90") == 0) {
color.assign(0.9f);
- } else if (face->texture() == "colors/grey75") {
+ } else if (face->texture().compare("colors/grey75") == 0) {
color.assign(0.75f);
- } else if (face->texture() == "colors/grey50") {
+ } else if (face->texture().compare("colors/grey50") == 0) {
color.assign(0.5f);
- } else if (face->texture() == "colors/grey25") {
+ } else if (face->texture().compare("colors/grey25") == 0) {
color.assign(0.25f);
- } else if (face->texture() == "colors/black") {
+ } else if (face->texture().compare("colors/black") == 0) {
color.assign(0.0f);
- } else if (face->texture() == "colors/red") {
+ } else if (face->texture().compare("colors/red") == 0) {
color.assign(1, 0, 0);
- } else if (face->texture() == "colors/green") {
+ } else if (face->texture().compare("colors/green") == 0) {
color.assign(0, 1, 0);
- } else if (face->texture() == "colors/blue") {
+ } else if (face->texture().compare("colors/blue") == 0) {
color.assign(0, 0, 1);
-
- } else if ((face->texture() == "common/entity") || (face->texture() == "common/primary")) {
+
+ } else if ((face->texture().compare("common/entity") == 0) || (face->texture().compare("common/primary") == 0)) {
material |= Material::Primary;
- } else if (face->texture() == "common/primary_dark") {
+ } else if (face->texture().compare("common/primary_dark") == 0) {
material |= Material::Primary;
material |= Material::Dark;
-
- } else if (face->texture() == "common/secundary") {
+
+ } else if (face->texture().compare("common/secundary") == 0) {
material |= Material::Secondary;
- } else if (face->texture() == "common/secundary_dark") {
+ } else if (face->texture().compare("common/secundary_dark") == 0) {
material |= Material::Secondary;
material |= Material::Dark;
-
- } else if (face->texture() == "common/tertiary") {
+
+ } else if (face->texture().compare("common/tertiary") == 0) {
material |= Material::Tertiary;
- } else if (face->texture() == "common/tertiary_dark") {
+ } else if (face->texture().compare("common/tertiary_dark") == 0) {
material |= Material::Tertiary;
material |= Material::Dark;
}
-
+
// translate surface flags to materials
-
+
// surface flag 1 light
if ((face->surface_flags() & 1) == 1) {
material |= Material::Light;
}
-
+
+ // 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++) {
-
+ 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];
}
}
-
+
// split face into triangles
- while (vl.size() >2 ) {
+ // FIXME split off quads
+ 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();
@@ -616,21 +523,9 @@ void Map::make_brushface(Plane *face)
Vector3f n(face->normal()*-1);
n.normalize();
-
- if (material & Material::Primary) {
- // evertices will be added to the VertexArray after normal vertices
- Triangle *triangle = new Triangle(*(*vn1), *(*vn), *(*v0), n, 0, face->detail());
- class_etris.push_back(triangle);
- } else if (material & Material::Light) {
- // lvertices
- Triangle *triangle = new Triangle(*(*vn1), *(*vn), *(*v0), n, color, face->detail());
- class_ltris.push_back(triangle);
- } else {
- Triangle *triangle = new Triangle(*(*vn1), *(*vn), *(*v0), n, color, face->detail());
- class_tris.push_back(triangle);
- }
-
- delete (*vn);
+
+ primitives->add_triangle(*(*vn1), *(*vn), *(*v0), n, color, face->detail());
+ delete(*vn);
vl.pop_back();
}
} else {
@@ -645,8 +540,9 @@ void Map::make_brushface(Plane *face)
vl.clear();
}
-bool Map::got_key_string(const char * keylabel, std::string & valuestring) {
- if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+bool Map::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 {
@@ -654,14 +550,15 @@ bool Map::got_key_string(const char * keylabel, std::string & valuestring) {
}
}
-bool Map::got_key_vector3f(const char * keylabel, math::Vector3f & v) {
- if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+bool Map::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();
+ v= math::Vector3f();
}
return true;
} else {
@@ -669,8 +566,9 @@ bool Map::got_key_vector3f(const char * keylabel, math::Vector3f & v) {
}
}
-bool Map::got_key_float(const char * keylabel, float & f) {
- if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+bool Map::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;
@@ -683,7 +581,7 @@ bool Map::got_key_float(const char * keylabel, float & f) {
bool Map::got_key_int(const char * keylabel, unsigned int & u)
{
- if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+ if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
std::istringstream is(value_current);
if (!(is >> u)) {
u = 0;
@@ -694,12 +592,14 @@ bool Map::got_key_int(const char * keylabel, unsigned int & u)
}
}
-bool Map::got_key(const char * keylabel) {
- return (last_read_was_key && (key_current.compare(keylabel) == 0 ));
+bool Map::got_key(const char * keylabel)
+{
+ return (last_read_was_key && (key_current.compare(keylabel) == 0));
}
-bool Map::got_key_angle(const char * keylabel, float & f) {
- if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+bool Map::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);
@@ -712,13 +612,16 @@ bool Map::got_key_angle(const char * keylabel, float & f) {
}
}
-bool Map::got_key_color(const char * keylabel, math::Color & color) {
- if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+bool Map::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;
+ r /= 255;
+ g /= 255;
+ b /= 255;
}
color = math::Color(r, g, b);
} else {
@@ -739,119 +642,231 @@ void Map::load_fragments(Model *model)
{
if (!VertexArray::instance() || VertexArray::instance()->overflow())
return;
-
- // process the triangles calculated by the mapfile and add them to the vertex array
- if ((class_tris.size() + class_etris.size() + class_ltris.size()) > 0) {
-
- math::Vector3f center = (class_minbbox + class_maxbbox) / 2;
-
- model->model_minbbox = class_minbbox - center;
- model->model_maxbbox = class_maxbbox - center;
-
- model->model_radius = model->model_maxbbox.length();
-
- // structural triangles
- model->model_first_vertex = VertexArray::instance()->index()/3;
- for (std::list<Triangle *>::iterator it = class_tris.begin(); it != class_tris.end(); it++) {
- Triangle *triangle = (*it);
- if (!triangle->detail()) {
- size_t count = 0;
- count += VertexArray::instance()->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color() );
- count += VertexArray::instance()->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color() );
- count += VertexArray::instance()->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color() );
- if (count == 3)
- model->model_vertex_count += count;
+
+ if (!map_materials.size())
+ return;
+
+ // FIXME center in maps without brushes
+ math::Vector3f center = (class_minbbox + class_maxbbox) / 2;
+
+ model->model_minbbox = class_minbbox - center;
+ model->model_maxbbox = class_maxbbox - center;
+
+ model->model_radius = model->model_maxbbox.length();
+
+ // reposition lights, flares and engines
+ for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) {
+ (*lit)->light_location -= center;
+ }
+
+ for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) {
+ (*flit)->light_location -= center;
+ }
+
+ for (Model::Engines::iterator eit = model->engines().begin(); eit != model->engines().end(); eit++) {
+ (*eit)->engine_location -= center;
+ }
+
+ 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()-center, triangle->normal(), triangle->color(), false);
+ count += fragment->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color(), false);
+ count += fragment->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color(), false);
+ if (count == 3)
+ model->model_tris_count++;
+ }
}
- }
-
- // detail triangles
- for (std::list<Triangle *>::iterator it = class_tris.begin(); it != class_tris.end(); it++) {
- Triangle *triangle = (*it);
- if (triangle->detail()) {
- size_t count = 0;
- count += VertexArray::instance()->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color() );
- count += VertexArray::instance()->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color() );
- count += VertexArray::instance()->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color() );
- if (count == 3)
- model->model_vertex_countdetail += 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()-center, triangle->normal(), triangle->color(), true);
+ count += fragment->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color(), true);
+ count += fragment->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color(), true);
+ if (count == 3) {
+ model->model_tris_count++;
+ model->model_tris_detail_count++;
+ }
+ }
}
- delete triangle;
+
+ // add the fragment to the model
+ model->fragments().push_back(fragment);
}
- class_tris.clear();
- // structural etriangles
- model->model_first_evertex = VertexArray::instance()->index()/3;
- for (std::list<Triangle *>::iterator it = class_etris.begin(); it != class_etris.end(); it++) {
- Triangle *triangle = (*it);
- if (!triangle->detail()) {
- size_t count = 0;
- count += VertexArray::instance()->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color());
- count += VertexArray::instance()->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color());
- count += VertexArray::instance()->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color());
- if (count == 3)
- model->model_evertex_count += count;
- }
- }
+ }
+
+ if (model->model_tris_count + model->model_quad_count > 0) {
+
+ }
+
+}
- // detail etriangles
- for (std::list<Triangle *>::iterator it = class_etris.begin(); it != class_etris.end(); it++) {
- Triangle *triangle = (*it);
- if (triangle->detail()) {
- size_t count = 0;
- count += VertexArray::instance()->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color());
- count += VertexArray::instance()->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color());
- count += VertexArray::instance()->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color());
- if (count == 3)
- model->model_evertex_countdetail += count;
+Model * Map::load(std::string const &name)
+{
+ // open the .map file
+ Map mapfile;
+
+ if (!mapfile.open(name)) {
+ return 0;
+ }
+
+ Model *model = new Model(name);
+ Light *light = 0;
+ Flare *flare = 0;
+ Engine *engine = 0;
+
+ unsigned int u;
+
+ while (mapfile.getline()) {
+
+ if (mapfile.got_classname("worldspawn")) {
+
+ // new wordspawn
+
+ } else if (mapfile.classname().compare("worldspawn") == 0) {
+
+ // worldspawn attributes
+ if (mapfile.got_key_int("enginesound", u)) {
+ model->model_enginesound = u;
+ continue;
}
- delete triangle;
- }
- class_etris.clear();
-
- // structural ltriangles
- model->model_first_lvertex = VertexArray::instance()->index()/3;
- for (std::list<Triangle *>::iterator it = class_ltris.begin(); it != class_ltris.end(); it++) {
- Triangle *triangle = (*it);
- if (!triangle->detail()) {
- size_t count = 0;
- count += VertexArray::instance()->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color());
- count += VertexArray::instance()->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color());
- count += VertexArray::instance()->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color());
- if (count == 3)
- model->model_lvertex_count += count;
+
+ } 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 /= 100.0f;
+
+ } 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;
+
}
- }
-
- // detail ltriangles
- for (std::list<Triangle *>::iterator it = class_ltris.begin(); it != class_ltris.end(); it++) {
- Triangle *triangle = (*it);
- if (triangle->detail()) {
- size_t count = 0;
- count += VertexArray::instance()->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color() );
- count += VertexArray::instance()->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color() );
- count += VertexArray::instance()->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color() );
- if (count == 3)
- model->model_lvertex_countdetail += count;
+
+ } else if (mapfile.got_classname("target_flare")) {
+
+ // new flare
+ flare = new Flare();
+ model->add_flare(flare);
+
+ } else if (mapfile.classname().compare("target_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);
+
+ } else if (mapfile.got_key_float("radius", flare->light_radius)) {
+ flare->light_radius /= 100.0f;
+
+ } 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", flare->flare_angle)) {
+ flare->flare_angle = math::degrees360f(flare->flare_angle);
+ continue;
+
+ }
+
+ } else if (mapfile.got_classname("target_engine")) {
+ // new engine
+ engine = new Engine();
+ model->add_engine(engine);
+
+ } else if (mapfile.classname().compare("target_engine") == 0) {
+ // engine attributes
+
+ if (mapfile.got_key_vector3f("origin", engine->engine_location)) {
+ engine->engine_location *= SCALE;
+ continue;
+
+ } else if (mapfile.got_key_color("_color", engine->engine_color)) {
+ continue;
+
+ } else if (mapfile.got_key_float("radius", engine->engine_radius)) {
+ engine->engine_radius /= 100.0f;
+ continue;
+
+ } else if (mapfile.got_key_int("flare", engine->engine_flare)) {
+ continue;
+
+ } else if (mapfile.got_key_color("_color", engine->engine_color)) {
+ continue;
}
- delete triangle;
- }
- class_ltris.clear();
-
- // reposition lights, flares and engines
- for (std::list<Light *>::iterator lit = model->model_light.begin(); lit != model->model_light.end(); lit++) {
- (*lit)->light_location -= center;
- }
-
- for (std::list<Flare *>::iterator flit = model->model_flare.begin(); flit != model->model_flare.end(); flit++) {
- (*flit)->light_location -= center;
- }
-
- for (std::list<Engine *>::iterator eit = model->model_engine.begin(); eit != model->model_engine.end(); eit++) {
- (*eit)->engine_location -= center;
}
}
-
- con_print << " maps/" << model->name() << ".map " << brushes << " brushes " << model->tris() << " tris (" << model->details() << " detail)" << std::endl;
+
+ mapfile.close();
+ /*
+ con_print << " " << mapfile.name() << " " << mapfile.map_materials.size() << " mat" <<
+ mapfile.map_brushes << " brushes " <<
+ mapfile.map_faces << "/" << mapfile.map_faces_detail << " faces/detail " << std::endl;
+ */
+ mapfile.load_fragments(model);
+
+ con_print << " " << mapfile.name() << " " <<
+ model->model_tris_count << "/" << model->model_tris_detail_count << " tris/detail " <<
+ model->model_quad_count << "/" << model->model_quad_detail_count << " quads/detail " <<
+ model->fragments().size() << " frags " <<std::endl;
+
+ mapfile.clear_materials();
+
+ return model;
}
}