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).

meow-7.2.2
Dave Parks 2011-06-18 01:02:03 -05:00
parent 1b01476dad
commit 15235061e8
3 changed files with 319 additions and 235 deletions

View File

@ -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);
}

View File

@ -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)

View File

@ -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);