//----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); LLJoint* joint; joint_vec_map_t::iterator iter; for (iter = mJointScales.begin(); iter != mJointScales.end(); iter++) { joint = iter->first; LLVector3 newScale = joint->getScale(); LLVector3 scaleDelta = iter->second; newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta); joint->setScale(newScale); } for (iter = mJointOffsets.begin(); iter != mJointOffsets.end(); iter++) { joint = iter->first; LLVector3 newPosition = joint->getPosition(); LLVector3 positionDelta = iter->second; newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta); joint->setPosition(newPosition); } if (mLastWeight != mCurWeight && !mIsAnimating) { mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); } mLastWeight = mCurWeight; }
void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake) { if (mIsAnimating) { return; } const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo(); F32 min_weight = getMinWeight(); F32 max_weight = getMaxWeight(); F32 new_weight = llclamp(weight, min_weight, max_weight); U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight); U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight); if (cur_u8 != new_u8) { mCurWeight = new_weight; if (info->mNumColors <= 0) { // This will happen when we set the default weight the first time. return; } if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. { onGlobalColorChanged(upload_bake); if (mTexLayer) { mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); } } // llinfos << "param " << mName << " = " << new_weight << llendl; } }
LLColor4 LLTexLayerParamColor::getNetColor() const { const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo(); llassert(info->mNumColors >= 1); F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight(); S32 index_last = info->mNumColors - 1; F32 scaled_weight = effective_weight * index_last; S32 index_start = (S32) scaled_weight; S32 index_end = index_start + 1; if (index_start == index_last) { return info->mColors[index_last]; } else { F32 weight = scaled_weight - index_start; const LLColor4 *start = &info->mColors[ index_start ]; const LLColor4 *end = &info->mColors[ index_end ]; return LLColor4((1.f - weight) * start->mV[VX] + weight * end->mV[VX], (1.f - weight) * start->mV[VY] + weight * end->mV[VY], (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ], (1.f - weight) * start->mV[VW] + weight * end->mV[VW]); } }
BOOL LLTexLayerParamAlpha::getSkip() const { if (!mTexLayer) { return TRUE; } const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar(); if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight) { F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); if (is_approx_zero(effective_weight)) { return TRUE; } } LLWearableType::EType type = (LLWearableType::EType)getWearableType(); if ((type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType(type)) { return TRUE; } return FALSE; }
void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake) { if (mIsAnimating || mTexLayer == NULL) { return; } F32 min_weight = getMinWeight(); F32 max_weight = getMaxWeight(); F32 new_weight = llclamp(weight, min_weight, max_weight); U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight); U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight); if (cur_u8 != new_u8) { mCurWeight = new_weight; if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. { if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) { upload_bake = FALSE; } mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); mTexLayer->invalidateMorphMasks(); } } }
TaiwanCollegeStudent &TaiwanCollegeStudent::printfIndroduce(){ cout << "姓名: " << getName() << endl; cout << "身分證: " <<TaiwanCard::getId() << endl; cout << "性別: " << getSex() << endl; cout << "生日: " << getDate() << endl; cout << "校名: " << getSchoolName() << endl; cout << "學號: " << PCCUCard::getId() << endl; cout << "入學年度: " << getYear() << endl; TaiwanCard::checkYear(*this); PCCUCard::checkYear(*this); return *this; }
//---------------------------------------------------------------------- // get debug string //---------------------------------------------------------------------- string PCSlayerInfo::toString () const throw() { StringStream msg; msg << "PCSlayerInfo(" << "NSize:" << m_Name.size() << ",Name:" << m_Name << ",Slot:" << Slot2String[m_Slot] << ",Alignment:" << m_Alignment << ",Rank:" << m_Rank << ",STR[BASIC]:" << (int)m_STR << ",DEX[BASIC]:" << (int)m_DEX << ",INT[BASIC]:" << (int)m_INT << ",HP:" << m_HP[ATTR_CURRENT] << "/" << m_HP[ATTR_MAX] << ",MP:" << m_MP[ATTR_CURRENT] << "/" << m_MP[ATTR_MAX] << ",Fame:" << m_Fame; // << ",Gold:" << m_Gold; for (uint i = 0 ; i < SKILL_DOMAIN_VAMPIRE ; i ++ ) msg << "," << SkillDomain2String[i] << ":" << (int)m_DomainLevels[i]; // msg << ",ZoneID:" << m_ZoneID msg << ",Sex:" << Sex2String[getSex()] << ",HairStyle:" << HairStyle2String[getHairStyle()] << ",HairColor:" << (int)getHairColor() << ",SkinColor:" << (int)getSkinColor() << " ,Helmet:" << (int)getHelmetType() << ",HelmetColor:" << (int)getHelmetColor() << " ,Jacket:" << (int)getJacketType() << ",JacketColor:" << (int)getJacketColor() << " ,Pants:" << (int)getPantsType() << ",PantsColor:" << (int)getPantsColor() << " ,Weapon:" << (int)getWeaponType() << ",WeaponColor:" << (int)getWeaponColor() << " ,Shield:" << (int)getShieldType() << ",ShieldColor:" << (int)getShieldColor() << ")"; return msg.toString(); }
void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { LL_RECORD_BLOCK_TIME(FTM_POLYSKELETAL_DISTORTION_APPLY); F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); LLJoint* joint; joint_vec_map_t::iterator iter; for (iter = mJointScales.begin(); iter != mJointScales.end(); iter++) { joint = iter->first; LLVector3 newScale = joint->getScale(); LLVector3 scaleDelta = iter->second; newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta); //An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached // needed? // joint->storeScaleForReset( newScale ); joint->setScale(newScale); } for (iter = mJointOffsets.begin(); iter != mJointOffsets.end(); iter++) { joint = iter->first; LLVector3 newPosition = joint->getPosition(); LLVector3 positionDelta = iter->second; newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta); joint->setPosition(newPosition); } if (mLastWeight != mCurWeight && !mIsAnimating) { mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); } mLastWeight = mCurWeight; }
void LLPolyMorphTarget::apply( ESex avatar_sex ) { if (!mMorphData || mNumMorphMasksPending > 0) { return; } LL_RECORD_BLOCK_TIME(FTM_APPLY_MORPH_TARGET); mLastSex = avatar_sex; // Check for NaN condition (NaN is detected if a variable doesn't equal itself. if (mCurWeight != mCurWeight) { mCurWeight = 0.0; } if (mLastWeight != mLastWeight) { mLastWeight = mCurWeight+.001; } // perform differential update of morph F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight); // store last weight mLastWeight += delta_weight; if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); LLVector4a *coords = mMesh->getWritableCoords(); LLVector4a *scaled_normals = mMesh->getScaledNormals(); LLVector4a *normals = mMesh->getWritableNormals(); LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); LLVector4a *binormals = mMesh->getWritableBinormals(); LLVector4a *clothing_weights = mMesh->getWritableClothingWeights(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; for(U32 vert_index_morph = 0; vert_index_morph < mMorphData->mNumIndices; vert_index_morph++) { S32 vert_index_mesh = mMorphData->mVertexIndices[vert_index_morph]; F32 maskWeight = 1.f; if (maskWeightArray) { maskWeight = maskWeightArray[vert_index_morph]; } LLVector4a pos = mMorphData->mCoords[vert_index_morph]; pos.mul(delta_weight*maskWeight); coords[vert_index_mesh].add(pos); if (getInfo()->mIsClothingMorph && clothing_weights) { LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph]; clothing_offset.mul(delta_weight * maskWeight); LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh]; clothing_weight->add(clothing_offset); clothing_weight->getF32ptr()[VW] = maskWeight; } // calculate new normals based on half angles LLVector4a norm = mMorphData->mNormals[vert_index_morph]; norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); scaled_normals[vert_index_mesh].add(norm); norm = scaled_normals[vert_index_mesh]; // guard against degenerate input data before we create NaNs below! // norm.normalize3fast(); normals[vert_index_mesh] = norm; // calculate new binormals LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; // guard against degenerate input data before we create NaNs below! // if (!binorm.isFinite3() || (binorm.dot3(binorm).getF32() <= F_APPROXIMATELY_ZERO)) { binorm.set(1,0,0,1); } binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); scaled_binormals[vert_index_mesh].add(binorm); LLVector4a tangent; tangent.setCross3(scaled_binormals[vert_index_mesh], norm); LLVector4a& normalized_binormal = binormals[vert_index_mesh]; normalized_binormal.setCross3(norm, tangent); normalized_binormal.normalize3fast(); tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; } // now apply volume changes for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ ) { LLPolyVolumeMorph* volume_morph = &(*iter); LLVector3 scale_delta = volume_morph->mScale * delta_weight; LLVector3 pos_delta = volume_morph->mPos * delta_weight; volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); } } if (mNext) { mNext->apply(avatar_sex); } }
//----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- void LLPolyMorphTarget::apply( ESex avatar_sex ) { if (!mMorphData || mNumMorphMasksPending > 0) { return; } mLastSex = avatar_sex; // Check for NaN condition (NaN is detected if a variable doesn't equal itself. if (mCurWeight != mCurWeight) { mCurWeight = 0.0; } if (mLastWeight != mLastWeight) { mLastWeight = mCurWeight+.001; } // perform differential update of morph F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight); // store last weight mLastWeight += delta_weight; if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); LLVector4 *normals = mMesh->getWritableNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector3 *binormals = mMesh->getWritableBinormals(); LLVector4 *clothing_weights = mMesh->getWritableClothingWeights(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; for(U32 vert_index_morph = 0; vert_index_morph < mMorphData->mNumIndices; vert_index_morph++) { S32 vert_index_mesh = mMorphData->mVertexIndices[vert_index_morph]; F32 maskWeight = 1.f; if (maskWeightArray) { maskWeight = maskWeightArray[vert_index_morph]; } coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); if (getInfo()->mIsClothingMorph && clothing_weights) { LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; LLVector4* clothing_weight = &clothing_weights[vert_index_mesh]; clothing_weight->mV[VX] += clothing_offset.mV[VX]; clothing_weight->mV[VY] += clothing_offset.mV[VY]; clothing_weight->mV[VZ] += clothing_offset.mV[VZ]; clothing_weight->mV[VW] = maskWeight; } // calculate new normals based on half angles scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; normalized_normal.normVec(); normals[vert_index_mesh] = LLVector4(normalized_normal); // calculate new binormals scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; LLVector3 tangent = scaled_binormals[vert_index_mesh] % normalized_normal; LLVector3 normalized_binormal = normalized_normal % tangent; normalized_binormal.normVec(); binormals[vert_index_mesh] = normalized_binormal; tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; } // now apply volume changes for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ ) { LLPolyVolumeMorph* volume_morph = &(*iter); LLVector3 scale_delta = volume_morph->mScale * delta_weight; LLVector3 pos_delta = volume_morph->mPos * delta_weight; volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); } } if (mNext) { mNext->apply(avatar_sex); } }
BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) { BOOL success = TRUE; if (!mTexLayer) { return success; } F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); BOOL weight_changed = effective_weight != mCachedEffectiveWeight; if (getSkip()) { return success; } LLTexLayerParamAlphaInfo *info = (LLTexLayerParamAlphaInfo *)getInfo(); gGL.flush(); if (info->mMultiplyBlend) { gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function } else { gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function } if (!info->mStaticImageFileName.empty() && !mStaticImageInvalid) { if (mStaticImageTGA.isNull()) { // Don't load the image file until we actually need it the first time. Like now. mStaticImageTGA = LLTexLayerStaticImageList::getInstance()->getImageTGA(info->mStaticImageFileName); // We now have something in one of our caches LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE; if (mStaticImageTGA.isNull()) { llwarns << "Unable to load static file: " << info->mStaticImageFileName << llendl; mStaticImageInvalid = TRUE; // don't try again. return FALSE; } } const S32 image_tga_width = mStaticImageTGA->getWidth(); const S32 image_tga_height = mStaticImageTGA->getHeight(); if (!mCachedProcessedTexture || (mCachedProcessedTexture->getWidth() != image_tga_width) || (mCachedProcessedTexture->getHeight() != image_tga_height) || (weight_changed)) { // llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl; mCachedEffectiveWeight = effective_weight; if (!mCachedProcessedTexture) { mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE); // We now have something in one of our caches LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE; mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA); } // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed. mStaticImageRaw = NULL; mStaticImageRaw = new LLImageRaw; mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight); mNeedsCreateTexture = TRUE; } if (mCachedProcessedTexture) { { // Create the GL texture, and then hang onto it for future use. if (mNeedsCreateTexture) { mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw); mNeedsCreateTexture = FALSE; gGL.getTexUnit(0)->bind(mCachedProcessedTexture); mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP); } LLGLSNoAlphaTest gls_no_alpha_test; gGL.getTexUnit(0)->bind(mCachedProcessedTexture); gl_rect_2d_simple_tex(width, height); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); } } // Don't keep the cache for other people's avatars // (It's not really a "cache" in that case, but the logic is the same) if (!mAvatar->isSelf()) { mCachedProcessedTexture = NULL; } } else { LLGLDisable no_alpha(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f(0.f, 0.f, 0.f, effective_weight); gl_rect_2d_simple(width, height); } return success; }