llvolumemessage.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "message.h"
00035 #include "llvolumemessage.h"
00036 #include "lldatapacker.h"
00037 
00038 //============================================================================
00039 
00040 // LLVolumeMessage is just a wrapper class; all members are static
00041 
00042 //============================================================================
00043 
00044 bool LLVolumeMessage::packProfileParams(
00045         const LLProfileParams* params,
00046         LLMessageSystem *mesgsys)
00047 {
00048         // Default to cylinder
00049         static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0));
00050         
00051         if (!params)
00052                 params = &defaultparams;
00053         
00054         U8 tempU8;
00055         U16 tempU16;
00056         
00057         tempU8 = params->getCurveType();
00058         mesgsys->addU8Fast(_PREHASH_ProfileCurve, tempU8);
00059 
00060         tempU16 = (U16) llround( params->getBegin() / CUT_QUANTA);
00061         mesgsys->addU16Fast(_PREHASH_ProfileBegin, tempU16);
00062 
00063         tempU16 = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
00064         mesgsys->addU16Fast(_PREHASH_ProfileEnd, tempU16);
00065 
00066         tempU16 = (U16) llround(params->getHollow() / HOLLOW_QUANTA);
00067         mesgsys->addU16Fast(_PREHASH_ProfileHollow, tempU16);
00068 
00069         return true;
00070 }
00071 
00072 bool LLVolumeMessage::packProfileParams(
00073         const LLProfileParams* params,
00074         LLDataPacker &dp)
00075 {
00076         // Default to cylinder
00077         static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0));
00078         
00079         if (!params)
00080                 params = &defaultparams;
00081         
00082         U8 tempU8;
00083         U16 tempU16;
00084         
00085         tempU8 = params->getCurveType();
00086         dp.packU8(tempU8, "Curve");
00087 
00088         tempU16 = (U16) llround( params->getBegin() / CUT_QUANTA);
00089         dp.packU16(tempU16, "Begin");
00090 
00091         tempU16 = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
00092         dp.packU16(tempU16, "End");
00093 
00094         tempU16 = (U16) llround(params->getHollow() / HOLLOW_QUANTA);
00095         dp.packU16(tempU16, "Hollow");
00096         return true;
00097 }
00098 
00099 bool LLVolumeMessage::unpackProfileParams(
00100         LLProfileParams* params,
00101         LLMessageSystem* mesgsys,
00102         char* block_name,
00103         S32 block_num)
00104 {
00105         bool ok = true;
00106         U8 temp_u8;
00107         U16 temp_u16;
00108         F32 temp_f32;
00109 
00110         mesgsys->getU8Fast(block_name, _PREHASH_ProfileCurve, temp_u8, block_num);
00111         params->setCurveType(temp_u8);
00112 
00113         mesgsys->getU16Fast(block_name, _PREHASH_ProfileBegin, temp_u16, block_num);
00114         temp_f32 = temp_u16 * CUT_QUANTA;
00115         if (temp_f32 > 1.f)
00116         {
00117                 llwarns << "Profile begin out of range: " << temp_f32
00118                         << ". Clamping to 0.0." << llendl;
00119                 temp_f32 = 0.f;
00120                 ok = false;
00121         }
00122         params->setBegin(temp_f32);
00123 
00124         mesgsys->getU16Fast(block_name, _PREHASH_ProfileEnd, temp_u16, block_num);
00125         temp_f32 = temp_u16 * CUT_QUANTA;
00126         if (temp_f32 > 1.f)
00127         {
00128                 llwarns << "Profile end out of range: " << 1.f - temp_f32
00129                         << ". Clamping to 1.0." << llendl;
00130                 temp_f32 = 1.f;
00131                 ok = false;
00132         }
00133         params->setEnd(1.f - temp_f32);
00134 
00135         mesgsys->getU16Fast(block_name, _PREHASH_ProfileHollow, temp_u16, block_num);
00136         temp_f32 = temp_u16 * HOLLOW_QUANTA;
00137         if (temp_f32 > 1.f)
00138         {
00139                 llwarns << "Profile hollow out of range: " << temp_f32
00140                         << ". Clamping to 0.0." << llendl;
00141                 temp_f32 = 0.f;
00142                 ok = false;
00143         }
00144         params->setHollow(temp_f32);
00145 
00146         /*
00147         llinfos << "Unpacking Profile Block " << block_num << llendl;
00148         llinfos << "Curve:     " << (U32)getCurve() << llendl;
00149         llinfos << "Begin:     " << getBegin() << llendl;
00150         llinfos << "End:     " << getEnd() << llendl;
00151         llinfos << "Hollow:     " << getHollow() << llendl;
00152         */
00153         return ok;
00154 
00155 }
00156 
00157 bool LLVolumeMessage::unpackProfileParams(
00158         LLProfileParams* params,
00159         LLDataPacker &dp)
00160 {
00161         bool ok = true;
00162         U8 temp_u8;
00163         U16 temp_u16;
00164         F32 temp_f32;
00165 
00166         dp.unpackU8(temp_u8, "Curve");
00167         params->setCurveType(temp_u8);
00168 
00169         dp.unpackU16(temp_u16, "Begin");
00170         temp_f32 = temp_u16 * CUT_QUANTA;
00171         if (temp_f32 > 1.f)
00172         {
00173                 llwarns << "Profile begin out of range: " << temp_f32 << llendl;
00174                 llwarns << "Clamping to 0.0" << llendl;
00175                 temp_f32 = 0.f;
00176                 ok = false;
00177         }
00178         params->setBegin(temp_f32);
00179 
00180         dp.unpackU16(temp_u16, "End");
00181         temp_f32 = temp_u16 * CUT_QUANTA;
00182         if (temp_f32 > 1.f)
00183         {
00184                 llwarns << "Profile end out of range: " << 1.f - temp_f32 << llendl;
00185                 llwarns << "Clamping to 1.0" << llendl;
00186                 temp_f32 = 1.f;
00187                 ok = false;
00188         }
00189         params->setEnd(1.f - temp_f32);
00190 
00191         dp.unpackU16(temp_u16, "Hollow");
00192         temp_f32 = temp_u16 * HOLLOW_QUANTA;
00193         if (temp_f32 > 1.f)
00194         {
00195                 llwarns << "Profile hollow out of range: " << temp_f32 << llendl;
00196                 llwarns << "Clamping to 0.0" << llendl;
00197                 temp_f32 = 0.f;
00198                 ok = false;
00199         }
00200         params->setHollow(temp_f32);
00201 
00202         return ok;
00203 }
00204 
00205 //============================================================================
00206 
00207 // Quantization:
00208 // For cut begin, range is 0 to 1, quanta is 0.005, 0 maps to 0
00209 // For cut end, range is 0 to 1, quanta is 0.005, 1 maps to 0
00210 // For scale, range is 0 to 1, quanta is 0.01, 0 maps to 0, 1 maps to 100
00211 // For shear, range is -0.5 to 0.5, quanta is 0.01, 0 maps to 0
00212 // For taper, range is -1 to 1, quanta is 0.01, 0 maps to 0
00213 bool LLVolumeMessage::packPathParams(
00214         const LLPathParams* params,
00215         LLMessageSystem *mesgsys)
00216 {
00217         // Default to cylinder with no cut, top same size as bottom, no shear, no twist
00218         static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0);
00219         if (!params)
00220                 params = &defaultparams;
00221         
00222         U8 curve = params->getCurveType();
00223         mesgsys->addU8Fast(_PREHASH_PathCurve, curve);
00224 
00225         U16 begin = (U16) llround(params->getBegin() / CUT_QUANTA);
00226         mesgsys->addU16Fast(_PREHASH_PathBegin, begin);
00227 
00228         U16 end = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
00229         mesgsys->addU16Fast(_PREHASH_PathEnd, end);
00230 
00231         // Avoid truncation problem with direct F32->U8 cast.
00232         // (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50.
00233 
00234         U8 pack_scale_x = 200 - (U8) llround(params->getScaleX() / SCALE_QUANTA);
00235         mesgsys->addU8Fast(_PREHASH_PathScaleX, pack_scale_x );
00236 
00237         U8 pack_scale_y = 200 - (U8) llround(params->getScaleY() / SCALE_QUANTA);
00238         mesgsys->addU8Fast(_PREHASH_PathScaleY, pack_scale_y );
00239 
00240         U8 pack_shear_x = (U8) llround(params->getShearX() / SHEAR_QUANTA);
00241         mesgsys->addU8Fast(_PREHASH_PathShearX, pack_shear_x );
00242 
00243         U8 pack_shear_y = (U8) llround(params->getShearY() / SHEAR_QUANTA);
00244         mesgsys->addU8Fast(_PREHASH_PathShearY, pack_shear_y );
00245 
00246         S8 twist = (S8) llround(params->getTwist() / SCALE_QUANTA);
00247         mesgsys->addS8Fast(_PREHASH_PathTwist, twist);
00248 
00249         S8 twist_begin = (S8) llround(params->getTwistBegin() / SCALE_QUANTA);
00250         mesgsys->addS8Fast(_PREHASH_PathTwistBegin, twist_begin);
00251 
00252         S8 radius_offset = (S8) llround(params->getRadiusOffset() / SCALE_QUANTA);
00253         mesgsys->addS8Fast(_PREHASH_PathRadiusOffset, radius_offset);
00254 
00255         S8 taper_x = (S8) llround(params->getTaperX() / TAPER_QUANTA);
00256         mesgsys->addS8Fast(_PREHASH_PathTaperX, taper_x);
00257 
00258         S8 taper_y = (S8) llround(params->getTaperY() / TAPER_QUANTA);
00259         mesgsys->addS8Fast(_PREHASH_PathTaperY, taper_y);
00260 
00261         U8 revolutions = (U8) llround( (params->getRevolutions() - 1.0f) / REV_QUANTA);
00262         mesgsys->addU8Fast(_PREHASH_PathRevolutions, revolutions);
00263 
00264         S8 skew = (S8) llround(params->getSkew() / SCALE_QUANTA);
00265         mesgsys->addS8Fast(_PREHASH_PathSkew, skew);
00266 
00267         return true;
00268 }
00269 
00270 bool LLVolumeMessage::packPathParams(
00271         const LLPathParams* params,
00272         LLDataPacker &dp)
00273 {
00274         // Default to cylinder with no cut, top same size as bottom, no shear, no twist
00275         static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0);
00276         if (!params)
00277                 params = &defaultparams;
00278         
00279         U8 curve = params->getCurveType();
00280         dp.packU8(curve, "Curve");
00281 
00282         U16 begin = (U16) llround(params->getBegin() / CUT_QUANTA);
00283         dp.packU16(begin, "Begin");
00284 
00285         U16 end = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
00286         dp.packU16(end, "End");
00287 
00288         // Avoid truncation problem with direct F32->U8 cast.
00289         // (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50.
00290 
00291         U8 pack_scale_x = 200 - (U8) llround(params->getScaleX() / SCALE_QUANTA);
00292         dp.packU8(pack_scale_x, "ScaleX");
00293 
00294         U8 pack_scale_y = 200 - (U8) llround(params->getScaleY() / SCALE_QUANTA);
00295         dp.packU8(pack_scale_y, "ScaleY");
00296 
00297         S8 pack_shear_x = (S8) llround(params->getShearX() / SHEAR_QUANTA);
00298         dp.packU8(*(U8 *)&pack_shear_x, "ShearX");
00299 
00300         S8 pack_shear_y = (S8) llround(params->getShearY() / SHEAR_QUANTA);
00301         dp.packU8(*(U8 *)&pack_shear_y, "ShearY");
00302 
00303         S8 twist = (S8) llround(params->getTwist() / SCALE_QUANTA);
00304         dp.packU8(*(U8 *)&twist, "Twist");
00305         
00306         S8 twist_begin = (S8) llround(params->getTwistBegin() / SCALE_QUANTA);
00307         dp.packU8(*(U8 *)&twist_begin, "TwistBegin");
00308 
00309         S8 radius_offset = (S8) llround(params->getRadiusOffset() / SCALE_QUANTA);
00310         dp.packU8(*(U8 *)&radius_offset, "RadiusOffset");
00311 
00312         S8 taper_x = (S8) llround(params->getTaperX() / TAPER_QUANTA);
00313         dp.packU8(*(U8 *)&taper_x, "TaperX");
00314 
00315         S8 taper_y = (S8) llround(params->getTaperY() / TAPER_QUANTA);
00316         dp.packU8(*(U8 *)&taper_y, "TaperY");
00317 
00318         U8 revolutions = (U8) llround( (params->getRevolutions() - 1.0f) / REV_QUANTA);
00319         dp.packU8(*(U8 *)&revolutions, "Revolutions");
00320 
00321         S8 skew = (S8) llround(params->getSkew() / SCALE_QUANTA);
00322         dp.packU8(*(U8 *)&skew, "Skew");
00323 
00324         return true;
00325 }
00326 
00327 bool LLVolumeMessage::unpackPathParams(
00328         LLPathParams* params,
00329         LLMessageSystem* mesgsys,
00330         char* block_name,
00331         S32 block_num)
00332 {
00333         U8 curve;
00334         mesgsys->getU8Fast(block_name, _PREHASH_PathCurve, curve, block_num);
00335         params->setCurveType(curve);
00336 
00337         U16 begin;
00338         mesgsys->getU16Fast(block_name, _PREHASH_PathBegin, begin, block_num);
00339         params->setBegin((F32)(begin * CUT_QUANTA));
00340 
00341         U16 end;
00342         mesgsys->getU16Fast(block_name, _PREHASH_PathEnd, end, block_num);
00343         params->setEnd((F32)((50000 - end) * CUT_QUANTA));
00344 
00345         U8 pack_scale_x, pack_scale_y;
00346         mesgsys->getU8Fast(block_name, _PREHASH_PathScaleX, pack_scale_x, block_num);
00347         mesgsys->getU8Fast(block_name, _PREHASH_PathScaleY, pack_scale_y, block_num);
00348         F32 x = (F32) (200 - pack_scale_x) * SCALE_QUANTA;
00349         F32 y = (F32) (200 - pack_scale_y) * SCALE_QUANTA;
00350         params->setScale( x, y );
00351 
00352         S8 shear_x_quant, shear_y_quant;
00353         mesgsys->getS8Fast(block_name, _PREHASH_PathShearX, shear_x_quant, block_num);
00354         mesgsys->getS8Fast(block_name, _PREHASH_PathShearY, shear_y_quant, block_num);
00355         F32 shear_x = (F32) shear_x_quant * SHEAR_QUANTA;
00356         F32 shear_y = (F32) shear_y_quant * SHEAR_QUANTA;
00357         params->setShear( shear_x, shear_y );
00358 
00359         S8 twist;
00360         mesgsys->getS8Fast(block_name, _PREHASH_PathTwist, twist, block_num );
00361         params->setTwist((F32)(twist * SCALE_QUANTA));
00362 
00363         S8 twist_begin;
00364         mesgsys->getS8Fast(block_name, _PREHASH_PathTwistBegin, twist_begin, block_num );
00365         params->setTwistBegin((F32)(twist_begin * SCALE_QUANTA));
00366         
00367         S8 radius_offset;
00368         mesgsys->getS8Fast(block_name, _PREHASH_PathRadiusOffset, radius_offset, block_num );
00369         params->setRadiusOffset((F32)(radius_offset * SCALE_QUANTA));
00370 
00371         S8 taper_x_quant, taper_y_quant;
00372         mesgsys->getS8Fast(block_name, _PREHASH_PathTaperX, taper_x_quant, block_num );
00373         mesgsys->getS8Fast(block_name, _PREHASH_PathTaperY, taper_y_quant, block_num );
00374         F32 taper_x = (F32)(taper_x_quant * TAPER_QUANTA);
00375         F32 taper_y = (F32)(taper_y_quant * TAPER_QUANTA);
00376         params->setTaper( taper_x, taper_y );
00377 
00378         U8 revolutions;
00379         mesgsys->getU8Fast(block_name, _PREHASH_PathRevolutions, revolutions, block_num );
00380         params->setRevolutions((F32)(revolutions * REV_QUANTA + 1.0f));
00381 
00382         S8 skew;
00383         mesgsys->getS8Fast(block_name, _PREHASH_PathSkew, skew, block_num );
00384         params->setSkew((F32)(skew * SCALE_QUANTA));
00385 
00386 /*
00387         llinfos << "Unpacking Path Block " << block_num << llendl;
00388         llinfos << "Curve:     " << (U32)params->getCurve() << llendl;
00389         llinfos << "Begin:     " << params->getBegin() << llendl;
00390         llinfos << "End:     " << params->getEnd() << llendl;
00391         llinfos << "Scale:     " << params->getScale() << llendl;
00392         llinfos << "Twist:     " << params->getTwist() << llendl;
00393 */
00394 
00395         return true;
00396 
00397 }
00398 
00399 bool LLVolumeMessage::unpackPathParams(LLPathParams* params, LLDataPacker &dp)
00400 {
00401         U8 value;
00402         S8 svalue;
00403         U16 temp_u16;
00404         
00405         dp.unpackU8(value, "Curve");
00406         params->setCurveType( value );
00407 
00408         dp.unpackU16(temp_u16, "Begin");
00409         params->setBegin((F32)(temp_u16 * CUT_QUANTA));
00410 
00411         dp.unpackU16(temp_u16, "End");
00412         params->setEnd((F32)((50000 - temp_u16) * CUT_QUANTA));
00413 
00414         dp.unpackU8(value, "ScaleX");
00415         F32 x = (F32) (200 - value) * SCALE_QUANTA;
00416         dp.unpackU8(value, "ScaleY");
00417         F32 y = (F32) (200 - value) * SCALE_QUANTA;
00418         params->setScale( x, y );
00419 
00420         dp.unpackU8(value, "ShearX");
00421         svalue = *(S8 *)&value;
00422         F32 shear_x = (F32) svalue * SHEAR_QUANTA;
00423         dp.unpackU8(value, "ShearY");
00424         svalue = *(S8 *)&value;
00425         F32 shear_y = (F32) svalue * SHEAR_QUANTA;
00426         params->setShear( shear_x, shear_y );
00427 
00428         dp.unpackU8(value, "Twist");
00429         svalue = *(S8 *)&value;
00430         params->setTwist((F32)(svalue * SCALE_QUANTA));
00431 
00432         dp.unpackU8(value, "TwistBegin");
00433         svalue = *(S8 *)&value;
00434         params->setTwistBegin((F32)(svalue * SCALE_QUANTA));
00435 
00436         dp.unpackU8(value, "RadiusOffset");
00437         svalue = *(S8 *)&value;
00438         params->setRadiusOffset((F32)(svalue * SCALE_QUANTA));
00439 
00440         dp.unpackU8(value, "TaperX");
00441         svalue = *(S8 *)&value;
00442         params->setTaperX((F32)(svalue * TAPER_QUANTA));
00443 
00444         dp.unpackU8(value, "TaperY");
00445         svalue = *(S8 *)&value;
00446         params->setTaperY((F32)(svalue * TAPER_QUANTA));
00447 
00448         dp.unpackU8(value, "Revolutions");
00449         params->setRevolutions((F32)(value * REV_QUANTA + 1.0f));
00450 
00451         dp.unpackU8(value, "Skew");
00452         svalue = *(S8 *)&value;
00453         params->setSkew((F32)(svalue * SCALE_QUANTA));
00454 
00455         return true;
00456 }
00457 
00458 //============================================================================
00459 
00460 // static
00461 bool LLVolumeMessage::constrainVolumeParams(LLVolumeParams& params)
00462 {
00463         U32 bad = 0;
00464 
00465         // This is called immediately after an unpack. feed the raw data
00466         // through the checked setters to constraint it to a valid set of
00467         // volume params.
00468         bad |= params.setType(params.getProfileParams().getCurveType(),
00469                                                  params.getPathParams().getCurveType()) ? 0 : 1;
00470         bad |= params.setBeginAndEndS(params.getProfileParams().getBegin(),
00471                                                                   params.getProfileParams().getEnd()) ? 0 : 2;
00472         bad |= params.setBeginAndEndT(params.getPathParams().getBegin(),
00473                                                                   params.getPathParams().getEnd()) ? 0 : 4;
00474         bad |= params.setHollow(params.getProfileParams().getHollow()) ? 0 : 8;
00475         bad |= params.setTwistBegin(params.getPathParams().getTwistBegin()) ? 0 : 0x10;
00476         bad |= params.setTwistEnd(params.getPathParams().getTwistEnd()) ? 0 : 0x20;
00477         bad |= params.setRatio(params.getPathParams().getScaleX(),
00478                                                    params.getPathParams().getScaleY()) ? 0 : 0x40;
00479         bad |= params.setShear(params.getPathParams().getShearX(),
00480                                                    params.getPathParams().getShearY()) ? 0 : 0x80;
00481         bad |= params.setTaper(params.getPathParams().getTaperX(),
00482                                                    params.getPathParams().getTaperY()) ? 0 : 0x100;
00483         bad |= params.setRevolutions(params.getPathParams().getRevolutions()) ? 0 : 0x200;
00484         bad |= params.setRadiusOffset(params.getPathParams().getRadiusOffset()) ? 0 : 0x400;
00485         bad |= params.setSkew(params.getPathParams().getSkew()) ? 0 : 0x800;
00486         if(bad)
00487         {
00488                 llwarns << "LLVolumeMessage::constrainVolumeParams() - "
00489                                 << "forced to constrain incoming volume params: "
00490                                 << llformat("0x%04x",bad) << llendl;
00491         }
00492         return bad ? false : true;
00493 }
00494 
00495 bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLMessageSystem *mesgsys)
00496 {
00497         // llinfos << "pack volume" << llendl;
00498         if (params)
00499         {
00500                 packPathParams(&params->getPathParams(), mesgsys);
00501                 packProfileParams(&params->getProfileParams(), mesgsys);
00502         }
00503         else
00504         {
00505                 packPathParams(0, mesgsys);
00506                 packProfileParams(0, mesgsys);
00507         }
00508         return true;
00509 }
00510 
00511 bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLDataPacker &dp)
00512 {
00513         // llinfos << "pack volume" << llendl;
00514         if (params)
00515         {
00516                 packPathParams(&params->getPathParams(), dp);
00517                 packProfileParams(&params->getProfileParams(), dp);
00518         }
00519         else
00520         {
00521                 packPathParams(0, dp);
00522                 packProfileParams(0, dp);
00523         }
00524         return true;
00525 }
00526 
00527 bool LLVolumeMessage::unpackVolumeParams(
00528         LLVolumeParams* params,
00529         LLMessageSystem* mesgsys,
00530         char* block_name,
00531         S32 block_num)
00532 {
00533         bool ok = true;
00534         ok &= unpackPathParams(
00535                 &params->getPathParams(),
00536                 mesgsys,
00537                 block_name,
00538                 block_num);
00539         ok &= unpackProfileParams(
00540                 &params->getProfileParams(),
00541                 mesgsys,
00542                 block_name,
00543                 block_num);
00544         ok &= constrainVolumeParams(*params);
00545                 
00546         return ok;
00547 }
00548 
00549 bool LLVolumeMessage::unpackVolumeParams(
00550         LLVolumeParams* params,
00551         LLDataPacker &dp)
00552 {
00553         bool ok = true;
00554         ok &= unpackPathParams(&params->getPathParams(), dp);
00555         ok &= unpackProfileParams(&params->getProfileParams(), dp);
00556         ok &= constrainVolumeParams(*params);
00557         return ok;
00558 }
00559 
00560 //============================================================================

Generated on Thu Jul 1 06:09:41 2010 for Second Life Viewer by  doxygen 1.4.7