celestia/src/celengine/model.h

193 lines
5.4 KiB
C++

// model.h
//
// Copyright (C) 2004-2006, Chris Laurel <claurel@shatters.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#ifndef _CELENGINE_MODEL_H_
#define _CELENGINE_MODEL_H_
#include "mesh.h"
class Geometry
{
public:
Geometry() {};
virtual ~Geometry() {};
//! Render the geometry in the specified OpenGL context
virtual void render(RenderContext& rc, double t = 0.0) = 0;
/*! Find the closest intersection between the ray and the
* model. If the ray intersects the model, return true
* and set distance; otherwise return false and leave
* distance unmodified.
*/
virtual bool pick(const Ray3d& r, double& distance) const = 0;
virtual bool isOpaque() const = 0;
virtual bool isNormalized() const
{
return true;
}
/*! Return true if the specified texture map type is used at
* all within this geometry object. This information is used
* to decide whether multiple rendering passes are required.
*/
virtual bool usesTextureType(Mesh::TextureSemantic) const
{
return false;
}
};
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif
/*!
* Model is the standard geometry object in Celestia. A Model
* consists of a library of materials together with a list of
* meshes. Each mesh object contains a pool of vertices and a
* set of primitive groups. A primitive groups consists of a
* a primitive group type and a list of vertex indices. This
* structure is exactly the one used in Celestia model (.cmod)
* files.
*/
class Model : public Geometry
{
public:
Model();
~Model();
/*! Return the material with the specified index, or NULL if
* the index is out of range.
*/
const Mesh::Material* getMaterial(uint32) const;
/*! Add a new material to the model's material library; the
* return value is the number of materials in the model.
*/
uint32 addMaterial(const Mesh::Material*);
/*! Return the number of materials in the model
*/
uint32 getMaterialCount() const;
/*! Return the total number of vertices in the model
*/
uint32 getVertexCount() const;
/*! Return the total number of primitives in the model
*/
uint32 getPrimitiveCount() const;
/*! Return the mesh with the specified index, or NULL if the
* index is out of range.
*/
Mesh* getMesh(uint32) const;
/*! Add a new mesh to the model; the return value is the
* total number of meshes in the model.
*/
uint32 addMesh(Mesh*);
/*! Find the closest intersection between the ray and the
* model. If the ray intersects the model, return true
* and set distance; otherwise return false and leave
* distance unmodified.
*/
virtual bool pick(const Ray3d& r, double& distance) const;
//! Render the model in the current OpenGL context
virtual void render(RenderContext&, double t = 0.0);
void transform(const Vec3f& translation, float scale);
/*! Apply a uniform scale to the model so that it fits into
* a box with a center at centerOffset and a maximum side
* length of one.
*/
void normalize(const Vec3f& centerOffset);
/*! Return true if the specified texture map type is used at
* all within a mesh. This information is used to decide
* if multiple rendering passes are required.
*/
virtual bool usesTextureType(Mesh::TextureSemantic) const;
/*! Return true if the model has no translucent components. */
virtual bool isOpaque() const
{
return opaque;
}
virtual bool isNormalized() const
{
return normalized;
}
/*! Set the opacity flag based on material usage within the model */
void determineOpacity();
class MeshComparator
{
public:
virtual ~MeshComparator() {};
virtual bool operator()(const Mesh&, const Mesh&) const = 0;
};
/*! Sort the model's meshes in place. */
void sortMeshes(const MeshComparator&);
/*! Optimize the model by eliminating all duplicated materials */
void uniquifyMaterials();
/*! This comparator will roughly sort the model's meshes by
* opacity so that transparent meshes are rendered last. It's far
* from perfect, but covers a lot of cases. A better method of
* opacity sorting would operate at the primitive group level, or
* even better at the triangle level.
*
* Standard usage for this class is:
* model->sortMeshes(Model::OpacityComparator());
*
* uniquifyMaterials() should be used before sortMeshes(), since
* the opacity comparison depends on material indices being ordered
* by opacity.
*/
class OpacityComparator : public MeshComparator
{
public:
OpacityComparator();
virtual ~OpacityComparator() {};
virtual bool operator()(const Mesh&, const Mesh&) const;
private:
int unused;
};
private:
std::vector<const Mesh::Material*> materials;
std::vector<Mesh*> meshes;
bool textureUsage[Mesh::TextureSemanticMax];
bool opaque;
bool normalized;
};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif // !_CELENGINE_MODEL_H_