SH-828 Fix for using uninitialized data when normals or texture coordinates are absent from collada file (can now upload meshes without normals or texture coordinates).
parent
1b01476dad
commit
15235061e8
|
|
@ -2379,11 +2379,16 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co
|
|||
bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const
|
||||
{
|
||||
bool retval = false;
|
||||
if (rhs.mData[POSITION].equals3(mData[POSITION]) && rhs.mTexCoord == mTexCoord)
|
||||
|
||||
const F32 epsilon = 0.00001f;
|
||||
|
||||
if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) &&
|
||||
abs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon &&
|
||||
abs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon)
|
||||
{
|
||||
if (angle_cutoff > 1.f)
|
||||
{
|
||||
retval = (mData[NORMAL].equals3(rhs.mData[NORMAL]));
|
||||
retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2499,38 +2504,52 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
|
|||
}
|
||||
|
||||
{
|
||||
U16* n = (U16*) &(norm[0]);
|
||||
for (U32 j = 0; j < num_verts; ++j)
|
||||
if (!norm.empty())
|
||||
{
|
||||
norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]);
|
||||
norm_out->div(65535.f);
|
||||
norm_out->mul(2.f);
|
||||
norm_out->sub(1.f);
|
||||
norm_out++;
|
||||
n += 3;
|
||||
U16* n = (U16*) &(norm[0]);
|
||||
for (U32 j = 0; j < num_verts; ++j)
|
||||
{
|
||||
norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]);
|
||||
norm_out->div(65535.f);
|
||||
norm_out->mul(2.f);
|
||||
norm_out->sub(1.f);
|
||||
norm_out++;
|
||||
n += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(norm_out, 0, sizeof(LLVector4a)*num_verts);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
U16* t = (U16*) &(tc[0]);
|
||||
for (U32 j = 0; j < num_verts; j+=2)
|
||||
if (!tc.empty())
|
||||
{
|
||||
if (j < num_verts-1)
|
||||
U16* t = (U16*) &(tc[0]);
|
||||
for (U32 j = 0; j < num_verts; j+=2)
|
||||
{
|
||||
tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]);
|
||||
if (j < num_verts-1)
|
||||
{
|
||||
tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f);
|
||||
}
|
||||
|
||||
t += 4;
|
||||
|
||||
tc_out->div(65535.f);
|
||||
tc_out->mul(tc_range);
|
||||
tc_out->add(min_tc4);
|
||||
|
||||
tc_out++;
|
||||
}
|
||||
else
|
||||
{
|
||||
tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f);
|
||||
}
|
||||
|
||||
t += 4;
|
||||
|
||||
tc_out->div(65535.f);
|
||||
tc_out->mul(tc_range);
|
||||
tc_out->add(min_tc4);
|
||||
|
||||
tc_out++;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(tc_out, 0, sizeof(LLVector2)*num_verts);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2656,6 +2675,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
|
|||
min.setMin(min, face.mPositions[i]);
|
||||
max.setMax(max, face.mPositions[i]);
|
||||
}
|
||||
|
||||
if (face.mTexCoords)
|
||||
{
|
||||
LLVector2& min_tc = face.mTexCoordExtents[0];
|
||||
LLVector2& max_tc = face.mTexCoordExtents[1];
|
||||
|
||||
min_tc = face.mTexCoords[0];
|
||||
max_tc = face.mTexCoords[0];
|
||||
|
||||
for (U32 j = 1; j < face.mNumVertices; ++j)
|
||||
{
|
||||
update_min_max(min_tc, max_tc, face.mTexCoords[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
face.mTexCoordExtents[0].set(0,0);
|
||||
face.mTexCoordExtents[1].set(1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5696,8 +5734,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
|
|||
void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv)
|
||||
{
|
||||
cv.setPosition(mPositions[index]);
|
||||
cv.setNormal(mNormals[index]);
|
||||
cv.mTexCoord = mTexCoords[index];
|
||||
if (mNormals)
|
||||
{
|
||||
cv.setNormal(mNormals[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv.getNormal().clear();
|
||||
}
|
||||
|
||||
if (mTexCoords)
|
||||
{
|
||||
cv.mTexCoord = mTexCoords[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
cv.mTexCoord.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const
|
||||
|
|
@ -5727,7 +5780,10 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
|
|||
LLVolumeFace new_face;
|
||||
|
||||
//map of points to vector of vertices at that point
|
||||
VertexMapData::PointMap point_map;
|
||||
std::map<U64, std::vector<VertexMapData> > point_map;
|
||||
|
||||
LLVector4a range;
|
||||
range.setSub(mExtents[1],mExtents[0]);
|
||||
|
||||
//remove redundant vertices
|
||||
for (U32 i = 0; i < mNumIndices; ++i)
|
||||
|
|
@ -5738,7 +5794,19 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
|
|||
getVertexData(index, cv);
|
||||
|
||||
BOOL found = FALSE;
|
||||
VertexMapData::PointMap::iterator point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr()));
|
||||
|
||||
LLVector4a pos;
|
||||
pos.setSub(mPositions[index], mExtents[0]);
|
||||
pos.div(range);
|
||||
|
||||
U64 pos64 = 0;
|
||||
|
||||
pos64 = (U16) (pos[0]*65535);
|
||||
pos64 = pos64 | (((U64) (pos[1]*65535)) << 16);
|
||||
pos64 = pos64 | (((U64) (pos[2]*65535)) << 32);
|
||||
|
||||
std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64);
|
||||
|
||||
if (point_iter != point_map.end())
|
||||
{ //duplicate point might exist
|
||||
for (U32 j = 0; j < point_iter->second.size(); ++j)
|
||||
|
|
@ -5770,11 +5838,26 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
|
|||
}
|
||||
else
|
||||
{
|
||||
point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d);
|
||||
point_map[pos64].push_back(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llassert(new_face.mNumIndices == mNumIndices);
|
||||
llassert(new_face.mNumVertices <= mNumVertices);
|
||||
|
||||
if (angle_cutoff > 1.f && !mNormals)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!mTexCoords)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
swapData(new_face);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "llmodel.h"
|
||||
#include "llmemory.h"
|
||||
#include "llconvexdecomposition.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llvector4a.h"
|
||||
|
|
@ -71,88 +72,10 @@ LLModel::~LLModel()
|
|||
}
|
||||
}
|
||||
|
||||
void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Array& inputs, U32 min_idx, U32 max_idx)
|
||||
{
|
||||
for (U32 j = 0; j < inputs.getCount(); ++j)
|
||||
{
|
||||
if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0)
|
||||
{ //found vertex array
|
||||
const domURIFragmentType& uri = inputs[j]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domVertices* vertices = (domVertices*) elem.cast();
|
||||
|
||||
domInputLocal_Array& v_inp = vertices->getInput_array();
|
||||
if (inputs[j]->getOffset() != 0)
|
||||
{
|
||||
llerrs << "Vertex array offset MUST be zero." << llendl;
|
||||
}
|
||||
|
||||
for (U32 k = 0; k < v_inp.getCount(); ++k)
|
||||
{
|
||||
if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
|
||||
{
|
||||
const domURIFragmentType& uri = v_inp[k]->getSource();
|
||||
|
||||
daeElementRef elem = uri.getElement();
|
||||
domSource* src = (domSource*) elem.cast();
|
||||
|
||||
if (src->getTechnique_common()->getAccessor()->getStride() != 3)
|
||||
{
|
||||
llerrs << "Vertex array stride MUST be three." << llendl;
|
||||
}
|
||||
|
||||
domListOfFloats& v = src->getFloat_array()->getValue();
|
||||
|
||||
LLVector4a min;
|
||||
min.set(v[min_idx], v[min_idx+1], v[min_idx+2]);
|
||||
LLVector4a max = min;
|
||||
|
||||
for (U32 j = min_idx; j <= max_idx; ++j)
|
||||
{ //copy vertex array
|
||||
face.mPositions[j-min_idx].set(v[j*3+0], v[j*3+1], v[j*3+2]);
|
||||
update_min_max(min, max, face.mPositions[j-min_idx]);
|
||||
}
|
||||
|
||||
face.mExtents[0] = min;
|
||||
face.mExtents[1] = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0)
|
||||
{
|
||||
//found normal array for this triangle list
|
||||
const domURIFragmentType& uri = inputs[j]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domSource* src = (domSource*) elem.cast();
|
||||
domListOfFloats& n = src->getFloat_array()->getValue();
|
||||
|
||||
for (U32 j = min_idx; j <= max_idx; ++j)
|
||||
{
|
||||
LLVector4a* norm = (LLVector4a*) face.mNormals + (j-min_idx);
|
||||
norm->set(n[j*3+0], n[j*3+1], n[j*3+2]);
|
||||
norm->normalize3();
|
||||
}
|
||||
}
|
||||
else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0)
|
||||
{ //found texCoords
|
||||
const domURIFragmentType& uri = inputs[j]->getSource();
|
||||
daeElementRef elem = uri.getElement();
|
||||
domSource* src = (domSource*) elem.cast();
|
||||
domListOfFloats& u = src->getFloat_array()->getValue();
|
||||
|
||||
for (U32 j = min_idx; j <= max_idx; ++j)
|
||||
{
|
||||
face.mTexCoords[j-min_idx].setVec(u[j*2+0], u[j*2+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
|
||||
domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)
|
||||
{
|
||||
|
||||
idx_stride = 0;
|
||||
|
||||
for (U32 j = 0; j < inputs.getCount(); ++j)
|
||||
|
|
@ -271,14 +194,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
|
||||
tc[idx[i+tc_offset]*2+1]);
|
||||
}
|
||||
|
||||
|
||||
if (norm_source)
|
||||
{
|
||||
cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
|
||||
n[idx[i+norm_offset]*3+1],
|
||||
n[idx[i+norm_offset]*3+2]));
|
||||
}
|
||||
|
||||
|
||||
BOOL found = FALSE;
|
||||
|
||||
|
|
@ -329,10 +251,22 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
{
|
||||
face_list.push_back(face);
|
||||
face_list.rbegin()->fillFromLegacyData(verts, indices);
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
face = LLVolumeFace();
|
||||
point_map.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!verts.empty())
|
||||
|
|
@ -348,6 +282,18 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
face_list.push_back(face);
|
||||
|
||||
face_list.rbegin()->fillFromLegacyData(verts, indices);
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return LLModel::NO_ERRORS ;
|
||||
|
|
@ -433,14 +379,14 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],
|
||||
tc[idx[cur_idx+tc_offset]*2+1]);
|
||||
}
|
||||
|
||||
|
||||
if (norm_source)
|
||||
{
|
||||
cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
|
||||
n[idx[cur_idx+norm_offset]*3+1],
|
||||
n[idx[cur_idx+norm_offset]*3+2]);
|
||||
}
|
||||
|
||||
|
||||
cur_idx += idx_stride;
|
||||
|
||||
BOOL found = FALSE;
|
||||
|
|
@ -524,6 +470,19 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
{
|
||||
face_list.push_back(face);
|
||||
face_list.rbegin()->fillFromLegacyData(verts, indices);
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
face = LLVolumeFace();
|
||||
verts.clear();
|
||||
indices.clear();
|
||||
|
|
@ -540,10 +499,23 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
{
|
||||
material = std::string(poly->getMaterial());
|
||||
}
|
||||
|
||||
|
||||
materials.push_back(material);
|
||||
face_list.push_back(face);
|
||||
face_list.rbegin()->fillFromLegacyData(verts, indices);
|
||||
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return LLModel::NO_ERRORS ;
|
||||
|
|
@ -557,7 +529,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
|
||||
const domInputLocalOffset_Array& inputs = poly->getInput_array();
|
||||
|
||||
|
||||
S32 v_offset = -1;
|
||||
S32 n_offset = -1;
|
||||
S32 t_offset = -1;
|
||||
|
|
@ -662,15 +633,14 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
n->get(n_idx+1),
|
||||
n->get(n_idx+2));
|
||||
}
|
||||
|
||||
|
||||
if (t)
|
||||
{
|
||||
U32 t_idx = idx[j*stride+t_offset]*2;
|
||||
vert.mTexCoord.setVec(t->get(t_idx),
|
||||
t->get(t_idx+1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
verts.push_back(vert);
|
||||
}
|
||||
}
|
||||
|
|
@ -733,6 +703,19 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
materials.push_back(material);
|
||||
face_list.push_back(face);
|
||||
face_list.rbegin()->fillFromLegacyData(new_verts, indices);
|
||||
|
||||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!n)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!t)
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return LLModel::NO_ERRORS ;
|
||||
|
|
@ -817,9 +800,9 @@ BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh)
|
|||
|
||||
if (getNumVolumeFaces() > 0)
|
||||
{
|
||||
optimizeVolumeFaces();
|
||||
normalizeVolumeFaces();
|
||||
|
||||
optimizeVolumeFaces();
|
||||
|
||||
if (getNumVolumeFaces() > 0)
|
||||
{
|
||||
return TRUE;
|
||||
|
|
@ -853,81 +836,10 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint )
|
|||
|
||||
void LLModel::optimizeVolumeFaces()
|
||||
{
|
||||
#if 0 //VECTORIZE ?
|
||||
for (std::vector<LLVolumeFace>::iterator iter = mVolumeFaces.begin(); iter != mVolumeFaces.end(); )
|
||||
for (U32 i = 0; i < getNumVolumeFaces(); ++i)
|
||||
{
|
||||
std::vector<LLVolumeFace>::iterator cur_iter = iter++;
|
||||
LLVolumeFace& face = *cur_iter;
|
||||
|
||||
for (S32 i = 0; i < (S32) face.mNumIndices; i += 3)
|
||||
{ //remove zero area triangles
|
||||
U16 i0 = face.mIndices[i+0];
|
||||
U16 i1 = face.mIndices[i+1];
|
||||
U16 i2 = face.mIndices[i+2];
|
||||
|
||||
if (i0 == i1 ||
|
||||
i1 == i2 ||
|
||||
i0 == i2)
|
||||
{ //duplicate index in triangle, remove triangle
|
||||
face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3);
|
||||
i -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVolumeFace::VertexData& v0 = face.mVertices[i0];
|
||||
LLVolumeFace::VertexData& v1 = face.mVertices[i1];
|
||||
LLVolumeFace::VertexData& v2 = face.mVertices[i2];
|
||||
|
||||
if (v0.mPosition == v1.mPosition ||
|
||||
v1.mPosition == v2.mPosition ||
|
||||
v2.mPosition == v0.mPosition)
|
||||
{ //zero area triangle, delete
|
||||
face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3);
|
||||
i-=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remove unreference vertices
|
||||
std::vector<bool> ref;
|
||||
ref.resize(face.mNumVertices);
|
||||
|
||||
for (U32 i = 0; i < ref.size(); ++i)
|
||||
{
|
||||
ref[i] = false;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < face.mNumIndices; ++i)
|
||||
{
|
||||
ref[face.mIndices[i]] = true;
|
||||
}
|
||||
|
||||
U32 unref_count = 0;
|
||||
for (U32 i = 0; i < ref.size(); ++i)
|
||||
{
|
||||
if (!ref[i])
|
||||
{
|
||||
//vertex is unreferenced
|
||||
face.mVertices.erase(face.mVertices.begin()+(i-unref_count));
|
||||
U16 idx = (U16) (i-unref_count);
|
||||
|
||||
for (U32 j = 0; j < face.mNumIndices; ++j)
|
||||
{ //decrement every index array value greater than idx
|
||||
if (face.mIndices[j] > idx)
|
||||
{
|
||||
--face.mIndices[j];
|
||||
}
|
||||
}
|
||||
++unref_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (face.mVertices.empty() || face.mIndices.empty())
|
||||
{ //face is empty, remove it
|
||||
iter = mVolumeFaces.erase(cur_iter);
|
||||
}
|
||||
mVolumeFaces[i].optimize();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Shrink the model to fit
|
||||
|
|
@ -962,6 +874,25 @@ void LLModel::normalizeVolumeFaces()
|
|||
|
||||
update_min_max(min, max, face.mExtents[0]);
|
||||
update_min_max(min, max, face.mExtents[1]);
|
||||
|
||||
if (face.mTexCoords)
|
||||
{
|
||||
LLVector2& min_tc = face.mTexCoordExtents[0];
|
||||
LLVector2& max_tc = face.mTexCoordExtents[1];
|
||||
|
||||
min_tc = face.mTexCoords[0];
|
||||
max_tc = face.mTexCoords[0];
|
||||
|
||||
for (U32 j = 1; j < face.mNumVertices; ++j)
|
||||
{
|
||||
update_min_max(min_tc, max_tc, face.mTexCoords[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
face.mTexCoordExtents[0].set(0,0);
|
||||
face.mTexCoordExtents[1].set(1,1);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have the extents of the model
|
||||
|
|
@ -1029,8 +960,11 @@ void LLModel::normalizeVolumeFaces()
|
|||
{
|
||||
pos[j].add(trans);
|
||||
pos[j].mul(scale);
|
||||
norm[j].mul(inv_scale);
|
||||
norm[j].normalize3();
|
||||
if (norm && !norm[j].equals3(LLVector4a::getZero()))
|
||||
{
|
||||
norm[j].mul(inv_scale);
|
||||
norm[j].normalize3();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1073,8 +1007,26 @@ void LLModel::setVolumeFaceData(
|
|||
face.resizeIndices(num_indices);
|
||||
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*sizeof(F32));
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32));
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
|
||||
if (norm.get())
|
||||
{
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32));
|
||||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(face.mNormals);
|
||||
face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (tc.get())
|
||||
{
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
|
||||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
U32 size = (num_indices*2+0xF)&~0xF;
|
||||
LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size);
|
||||
}
|
||||
|
|
@ -1477,9 +1429,8 @@ LLSD LLModel::writeModel(
|
|||
{ //for each vert
|
||||
|
||||
F32* pos = face.mPositions[j].getF32ptr();
|
||||
F32* norm = face.mNormals[j].getF32ptr();
|
||||
|
||||
//position + normal
|
||||
|
||||
//position
|
||||
for (U32 k = 0; k < 3; ++k)
|
||||
{ //for each component
|
||||
//convert to 16-bit normalized across domain
|
||||
|
|
@ -1489,29 +1440,41 @@ LLSD LLModel::writeModel(
|
|||
//write to binary buffer
|
||||
verts[vert_idx++] = buff[0];
|
||||
verts[vert_idx++] = buff[1];
|
||||
|
||||
//convert to 16-bit normalized
|
||||
val = (U16) ((norm[k]+1.f)*0.5f*65535);
|
||||
|
||||
//write to binary buffer
|
||||
normals[norm_idx++] = buff[0];
|
||||
normals[norm_idx++] = buff[1];
|
||||
}
|
||||
|
||||
if (face.mNormals)
|
||||
{ //normals
|
||||
F32* norm = face.mNormals[j].getF32ptr();
|
||||
|
||||
for (U32 k = 0; k < 3; ++k)
|
||||
{ //for each component
|
||||
//convert to 16-bit normalized
|
||||
U16 val = (U16) ((norm[k]+1.f)*0.5f*65535);
|
||||
U8* buff = (U8*) &val;
|
||||
|
||||
//write to binary buffer
|
||||
normals[norm_idx++] = buff[0];
|
||||
normals[norm_idx++] = buff[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
F32* src_tc = (F32*) face.mTexCoords[j].mV;
|
||||
|
||||
//texcoord
|
||||
for (U32 k = 0; k < 2; ++k)
|
||||
{ //for each component
|
||||
//convert to 16-bit normalized
|
||||
U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535);
|
||||
if (face.mTexCoords)
|
||||
{
|
||||
for (U32 k = 0; k < 2; ++k)
|
||||
{ //for each component
|
||||
//convert to 16-bit normalized
|
||||
U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535);
|
||||
|
||||
U8* buff = (U8*) &val;
|
||||
//write to binary buffer
|
||||
tc[tc_idx++] = buff[0];
|
||||
tc[tc_idx++] = buff[1];
|
||||
U8* buff = (U8*) &val;
|
||||
//write to binary buffer
|
||||
tc[tc_idx++] = buff[0];
|
||||
tc[tc_idx++] = buff[1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
U32 idx_idx = 0;
|
||||
|
|
@ -1525,12 +1488,20 @@ LLSD LLModel::writeModel(
|
|||
//write out face data
|
||||
mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
|
||||
mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue();
|
||||
|
||||
mdl[model_names[idx]][i]["Position"] = verts;
|
||||
mdl[model_names[idx]][i]["Normal"] = normals;
|
||||
mdl[model_names[idx]][i]["TexCoord0"] = tc;
|
||||
|
||||
if (face.mNormals)
|
||||
{
|
||||
mdl[model_names[idx]][i]["Normal"] = normals;
|
||||
}
|
||||
|
||||
if (face.mTexCoords)
|
||||
{
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue();
|
||||
mdl[model_names[idx]][i]["TexCoord0"] = tc;
|
||||
}
|
||||
|
||||
mdl[model_names[idx]][i]["TriangleList"] = indices;
|
||||
|
||||
if (skinning)
|
||||
|
|
|
|||
|
|
@ -3719,7 +3719,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
|
|||
U32 tri_count = 0;
|
||||
for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i)
|
||||
{
|
||||
mVertexBuffer[5][mdl][i]->setBuffer(type_mask);
|
||||
LLVertexBuffer* buff = mVertexBuffer[5][mdl][i];
|
||||
buff->setBuffer(type_mask & buff->getTypeMask());
|
||||
|
||||
U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices();
|
||||
if (num_indices > 2)
|
||||
{
|
||||
|
|
@ -3841,6 +3843,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
|
|||
|
||||
for (GLint i = 0; i < patch_count; ++i)
|
||||
{
|
||||
type_mask = mVertexBuffer[5][base][i]->getTypeMask();
|
||||
|
||||
LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
|
||||
|
||||
if (sizes[i*2+1] > 0 && sizes[i*2] > 0)
|
||||
|
|
@ -3865,8 +3869,15 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
|
|||
LLStrider<U16> index;
|
||||
|
||||
buff->getVertexStrider(pos);
|
||||
buff->getNormalStrider(norm);
|
||||
buff->getTexCoord0Strider(tc);
|
||||
if (type_mask & LLVertexBuffer::MAP_NORMAL)
|
||||
{
|
||||
buff->getNormalStrider(norm);
|
||||
}
|
||||
if (type_mask & LLVertexBuffer::MAP_TEXCOORD0)
|
||||
{
|
||||
buff->getTexCoord0Strider(tc);
|
||||
}
|
||||
|
||||
buff->getIndexStrider(index);
|
||||
|
||||
target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices());
|
||||
|
|
@ -4462,7 +4473,16 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
|
|||
|
||||
bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
|
||||
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX;
|
||||
|
||||
if (vf.mNormals)
|
||||
{
|
||||
mask |= LLVertexBuffer::MAP_NORMAL;
|
||||
}
|
||||
if (vf.mTexCoords)
|
||||
{
|
||||
mask |= LLVertexBuffer::MAP_TEXCOORD0;
|
||||
}
|
||||
|
||||
if (skinned)
|
||||
{
|
||||
|
|
@ -4480,8 +4500,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
|
|||
LLStrider<LLVector4> weights_strider;
|
||||
|
||||
vb->getVertexStrider(vertex_strider);
|
||||
vb->getNormalStrider(normal_strider);
|
||||
vb->getTexCoord0Strider(tc_strider);
|
||||
vb->getIndexStrider(index_strider);
|
||||
|
||||
if (skinned)
|
||||
|
|
@ -4490,8 +4508,18 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
|
|||
}
|
||||
|
||||
LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32));
|
||||
LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
|
||||
LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32));
|
||||
|
||||
if (vf.mTexCoords)
|
||||
{
|
||||
vb->getTexCoord0Strider(tc_strider);
|
||||
LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
|
||||
}
|
||||
|
||||
if (vf.mNormals)
|
||||
{
|
||||
vb->getNormalStrider(normal_strider);
|
||||
LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32));
|
||||
}
|
||||
|
||||
if (skinned)
|
||||
{
|
||||
|
|
@ -4750,6 +4778,8 @@ BOOL LLModelPreview::render()
|
|||
const F32 BRIGHTNESS = 0.9f;
|
||||
gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
|
||||
|
||||
const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
|
||||
|
||||
LLGLEnable normalize(GL_NORMALIZE);
|
||||
|
||||
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
|
||||
|
|
@ -4798,8 +4828,8 @@ BOOL LLModelPreview::render()
|
|||
for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i)
|
||||
{
|
||||
LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
|
||||
|
||||
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
|
||||
buffer->setBuffer(type_mask & buffer->getTypeMask());
|
||||
|
||||
if (textures)
|
||||
{
|
||||
|
|
@ -4918,7 +4948,7 @@ BOOL LLModelPreview::render()
|
|||
{
|
||||
LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
|
||||
|
||||
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
buffer->setBuffer(type_mask & buffer->getTypeMask());
|
||||
|
||||
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
|
@ -4984,7 +5014,7 @@ BOOL LLModelPreview::render()
|
|||
{
|
||||
LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
|
||||
|
||||
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
buffer->setBuffer(type_mask & buffer->getTypeMask());
|
||||
|
||||
LLStrider<LLVector3> pos_strider;
|
||||
buffer->getVertexStrider(pos_strider, 0);
|
||||
|
|
@ -5109,7 +5139,7 @@ BOOL LLModelPreview::render()
|
|||
position[j] = v;
|
||||
}
|
||||
|
||||
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
buffer->setBuffer(type_mask & buffer->getTypeMask());
|
||||
glColor4fv(instance.mMaterial[i].mDiffuseColor.mV);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue