panda3d/pandatool/src/xfile/xFileMesh.cxx
2001-06-21 16:35:27 +00:00

277 lines
8.7 KiB
C++

// Filename: xFileMesh.cxx
// Created by: drose (19Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "xFileMesh.h"
#include "xFileFace.h"
#include "xFileVertex.h"
#include "xFileNormal.h"
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
XFileMesh::
XFileMesh() {
_has_normals = false;
_has_colors = false;
_has_uvs = false;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
XFileMesh::
~XFileMesh() {
Vertices::iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
delete vertex;
}
Normals::iterator ni;
for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
XFileNormal *normal = (*ni);
delete normal;
}
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::add_polygon
// Access: Public
// Description: Adds the indicated polygon to the mesh.
////////////////////////////////////////////////////////////////////
void XFileMesh::
add_polygon(EggPolygon *egg_poly) {
XFileFace *face = new XFileFace(this, egg_poly);
_faces.push_back(face);
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::add_vertex
// Access: Public
// Description: Creates a new XFileVertex, if one does not already
// exist for the indicated vertex, and returns its
// index.
////////////////////////////////////////////////////////////////////
int XFileMesh::
add_vertex(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
int next_index = _vertices.size();
XFileVertex *vertex = new XFileVertex(egg_vertex, egg_prim);
if (vertex->_has_color) {
_has_colors = true;
}
if (vertex->_has_uv) {
_has_uvs = true;
}
pair<UniqueVertices::iterator, bool> result =
_unique_vertices.insert(UniqueVertices::value_type(vertex, next_index));
if (result.second) {
// Successfully added; this is a new vertex.
_vertices.push_back(vertex);
return next_index;
} else {
// Not successfully added; there is already a vertex with these
// properties. Return that one instead.
delete vertex;
return (*result.first).second;
}
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::add_normal
// Access: Public
// Description: Creates a new XFileNormal, if one does not already
// exist for the indicated normal, and returns its
// index.
////////////////////////////////////////////////////////////////////
int XFileMesh::
add_normal(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
int next_index = _normals.size();
XFileNormal *normal = new XFileNormal(egg_vertex, egg_prim);
if (normal->_has_normal) {
_has_normals = true;
}
pair<UniqueNormals::iterator, bool> result =
_unique_normals.insert(UniqueNormals::value_type(normal, next_index));
if (result.second) {
// Successfully added; this is a new normal.
_normals.push_back(normal);
return next_index;
} else {
// Not successfully added; there is already a normal with these
// properties. Return that one instead.
delete normal;
return (*result.first).second;
}
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::has_normals
// Access: Public
// Description: Returns true if any of the vertices or faces added to
// this mesh used a normal, false otherwise.
////////////////////////////////////////////////////////////////////
bool XFileMesh::
has_normals() const {
return _has_normals;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::has_colors
// Access: Public
// Description: Returns true if any of the vertices or faces added to
// this mesh used a color, false otherwise.
////////////////////////////////////////////////////////////////////
bool XFileMesh::
has_colors() const {
return _has_colors;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::has_uvs
// Access: Public
// Description: Returns true if any of the vertices added to this
// mesh used a texture coordinate, false otherwise.
////////////////////////////////////////////////////////////////////
bool XFileMesh::
has_uvs() const {
return _has_uvs;
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_mesh_data
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// Mesh template.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_mesh_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_vertices.size());
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
const Vertexf &point = vertex->_point;
raw_data.add_float32(point[0]);
raw_data.add_float32(point[1]);
raw_data.add_float32(point[2]);
}
raw_data.add_int32(_faces.size());
Faces::const_iterator fi;
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
XFileFace *face = (*fi);
raw_data.add_int32(face->_vertices.size());
XFileFace::Vertices::const_iterator fvi;
for (fvi = face->_vertices.begin();
fvi != face->_vertices.end();
++fvi) {
raw_data.add_int32((*fvi)._vertex_index);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_normal_data
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshNormals template.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_normal_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_normals.size());
Normals::const_iterator ni;
for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
XFileNormal *normal = (*ni);
const Normalf &norm = normal->_normal;
raw_data.add_float32(norm[0]);
raw_data.add_float32(norm[1]);
raw_data.add_float32(norm[2]);
}
raw_data.add_int32(_faces.size());
Faces::const_iterator fi;
for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
XFileFace *face = (*fi);
raw_data.add_int32(face->_vertices.size());
XFileFace::Vertices::const_iterator fvi;
for (fvi = face->_vertices.begin();
fvi != face->_vertices.end();
++fvi) {
raw_data.add_int32((*fvi)._normal_index);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_color_data
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshVertexColors template.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_color_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_vertices.size());
Vertices::const_iterator vi;
int i = 0;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
const Colorf &color = vertex->_color;
raw_data.add_int32(i);
raw_data.add_float32(color[0]);
raw_data.add_float32(color[1]);
raw_data.add_float32(color[2]);
raw_data.add_float32(color[3]);
i++;
}
}
////////////////////////////////////////////////////////////////////
// Function: XFileMesh::make_uv_data
// Access: Public
// Description: Fills the datagram with the raw data for the DX
// MeshTextureCoords template.
////////////////////////////////////////////////////////////////////
void XFileMesh::
make_uv_data(Datagram &raw_data) {
raw_data.clear();
raw_data.add_int32(_vertices.size());
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
XFileVertex *vertex = (*vi);
const TexCoordf &uv = vertex->_uv;
raw_data.add_float32(uv[0]);
raw_data.add_float32(uv[1]);
}
}