193 lines
5.4 KiB
C++
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_
|