00001
00032 #include "linden_common.h"
00033
00034 #include "message.h"
00035 #include "llvolumemessage.h"
00036 #include "lldatapacker.h"
00037
00038
00039
00040
00041
00042
00043
00044 bool LLVolumeMessage::packProfileParams(
00045 const LLProfileParams* params,
00046 LLMessageSystem *mesgsys)
00047 {
00048
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
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
00148
00149
00150
00151
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
00208
00209
00210
00211
00212
00213 bool LLVolumeMessage::packPathParams(
00214 const LLPathParams* params,
00215 LLMessageSystem *mesgsys)
00216 {
00217
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
00232
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
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
00289
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
00388
00389
00390
00391
00392
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
00461 bool LLVolumeMessage::constrainVolumeParams(LLVolumeParams& params)
00462 {
00463 U32 bad = 0;
00464
00465
00466
00467
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
00498 if (params)
00499 {
00500 packPathParams(¶ms->getPathParams(), mesgsys);
00501 packProfileParams(¶ms->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
00514 if (params)
00515 {
00516 packPathParams(¶ms->getPathParams(), dp);
00517 packProfileParams(¶ms->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 ¶ms->getPathParams(),
00536 mesgsys,
00537 block_name,
00538 block_num);
00539 ok &= unpackProfileParams(
00540 ¶ms->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(¶ms->getPathParams(), dp);
00555 ok &= unpackProfileParams(¶ms->getProfileParams(), dp);
00556 ok &= constrainVolumeParams(*params);
00557 return ok;
00558 }
00559
00560