celmodel fixes:
- Removed unused code in #if 0/#endif blocks - Added non-const accessor for Mesh::PrimitiveGroup - Return more information in pick result: mesh, primitive group, and primitive index instead of just the distance to first intersection.sensor-dev
parent
626e24d9f9
commit
f9260386b2
|
@ -245,6 +245,16 @@ Mesh::getGroup(unsigned int index) const
|
|||
}
|
||||
|
||||
|
||||
Mesh::PrimitiveGroup*
|
||||
Mesh::getGroup(unsigned int index)
|
||||
{
|
||||
if (index >= groups.size())
|
||||
return NULL;
|
||||
else
|
||||
return groups[index];
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
Mesh::addGroup(PrimitiveGroup* group)
|
||||
{
|
||||
|
@ -350,7 +360,7 @@ Mesh::aggregateByMaterial()
|
|||
|
||||
|
||||
bool
|
||||
Mesh::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& distance) const
|
||||
Mesh::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, PickResult* result) const
|
||||
{
|
||||
double maxDistance = 1.0e30;
|
||||
double closest = maxDistance;
|
||||
|
@ -379,6 +389,7 @@ Mesh::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& dist
|
|||
(nIndices >= 3) &&
|
||||
!(primType == TriList && nIndices % 3 != 0))
|
||||
{
|
||||
unsigned int primitiveIndex = 0;
|
||||
index32 index = 0;
|
||||
index32 i0 = (*iter)->indices[0];
|
||||
index32 i1 = (*iter)->indices[1];
|
||||
|
@ -423,7 +434,15 @@ Mesh::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& dist
|
|||
double s0 = (m11 * q0 - m01 * q1) * d;
|
||||
double s1 = (m00 * q1 - m10 * q0) * d;
|
||||
if (s0 >= 0.0 && s1 >= 0.0 && s0 + s1 <= 1.0)
|
||||
{
|
||||
closest = t;
|
||||
if (result)
|
||||
{
|
||||
result->group = *iter;
|
||||
result->primitiveIndex = primitiveIndex;
|
||||
result->distance = closest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -461,82 +480,28 @@ Mesh::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& dist
|
|||
}
|
||||
}
|
||||
|
||||
primitiveIndex++;
|
||||
|
||||
} while (index < nIndices);
|
||||
}
|
||||
}
|
||||
|
||||
if (closest != maxDistance)
|
||||
{
|
||||
distance = closest;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return closest != maxDistance;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
Mesh::render(const std::vector<const Material*>& materials,
|
||||
RenderContext& rc) const
|
||||
bool
|
||||
Mesh::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& distance) const
|
||||
{
|
||||
// The first time the mesh is rendered, we will try and place the
|
||||
// vertex data in a vertex buffer object and potentially get a huge
|
||||
// rendering performance boost. This can consume a great deal of
|
||||
// memory, since we're duplicating the vertex data. TODO: investigate
|
||||
// the possibility of deleting the original data. We can always map
|
||||
// read-only later on for things like picking, but this could be a low
|
||||
// performance path.
|
||||
if (!vbInitialized && isVBOSupported())
|
||||
PickResult result;
|
||||
bool hit = pick(rayOrigin, rayDirection, &result);
|
||||
if (hit)
|
||||
{
|
||||
vbInitialized = true;
|
||||
|
||||
if (nVertices * vertexDesc.stride > MinVBOSize)
|
||||
{
|
||||
glGenBuffersARB(1, &vbObject);
|
||||
if (vbObject != 0)
|
||||
{
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbObject);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB,
|
||||
nVertices * vertexDesc.stride,
|
||||
vertices,
|
||||
GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
}
|
||||
distance = result.distance;
|
||||
}
|
||||
|
||||
if (vbObject != 0)
|
||||
{
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbObject);
|
||||
rc.setVertexArrays(vertexDesc, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc.setVertexArrays(vertexDesc, vertices);
|
||||
}
|
||||
|
||||
unsigned int lastMaterial = ~0u;
|
||||
|
||||
// Iterate over all primitive groups in the mesh
|
||||
for (vector<PrimitiveGroup*>::const_iterator iter = groups.begin();
|
||||
iter != groups.end(); iter++)
|
||||
{
|
||||
// Set up the material
|
||||
const Material* mat = NULL;
|
||||
unsigned int materialIndex = (*iter)->materialIndex;
|
||||
if (materialIndex != lastMaterial && materialIndex < materials.size())
|
||||
mat = materials[materialIndex];
|
||||
|
||||
rc.setMaterial(mat);
|
||||
rc.drawGroup(**iter);
|
||||
}
|
||||
|
||||
if (vbObject != 0)
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
return hit;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
AlignedBox<float, 3>
|
||||
|
@ -591,11 +556,6 @@ Mesh::transform(const Vector3f& translation, float scale)
|
|||
{
|
||||
const Vector3f tv = (Map<Vector3f>(reinterpret_cast<float*>(vdata)) + translation) * scale;
|
||||
Map<Vector3f>(reinterpret_cast<float*>(vdata)) = tv;
|
||||
#if CELVEC
|
||||
reinterpret_cast<float*>(vdata)[0] = tv.x();
|
||||
reinterpret_cast<float*>(vdata)[1] = tv.y();
|
||||
reinterpret_cast<float*>(vdata)[2] = tv.z();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Point sizes need to be scaled as well
|
||||
|
@ -726,3 +686,12 @@ Mesh::getVertexAttributeSize(VertexAttributeFormat fmt)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Mesh::PickResult::PickResult() :
|
||||
mesh(NULL),
|
||||
group(NULL),
|
||||
primitiveIndex(0),
|
||||
distance(-1.0)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -136,6 +136,17 @@ class Mesh
|
|||
unsigned int nIndices;
|
||||
};
|
||||
|
||||
class PickResult
|
||||
{
|
||||
public:
|
||||
PickResult();
|
||||
|
||||
Mesh* mesh;
|
||||
PrimitiveGroup* group;
|
||||
unsigned int primitiveIndex;
|
||||
double distance;
|
||||
};
|
||||
|
||||
Mesh();
|
||||
~Mesh();
|
||||
|
||||
|
@ -144,6 +155,7 @@ class Mesh
|
|||
const VertexDescription& getVertexDescription() const;
|
||||
|
||||
const PrimitiveGroup* getGroup(unsigned int index) const;
|
||||
PrimitiveGroup* getGroup(unsigned int index);
|
||||
unsigned int addGroup(PrimitiveGroup* group);
|
||||
unsigned int addGroup(PrimitiveGroupType prim,
|
||||
unsigned int materialIndex,
|
||||
|
@ -164,6 +176,7 @@ class Mesh
|
|||
const std::string& getName() const;
|
||||
void setName(const std::string&);
|
||||
|
||||
bool pick(const Eigen::Vector3d& origin, const Eigen::Vector3d& direction, PickResult* result) const;
|
||||
bool pick(const Eigen::Vector3d& origin, const Eigen::Vector3d& direction, double& distance) const;
|
||||
|
||||
Eigen::AlignedBox<float, 3> getBoundingBox() const;
|
||||
|
|
|
@ -132,30 +132,56 @@ Model::addMesh(Mesh* m)
|
|||
|
||||
|
||||
bool
|
||||
Model::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& distance) const
|
||||
Model::pick(const Eigen::Vector3d& rayOrigin,
|
||||
const Eigen::Vector3d& rayDirection,
|
||||
Mesh::PickResult* result) const
|
||||
{
|
||||
double maxDistance = 1.0e30;
|
||||
double closest = maxDistance;
|
||||
Mesh::PickResult closestResult;
|
||||
|
||||
for (vector<Mesh*>::const_iterator iter = meshes.begin();
|
||||
iter != meshes.end(); iter++)
|
||||
{
|
||||
double d = maxDistance;
|
||||
if ((*iter)->pick(rayOrigin, rayDirection, d) && d < closest)
|
||||
Mesh::PickResult result;
|
||||
if ((*iter)->pick(rayOrigin, rayDirection, &result))
|
||||
{
|
||||
closest = d;
|
||||
if (result.distance < closest)
|
||||
{
|
||||
closestResult = result;
|
||||
closestResult.mesh = *iter;
|
||||
closest = result.distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closest != maxDistance)
|
||||
{
|
||||
distance = closest;
|
||||
if (result)
|
||||
{
|
||||
*result = closestResult;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Model::pick(const Vector3d& rayOrigin, const Vector3d& rayDirection, double& distance) const
|
||||
{
|
||||
Mesh::PickResult result;
|
||||
bool hit = pick(rayOrigin, rayDirection, &result);
|
||||
if (hit)
|
||||
{
|
||||
distance = result.distance;
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,25 +458,3 @@ Model::sortMeshes(const MeshComparator& comparator)
|
|||
// Sort the meshes so that completely opaque ones are first
|
||||
sort(meshes.begin(), meshes.end(), MeshComparatorAdapter(comparator));
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
Model::loadTextures()
|
||||
{
|
||||
for (vector<const Material*>::const_iterator iter = materials.begin();
|
||||
iter != materials.end(); iter++)
|
||||
{
|
||||
const Mesh::Material* m = *iter;
|
||||
|
||||
if (m->maps[Material::DiffuseMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Material::DiffuseMap]);
|
||||
if (m->maps[Material::NormalMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Material::NormalMap]);
|
||||
if (m->maps[Material::SpecularMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Material::SpecularMap]);
|
||||
if (m->maps[Material::EmissiveMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Material::EmissiveMap]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -68,14 +68,25 @@ class Model
|
|||
*/
|
||||
unsigned int addMesh(Mesh* mesh);
|
||||
|
||||
/*! Find the closest intersection between the ray (given
|
||||
/** Find the closest intersection between the ray (given
|
||||
* by origin and direction) and the model. If the ray
|
||||
* intersects the model, return true and fill in the
|
||||
* pick result record. If the result record is NULL, it
|
||||
* ignored, and the function just computes whether or
|
||||
* not the ray intersected the model.
|
||||
*/
|
||||
bool pick(const Eigen::Vector3d& rayOrigin,
|
||||
const Eigen::Vector3d& rayDirection,
|
||||
Mesh::PickResult* result) const;
|
||||
|
||||
/** Find the closest intersection between the ray (given
|
||||
* by origin and direction) and the model. If the ray
|
||||
* intersects the model, return true and set distance;
|
||||
* otherwise return false and leave distance unmodified.
|
||||
*/
|
||||
bool pick(const Eigen::Vector3d& rayOrigin,
|
||||
const Eigen::Vector3d& rayDirection,
|
||||
double& distance) const;
|
||||
double& distance) const;
|
||||
|
||||
void transform(const Eigen::Vector3f& translation, float scale);
|
||||
|
||||
|
|
|
@ -571,84 +571,6 @@ Token TokenStream::nextToken()
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
class BinaryInputStream
|
||||
{
|
||||
public:
|
||||
BinaryInputStream(istream* in) :
|
||||
m_in(in)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
istream* m_in;
|
||||
};
|
||||
|
||||
|
||||
class BinaryOutputStream
|
||||
{
|
||||
public:
|
||||
BinaryOutputStream(ostream* out) :
|
||||
m_out(out)
|
||||
{
|
||||
}
|
||||
|
||||
void writeUint32(unsigned int i);
|
||||
void writeInt16(int i);
|
||||
void writeFloat(float f);
|
||||
|
||||
void writeString(const std::string s)
|
||||
{
|
||||
writeInt16(static_cast<int16>(s.length()));
|
||||
m_out->write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
private:
|
||||
ostream* m_out;
|
||||
};
|
||||
|
||||
|
||||
class CmodBinaryOutputStream : public BinaryOuputStream
|
||||
{
|
||||
public:
|
||||
CmodBinaryOuputStream(ostream* out) :
|
||||
BinaryOutputStream(out)
|
||||
{
|
||||
}
|
||||
|
||||
void writeToken(ModelFileToken val)
|
||||
{
|
||||
writeInt16((int) val);
|
||||
}
|
||||
|
||||
void writeType(ModelFileType val)
|
||||
{
|
||||
writeInt16((int) val);
|
||||
}
|
||||
|
||||
void writeTypeFloat1(float f)
|
||||
{
|
||||
writeType(CMOD_Float1);
|
||||
writeFloat(f);
|
||||
}
|
||||
|
||||
void writeTypeColor(const Material::Color& c)
|
||||
{
|
||||
writeType(CMOD_Color);
|
||||
writeFloat(c.red);
|
||||
writeFloat(c.green);
|
||||
writeFloat(c.blue);
|
||||
}
|
||||
|
||||
void writeTypeString(const string& s)
|
||||
{
|
||||
writeType(out, CMOD_String);
|
||||
writeString(s);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
This is an approximate Backus Naur form for the contents of ASCII cmod
|
||||
files. For brevity, the categories <unsigned_int> and <float> aren't
|
||||
|
|
Loading…
Reference in New Issue