diff options
Diffstat (limited to 'linden/indra/newview/llvoavatar.cpp')
-rw-r--r-- | linden/indra/newview/llvoavatar.cpp | 128 |
1 files changed, 92 insertions, 36 deletions
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 8adb910..e480eb3 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp | |||
@@ -2155,6 +2155,12 @@ void LLVOAvatar::releaseMeshData() | |||
2155 | { | 2155 | { |
2156 | LLFace* facep = mDrawable->getFace(0); | 2156 | LLFace* facep = mDrawable->getFace(0); |
2157 | facep->setSize(0, 0); | 2157 | facep->setSize(0, 0); |
2158 | |||
2159 | for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) | ||
2160 | { | ||
2161 | facep = mDrawable->getFace(i); | ||
2162 | facep->setSize(0, 0); | ||
2163 | } | ||
2158 | } | 2164 | } |
2159 | 2165 | ||
2160 | for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); | 2166 | for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); |
@@ -2211,50 +2217,97 @@ void LLVOAvatar::updateMeshData() | |||
2211 | if (mDrawable.notNull()) | 2217 | if (mDrawable.notNull()) |
2212 | { | 2218 | { |
2213 | stop_glerror(); | 2219 | stop_glerror(); |
2214 | LLFace* facep = mDrawable->getFace(0); | ||
2215 | 2220 | ||
2216 | U32 num_vertices = 0; | 2221 | LLViewerJoint* av_parts[8] ; |
2217 | U32 num_indices = 0; | 2222 | av_parts[0] = &mEyeBallLeftLOD ; |
2223 | av_parts[1] = &mEyeBallRightLOD ; | ||
2224 | av_parts[2] = &mEyeLashLOD ; | ||
2225 | av_parts[3] = &mHeadLOD ; | ||
2226 | av_parts[4] = &mLowerBodyLOD ; | ||
2227 | av_parts[5] = &mSkirtLOD ; | ||
2228 | av_parts[6] = &mUpperBodyLOD ; | ||
2229 | av_parts[7] = &mHairLOD ; | ||
2230 | |||
2231 | S32 f_num = 0 ; | ||
2232 | const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer. | ||
2218 | 2233 | ||
2219 | // this order is determined by number of LODS | 2234 | // this order is determined by number of LODS |
2220 | // if a mesh earlier in this list changed LODs while a later mesh doesn't, | 2235 | // if a mesh earlier in this list changed LODs while a later mesh doesn't, |
2221 | // the later mesh's index offset will be inaccurate | 2236 | // the later mesh's index offset will be inaccurate |
2222 | mEyeBallLeftLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | 2237 | for(S32 part_index = 0 ; part_index < 8 ;) |
2223 | mEyeBallRightLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2224 | mEyeLashLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2225 | mHeadLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2226 | mLowerBodyLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2227 | mSkirtLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2228 | mUpperBodyLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2229 | mHairLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); | ||
2230 | |||
2231 | // resize immediately | ||
2232 | facep->setSize(num_vertices, num_indices); | ||
2233 | |||
2234 | facep->mVertexBuffer = new LLVertexBufferAvatar(); | ||
2235 | facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); | ||
2236 | |||
2237 | facep->setGeomIndex(0); | ||
2238 | facep->setIndicesIndex(0); | ||
2239 | |||
2240 | // This is a hack! Avatars have their own pool, so we are detecting | ||
2241 | // the case of more than one avatar in the pool (thus > 0 instead of >= 0) | ||
2242 | if (facep->getGeomIndex() > 0) | ||
2243 | { | 2238 | { |
2244 | llerrs << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << llendl; | 2239 | S32 j = part_index ; |
2245 | } | 2240 | U32 last_v_num = 0, num_vertices = 0 ; |
2241 | U32 last_i_num = 0, num_indices = 0 ; | ||
2246 | 2242 | ||
2247 | mEyeBallLeftLOD.updateFaceData(facep, mAdjustedPixelArea); | 2243 | while(part_index < 8 && num_vertices < VERTEX_NUMBER_THRESHOLD) |
2248 | mEyeBallRightLOD.updateFaceData(facep, mAdjustedPixelArea); | 2244 | { |
2249 | mEyeLashLOD.updateFaceData(facep, mAdjustedPixelArea); | 2245 | last_v_num = num_vertices ; |
2250 | mHeadLOD.updateFaceData(facep, mAdjustedPixelArea); | 2246 | last_i_num = num_indices ; |
2251 | mLowerBodyLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2252 | mSkirtLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2253 | mUpperBodyLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2254 | mHairLOD.updateFaceData(facep, mAdjustedPixelArea, TRUE); | ||
2255 | 2247 | ||
2256 | stop_glerror(); | 2248 | av_parts[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); |
2257 | facep->mVertexBuffer->setBuffer(0); | 2249 | } |
2250 | if(num_vertices < 1)//skip empty meshes | ||
2251 | { | ||
2252 | break ; | ||
2253 | } | ||
2254 | if(last_v_num > 0)//put the last inserted part into next vertex buffer. | ||
2255 | { | ||
2256 | num_vertices = last_v_num ; | ||
2257 | num_indices = last_i_num ; | ||
2258 | part_index-- ; | ||
2259 | } | ||
2260 | |||
2261 | LLFace* facep ; | ||
2262 | if(f_num < mDrawable->getNumFaces()) | ||
2263 | { | ||
2264 | facep = mDrawable->getFace(f_num); | ||
2265 | } | ||
2266 | else | ||
2267 | { | ||
2268 | facep = mDrawable->addFace(mDrawable->getFace(0)->getPool(), mDrawable->getFace(0)->getTexture()) ; | ||
2269 | } | ||
2270 | |||
2271 | // resize immediately | ||
2272 | facep->setSize(num_vertices, num_indices); | ||
2273 | |||
2274 | if(facep->mVertexBuffer.isNull()) | ||
2275 | { | ||
2276 | facep->mVertexBuffer = new LLVertexBufferAvatar(); | ||
2277 | facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); | ||
2278 | } | ||
2279 | else | ||
2280 | { | ||
2281 | facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; | ||
2282 | } | ||
2283 | |||
2284 | facep->setGeomIndex(0); | ||
2285 | facep->setIndicesIndex(0); | ||
2286 | |||
2287 | // This is a hack! Avatars have their own pool, so we are detecting | ||
2288 | // the case of more than one avatar in the pool (thus > 0 instead of >= 0) | ||
2289 | if (facep->getGeomIndex() > 0) | ||
2290 | { | ||
2291 | llerrs << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << llendl; | ||
2292 | } | ||
2293 | |||
2294 | for(S32 k = j ; k < part_index ; k++) | ||
2295 | { | ||
2296 | av_parts[k]->updateFaceData(facep, mAdjustedPixelArea, (k == 7)); | ||
2297 | } | ||
2298 | |||
2299 | stop_glerror(); | ||
2300 | facep->mVertexBuffer->setBuffer(0); | ||
2301 | |||
2302 | if(!f_num) | ||
2303 | { | ||
2304 | f_num += mNumInitFaces ; | ||
2305 | } | ||
2306 | else | ||
2307 | { | ||
2308 | f_num++ ; | ||
2309 | } | ||
2310 | } | ||
2258 | } | 2311 | } |
2259 | } | 2312 | } |
2260 | 2313 | ||
@@ -5852,6 +5905,7 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) | |||
5852 | LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*) gPipeline.getPool(LLDrawPool::POOL_AVATAR); | 5905 | LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*) gPipeline.getPool(LLDrawPool::POOL_AVATAR); |
5853 | 5906 | ||
5854 | // Only a single face (one per avatar) | 5907 | // Only a single face (one per avatar) |
5908 | //this face will be splitted into several if its vertex buffer is too long. | ||
5855 | mDrawable->setState(LLDrawable::ACTIVE); | 5909 | mDrawable->setState(LLDrawable::ACTIVE); |
5856 | mDrawable->addFace(poolp, NULL); | 5910 | mDrawable->addFace(poolp, NULL); |
5857 | mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR); | 5911 | mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR); |
@@ -5865,6 +5919,8 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) | |||
5865 | facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep); | 5919 | facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep); |
5866 | mShadow1Facep = facep; | 5920 | mShadow1Facep = facep; |
5867 | 5921 | ||
5922 | mNumInitFaces = mDrawable->getNumFaces() ; | ||
5923 | |||
5868 | dirtyMesh(); | 5924 | dirtyMesh(); |
5869 | return mDrawable; | 5925 | return mDrawable; |
5870 | } | 5926 | } |