// linear interpolation LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) { LLQuaternion r; r = t * (q - p) + p; r.normalize(); return r; }
void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) { // do not update if avatar didn't move if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) { return; } LLVector3 last_position; LLVector3 last_axis; last_position = getOrigin(); last_axis = getAtAxis(); mLastPointOfInterest = point_of_interest; // constrain to max distance from avatar LLVector3 camera_offset = center - gAgent.getPositionAgent(); LLViewerRegion * regp = gAgent.getRegion(); F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f; LLVector3 origin = center; if (origin.mV[2] > water_height) { origin.mV[2] = llmax(origin.mV[2], water_height+0.20f); } else { origin.mV[2] = llmin(origin.mV[2], water_height-0.20f); } setOriginAndLookAt(origin, up_direction, point_of_interest); mVelocityDir = center - last_position ; F32 dpos = mVelocityDir.normVec() ; LLQuaternion rotation; rotation.shortestArc(last_axis, getAtAxis()); F32 x, y, z; F32 drot; rotation.getAngleAxis(&drot, &x, &y, &z); mVelocityStat.addValue(dpos); mAngularVelocityStat.addValue(drot); mAverageSpeed = mVelocityStat.getMeanPerSec() ; mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ; mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); // update pixel meter ratio using default fov, not modified one mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5)); // update screen pixel area mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); }
// lerp from identity to q LLQuaternion lerp(F32 t, const LLQuaternion &q) { LLQuaternion r; r.mQ[VX] = t * q.mQ[VX]; r.mQ[VY] = t * q.mQ[VY]; r.mQ[VZ] = t * q.mQ[VZ]; r.mQ[VW] = t * (q.mQ[VZ] - 1.f) + 1.f; r.normalize(); return r; }
void LLToolGrab::startGrab() { // Compute grab_offset in the OBJECT's root's coordinate frame // (sometimes root == object) LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) { return; } LLViewerObject *root = (LLViewerObject *)objectp->getRoot(); // drag from center LLVector3d grab_start_global = root->getPositionGlobal(); // Where the grab starts, relative to the center of the root object of the set. // JC - This code looks wonky, but I believe it does the right thing. // Otherwise, when you grab a linked object set, it "pops" on the start // of the drag. LLVector3d grab_offsetd = root->getPositionGlobal() - objectp->getPositionGlobal(); LLVector3 grab_offset; grab_offset.setVec(grab_offsetd); LLQuaternion rotation = root->getRotation(); rotation.conjQuat(); grab_offset = grab_offset * rotation; // This planar drag starts at the grab point mDragStartPointGlobal = grab_start_global; mDragStartFromCamera = grab_start_global - gAgent.getCameraPositionGlobal(); LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_ObjectGrab); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset ); msg->nextBlock("SurfaceInfo"); msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords)); msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords)); msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace); msg->addVector3("Position", mGrabPick.mIntersection); msg->addVector3("Normal", mGrabPick.mNormal); msg->addVector3("Binormal", mGrabPick.mBinormal); msg->sendMessage( objectp->getRegion()->getHost()); mGrabOffsetFromCenterInitial = grab_offset; mGrabHiddenOffsetFromCamera = mDragStartFromCamera; mGrabTimer.reset(); }
LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) { LLQuaternion r; F32 inv_t; inv_t = 1.f - t; r.mQ[VX] = t * q.mQ[VX] + (inv_t * p.mQ[VX]); r.mQ[VY] = t * q.mQ[VY] + (inv_t * p.mQ[VY]); r.mQ[VZ] = t * q.mQ[VZ] + (inv_t * p.mQ[VZ]); r.mQ[VW] = t * q.mQ[VW] + (inv_t * p.mQ[VW]); r.normalize(); return r; }
void lggBeamMaps::fireCurrentBeams(LLPointer<LLHUDEffectSpiral> mBeam, const LLColor4U& rgb) { if (mScale == 0.0f) { return; } static LLCachedControl<std::string> colorf(gSavedSettings, "FSBeamColorFile"); bool colorsDisabled = (colorf().empty()); for (std::vector<lggBeamData>::iterator it = mDots.begin(); it != mDots.end(); ++it) { LLColor4U myColor = rgb; if (colorsDisabled) { myColor = (*it).c; } F32 distanceAdjust = dist_vec(mBeam->getPositionGlobal(), gAgent.getPositionGlobal()); F32 pulse = (F32)(.75f + sinf(gFrameTimeSeconds * 1.0f) * 0.25f); LLVector3d offset = (*it).p; offset.mdV[VY] *= -1.f; offset *= pulse * mScale * distanceAdjust * 0.1f; LLVector3 beamLine = LLVector3( mBeam->getPositionGlobal() - gAgent.getPositionGlobal()); LLVector3 beamLineFlat = beamLine; beamLineFlat.mV[VZ]= 0.0f; LLVector3 newDirFlat = LLVector3::x_axis; beamLine.normalize(); beamLineFlat.normalize(); LLQuaternion change; change.shortestArc(newDirFlat, beamLineFlat); offset.rotVec(change); newDirFlat.rotVec(change); change.shortestArc(newDirFlat, beamLine); offset.rotVec(change); LLPointer<LLHUDEffectSpiral> myBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); myBeam->setPositionGlobal(mBeam->getPositionGlobal() + offset + (LLVector3d(beamLine) * sinf(gFrameTimeSeconds * 2.0f) * 0.2f)); myBeam->setColor(myColor); myBeam->setTargetObject(mBeam->getTargetObject()); myBeam->setSourceObject(mBeam->getSourceObject()); myBeam->setNeedsSendToSim(mBeam->getNeedsSendToSim()); myBeam->setDuration(mDuration * 1.2f); } }
void ImportTracker::wear(LLSD &prim) { LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ObjectAttach); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->addU8Fast(_PREHASH_AttachmentPoint, U8(prim["Attachment"].asInteger())); msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addQuatFast(_PREHASH_Rotation, LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); msg->sendReliable(gAgent.getRegion()->getHost()); LLVector3 position = prim["attachpos"]; LLSD rot = prim["attachrot"]; LLQuaternion rotq; rotq.mQ[VX] = (F32)(rot[0].asReal()); rotq.mQ[VY] = (F32)(rot[1].asReal()); rotq.mQ[VZ] = (F32)(rot[2].asReal()); rotq.mQ[VW] = (F32)(rot[3].asReal()); LLVector3 rotation = rotq.packToVector3(); U8 data[256]; LLMessageSystem* msg2 = gMessageSystem; msg2->newMessageFast(_PREHASH_MultipleObjectUpdate); msg2->nextBlockFast(_PREHASH_AgentData); msg2->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg2->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg2->nextBlockFast(_PREHASH_ObjectData); msg2->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg2->addU8Fast(_PREHASH_Type, U8(0x01 | 0x08)); htonmemcpy(&data[0], &(position.mV), MVT_LLVector3, 12); msg2->addBinaryDataFast(_PREHASH_Data, data, 12); msg2->nextBlockFast(_PREHASH_ObjectData); msg2->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg2->addU8Fast(_PREHASH_Type, U8(0x02 | 0x08)); htonmemcpy(&data[0], &(rotation.mV), MVT_LLQuaternion, 12); msg2->addBinaryDataFast(_PREHASH_Data, data, 12); msg2->sendReliable(gAgent.getRegion()->getHost()); llinfos << "POSITIONED, IMPORT COMPLETED" << llendl; cleanUp(); }
void llquat_test_object_t::test<22>() { //test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn F32 roll = -12.0f; F32 pitch = -22.43f; F32 yaw = 11.0f; LLQuaternion llquat; llquat.getEulerAngles(&roll, &pitch, &yaw); ensure( "LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed", is_approx_equal(0.000f, llquat.mQ[0]) && is_approx_equal(0.000f, llquat.mQ[1]) && is_approx_equal(0.000f, llquat.mQ[2]) && is_approx_equal(1.000f, llquat.mQ[3])); }
void LLTemplateMessageReader::getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum) { LLVector3 vec; getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum); if( vec.isFinite() ) { q.unpackFromVector3( vec ); } else { llwarns << "non-finite in getQuatFast " << block << " " << var << llendl; q.loadIdentity(); } }
// SJB: This code is correct for a logicly stored (non-transposed) matrix; // Our matrices are stored transposed, OpenGL style, so this generates the // INVERSE quaternion (-x, -y, -z, w)! // Because we use similar logic in LLQuaternion::getMatrix3, // we are internally consistant so everything works OK :) LLQuaternion LLMatrix3::quaternion() const { LLQuaternion quat; F32 tr, s, q[4]; U32 i, j, k; U32 nxt[3] = {1, 2, 0}; tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2]; // check the diagonal if (tr > 0.f) { s = (F32)sqrt (tr + 1.f); quat.mQ[VS] = s / 2.f; s = 0.5f / s; quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s; quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s; quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s; } else { // diagonal is negative i = 0; if (mMatrix[1][1] > mMatrix[0][0]) i = 1; if (mMatrix[2][2] > mMatrix[i][i]) i = 2; j = nxt[i]; k = nxt[j]; s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f); q[i] = s * 0.5f; if (s != 0.f) s = 0.5f / s; q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s; q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s; q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s; quat.setQuat(q); } return quat; }
void LLToolGrab::startGrab() { // Compute grab_offset in the OBJECT's root's coordinate frame // (sometimes root == object) LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) { return; } LLViewerObject *root = (LLViewerObject *)objectp->getRoot(); // drag from center LLVector3d grab_start_global = root->getPositionGlobal(); // Where the grab starts, relative to the center of the root object of the set. // JC - This code looks wonky, but I believe it does the right thing. // Otherwise, when you grab a linked object set, it "pops" on the start // of the drag. LLVector3d grab_offsetd = root->getPositionGlobal() - objectp->getPositionGlobal(); LLVector3 grab_offset; grab_offset.setVec(grab_offsetd); LLQuaternion rotation = root->getRotation(); rotation.conjQuat(); grab_offset = grab_offset * rotation; // This planar drag starts at the grab point mDragStartPointGlobal = grab_start_global; mDragStartFromCamera = grab_start_global - gAgentCamera.getCameraPositionGlobal(); send_ObjectGrab_message(objectp, mGrabPick, grab_offset); mGrabOffsetFromCenterInitial = grab_offset; mGrabHiddenOffsetFromCamera = mDragStartFromCamera; mGrabTimer.reset(); mLastUVCoords = mGrabPick.mUVCoords; mLastSTCoords = mGrabPick.mSTCoords; mLastFace = mGrabPick.mObjectFace; mLastIntersection = mGrabPick.mIntersection; mLastNormal = mGrabPick.mNormal; mLastBinormal = mGrabPick.mBinormal; mLastGrabPos = LLVector3(-1.f, -1.f, -1.f); }
void lggBeamMaps::fireCurrentBeams(LLPointer<LLHUDEffectSpiral> mBeam, LLColor4U rgb) { if (scale == 0.0f) { return; } static LLCachedControl<std::string> colorf(gSavedSettings, "FSBeamColorFile"); bool colorsDisabled = std::string(colorf) == "===OFF==="; for(int i = 0; i < (int)dots.size(); i++) { LLColor4U myColor = rgb; if (colorsDisabled) myColor = dots[i].c; F32 distanceAdjust = dist_vec(mBeam->getPositionGlobal(),gAgent.getPositionGlobal()) ; F32 pulse = (F32)(.75f+sinf(gFrameTimeSeconds*1.0f)*0.25f); LLVector3d offset = dots[i].p; offset.mdV[VY] *= -1; offset *= pulse * scale * distanceAdjust * 0.1; //llinfos << "dist is " << distanceAdjust << "scale is " << scale << llendl; LLVector3 beamLine = LLVector3( mBeam->getPositionGlobal() - gAgent.getPositionGlobal()); LLVector3 beamLineFlat = beamLine; beamLineFlat.mV[VZ]= 0.0f; LLVector3 newDirFlat = LLVector3::x_axis; beamLine.normalize(); beamLineFlat.normalize(); LLQuaternion change; change.shortestArc(newDirFlat,beamLineFlat); offset.rotVec(change); newDirFlat.rotVec(change); change.shortestArc(newDirFlat,beamLine); offset.rotVec(change); LLPointer<LLHUDEffectSpiral> myBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); myBeam->setPositionGlobal(mBeam->getPositionGlobal() + offset + (LLVector3d(beamLine) * sinf(gFrameTimeSeconds*2.0f) * 0.2f)); myBeam->setColor(myColor); myBeam->setTargetObject(mBeam->getTargetObject()); myBeam->setSourceObject(mBeam->getSourceObject()); myBeam->setNeedsSendToSim(mBeam->getNeedsSendToSim()); myBeam->setDuration(duration* 1.2f); } }
void setup_transforms_bbox(LLBBox bbox) { // translate to center LLVector3 center = bbox.getCenterAgent(); gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]); // rotate LLQuaternion rotation = bbox.getRotation(); F32 angle_radians, x, y, z; rotation.getAngleAxis(&angle_radians, &x, &y, &z); gGL.flush(); gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); // scale LLVector3 scale = bbox.getMaxLocal() - bbox.getMinLocal(); gGL.scalef(scale.mV[VX], scale.mV[VY], scale.mV[VZ]); }
void ImportTracker::send_vectors(LLSD& prim,int counter) { LLVector3 position = ((LLVector3)prim["position"] * rootrot) + root; LLSD rot = prim["rotation"]; LLQuaternion rotq; rotq.mQ[VX] = (F32)(rot[0].asReal()); rotq.mQ[VY] = (F32)(rot[1].asReal()); rotq.mQ[VZ] = (F32)(rot[2].asReal()); rotq.mQ[VW] = (F32)(rot[3].asReal()); LLVector3 rotation; if(counter == 1) rotation = rotq.packToVector3(); else rotation = (rotq * rootrot).packToVector3(); LLVector3 scale = prim["scale"]; U8 data[256]; LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_MultipleObjectUpdate); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addU8Fast(_PREHASH_Type, U8(0x01)); htonmemcpy(&data[0], &(position.mV), MVT_LLVector3, 12); msg->addBinaryDataFast(_PREHASH_Data, data, 12); msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addU8Fast(_PREHASH_Type, U8(0x02)); htonmemcpy(&data[0], &(rotation.mV), MVT_LLQuaternion, 12); msg->addBinaryDataFast(_PREHASH_Data, data, 12); msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_ObjectLocalID, prim["LocalID"].asInteger()); msg->addU8Fast(_PREHASH_Type, U8(0x04)); htonmemcpy(&data[0], &(scale.mV), MVT_LLVector3, 12); msg->addBinaryDataFast(_PREHASH_Data, data, 12); msg->sendReliable(gAgent.getRegion()->getHost()); }
void setup_transforms_bbox(LLBBox bbox) { // translate to center LLVector3 center = bbox.getCenterAgent(); gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]); // rotate LLQuaternion rotation = bbox.getRotation(); F32 angle_radians, x, y, z; rotation.getAngleAxis(&angle_radians, &x, &y, &z); // gGL has no rotate method (despite having translate and scale) presumably because // its authors smoke crack. so we hack. gGL.flush(); glRotatef(angle_radians * RAD_TO_DEG, x, y, z); // scale LLVector3 scale = bbox.getMaxLocal() - bbox.getMinLocal(); gGL.scalef(scale.mV[VX], scale.mV[VY], scale.mV[VZ]); }
void multiple_object_update(LLViewerObject* object, U8 type) { gMessageSystem->newMessageFast(_PREHASH_MultipleObjectUpdate); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); U8 data[256]; gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); gMessageSystem->addU8Fast(_PREHASH_Type, type ); S32 offset = 0; // JC: You MUST pack the data in this order. The receiving // routine process_multiple_update_message on simulator will // extract them in this order. if (type & UPD_POSITION) { htonmemcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12); offset += 12; } if (type & UPD_ROTATION) { LLQuaternion quat = object->getRotation(); LLVector3 vec = quat.packToVector3(); htonmemcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12); offset += 12; } if (type & UPD_SCALE) { //llinfos << "Sending object scale " << object->getScale() << llendl; htonmemcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12); offset += 12; } gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset); gAgent.sendReliableMessage(); }
//-------------------------------------------------------------------- // setRotation() //-------------------------------------------------------------------- void LLJoint::setRotation( const LLQuaternion& rot ) { if (rot.isFinite()) { // if (mXform.getRotation() != rot) { mXform.setRotation(rot); touch(MATRIX_DIRTY | ROTATION_DIRTY); } } }
void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, const LLFontGL &font, const U8 style, const LLFontGL::ShadowType shadow, const F32 x_offset, const F32 y_offset, const LLColor4& color, const BOOL orthographic) { LLViewerCamera* camera = LLViewerCamera::getInstance(); // Do cheap plane culling LLVector3 dir_vec = pos_agent - camera->getOrigin(); dir_vec /= dir_vec.magVec(); if (wstr.empty() || (!orthographic && dir_vec * camera->getAtAxis() <= 0.f)) { return; } LLVector3 right_axis; LLVector3 up_axis; if (orthographic) { right_axis.setVec(0.f, -1.f / gViewerWindow->getWorldViewHeightScaled(), 0.f); up_axis.setVec(0.f, 0.f, 1.f / gViewerWindow->getWorldViewHeightScaled()); } else { camera->getPixelVectors(pos_agent, up_axis, right_axis); } LLCoordFrame render_frame = *camera; LLQuaternion rot; if (!orthographic) { rot = render_frame.getQuaternion(); rot = rot * LLQuaternion(-F_PI_BY_TWO, camera->getYAxis()); rot = rot * LLQuaternion(F_PI_BY_TWO, camera->getXAxis()); } else { rot = LLQuaternion(-F_PI_BY_TWO, LLVector3(0.f, 0.f, 1.f)); rot = rot * LLQuaternion(-F_PI_BY_TWO, LLVector3(0.f, 1.f, 0.f)); } F32 angle; LLVector3 axis; rot.getAngleAxis(&angle, axis); LLVector3 render_pos = pos_agent + (floorf(x_offset) * right_axis) + (floorf(y_offset) * up_axis); //get the render_pos in screen space LLVector3 window_coordinates; F32& winX = window_coordinates.mV[VX]; F32& winY = window_coordinates.mV[VY]; F32& winZ = window_coordinates.mV[VZ]; const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); glProjectf(render_pos, gGLModelView, gGLProjection, world_view_rect, window_coordinates); //fonts all render orthographically, set up projection`` gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); LLUI::pushMatrix(); gl_state_for_2d(world_view_rect.getWidth(), world_view_rect.getHeight()); gViewerWindow->setup3DViewport(); winX -= world_view_rect.mLeft; winY -= world_view_rect.mBottom; LLUI::loadIdentity(); gGL.loadIdentity(); LLUI::translate((F32) winX*1.0f/LLFontGL::sScaleX, (F32) winY*1.0f/(LLFontGL::sScaleY), -(((F32) winZ*2.f)-1.f)); F32 right_x; font.render(wstr, 0, 0, 0, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, wstr.length(), 1000, &right_x); LLUI::popMatrix(); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); }
void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, const LLFontGL &font, const U8 style, const F32 x_offset, const F32 y_offset, const LLColor4& color, const BOOL orthographic) { LLViewerCamera* camera = LLViewerCamera::getInstance(); // Do cheap plane culling LLVector3 dir_vec = pos_agent - camera->getOrigin(); dir_vec /= dir_vec.magVec(); if (wstr.empty() || (!orthographic && dir_vec * camera->getAtAxis() <= 0.f)) { return; } LLVector3 right_axis; LLVector3 up_axis; if (orthographic) { right_axis.setVec(0.f, -1.f / gViewerWindow->getWindowHeight(), 0.f); up_axis.setVec(0.f, 0.f, 1.f / gViewerWindow->getWindowHeight()); } else { camera->getPixelVectors(pos_agent, up_axis, right_axis); } LLCoordFrame render_frame = *camera; LLQuaternion rot; if (!orthographic) { rot = render_frame.getQuaternion(); rot = rot * LLQuaternion(-F_PI_BY_TWO, camera->getYAxis()); rot = rot * LLQuaternion(F_PI_BY_TWO, camera->getXAxis()); } else { rot = LLQuaternion(-F_PI_BY_TWO, LLVector3(0.f, 0.f, 1.f)); rot = rot * LLQuaternion(-F_PI_BY_TWO, LLVector3(0.f, 1.f, 0.f)); } F32 angle; LLVector3 axis; rot.getAngleAxis(&angle, axis); LLVector3 render_pos = pos_agent + (floorf(x_offset) * right_axis) + (floorf(y_offset) * up_axis); //get the render_pos in screen space F64 winX, winY, winZ; gluProject(render_pos.mV[0], render_pos.mV[1], render_pos.mV[2], gGLModelView, gGLProjection, (GLint*) gGLViewport, &winX, &winY, &winZ); //fonts all render orthographically, set up projection glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); LLUI::pushMatrix(); gViewerWindow->setup2DRender(); LLUI::loadIdentity(); LLUI::translate((F32) winX*1.0f/LLFontGL::sScaleX, (F32) winY*1.0f/(LLFontGL::sScaleY), -(((F32) winZ*2.f)-1.f)); //glRotatef(angle * RAD_TO_DEG, axis.mV[VX], axis.mV[VY], axis.mV[VZ]); //glScalef(right_scale, up_scale, 1.f); F32 right_x; font.render(wstr, 0, 0, 0, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, wstr.length(), 1000, &right_x); LLUI::popMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); }
//----------------------------------------------------------------------------- // LLEditingMotion::onUpdate() //----------------------------------------------------------------------------- BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) { LLVector3 focus_pt; LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint"); BOOL result = TRUE; if (!pointAtPt) { focus_pt = mLastSelectPt; result = FALSE; } else { focus_pt = *pointAtPt; mLastSelectPt = focus_pt; } focus_pt += mCharacter->getCharacterPosition(); // propagate joint positions to kinematic chain mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); // propagate current joint rotations to kinematic chain mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); // update target position from character LLVector3 target = focus_pt - mParentJoint.getPosition(); F32 target_dist = target.normVec(); LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f); edit_plane_normal.normVec(); edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation()); F32 dot = edit_plane_normal * target; if (dot < 0.f) { target = target + (edit_plane_normal * (dot * 2.f)); target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f); target.normVec(); } target = target * target_dist; if (!target.isFinite()) { LL_WARNS() << "Non finite target in editing motion with target distance of " << target_dist << " and focus point " << focus_pt << " and pointAtPt: "; if (pointAtPt) { LL_CONT << *pointAtPt; } else { LL_CONT << "NULL"; } LL_CONT << LL_ENDL; target.setVec(1.f, 1.f, 1.f); } mTarget.setPosition( target + mParentJoint.getPosition()); // LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; // update the ikSolver if (!mTarget.getPosition().isExactlyZero()) { LLQuaternion shoulderRot = mShoulderJoint.getRotation(); LLQuaternion elbowRot = mElbowJoint.getRotation(); mIKSolver.solve(); // use blending... F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE); shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot); elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); // now put blended values back into joints llassert(shoulderRot.isFinite()); llassert(elbowRot.isFinite()); mShoulderState->setRotation(shoulderRot); mElbowState->setRotation(elbowRot); mWristState->setRotation(LLQuaternion::DEFAULT); } mCharacter->setAnimationData("Hand Pose", &sHandPose); mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority); return result; }
// writes contents to datapacker BOOL LLBVHLoader::serialize(LLDataPacker& dp) { JointVector::iterator ji; KeyVector::iterator ki; F32 time; // count number of non-ignored joints S32 numJoints = 0; for (ji=mJoints.begin(); ji!=mJoints.end(); ++ji) { Joint *joint = *ji; if ( ! joint->mIgnore ) numJoints++; } // print header dp.packU16(KEYFRAME_MOTION_VERSION, "version"); dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); dp.packS32(mPriority, "base_priority"); dp.packF32(mDuration, "duration"); dp.packString(mEmoteName, "emote_name"); dp.packF32(mLoopInPoint, "loop_in_point"); dp.packF32(mLoopOutPoint, "loop_out_point"); dp.packS32(mLoop, "loop"); dp.packF32(mEaseIn, "ease_in_duration"); dp.packF32(mEaseOut, "ease_out_duration"); dp.packU32(mHand, "hand_pose"); dp.packU32(numJoints, "num_joints"); for ( ji = mJoints.begin(); ji != mJoints.end(); ++ji ) { Joint *joint = *ji; // if ignored, skip it if ( joint->mIgnore ) continue; LLQuaternion first_frame_rot; LLQuaternion fixup_rot; dp.packString(joint->mOutName, "joint_name"); dp.packS32(joint->mPriority, "joint_priority"); // compute coordinate frame rotation LLQuaternion frameRot( joint->mFrameMatrix ); LLQuaternion frameRotInv = ~frameRot; LLQuaternion offsetRot( joint->mOffsetMatrix ); // find mergechild and mergeparent joints, if specified LLQuaternion mergeParentRot; LLQuaternion mergeChildRot; Joint *mergeParent = NULL; Joint *mergeChild = NULL; JointVector::iterator mji; for (mji=mJoints.begin(); mji!=mJoints.end(); ++mji) { Joint *mjoint = *mji; if ( !joint->mMergeParentName.empty() && (mjoint->mName == joint->mMergeParentName) ) { mergeParent = *mji; } if ( !joint->mMergeChildName.empty() && (mjoint->mName == joint->mMergeChildName) ) { mergeChild = *mji; } } dp.packS32(joint->mNumRotKeys, "num_rot_keys"); LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); S32 outcount = 0; S32 frame = 1; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { if ((frame == 1) && joint->mRelativeRotationKey) { first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); fixup_rot.shortestArc(LLVector3::z_axis * first_frame_rot * frameRot, LLVector3::z_axis); } if (ki->mIgnoreRot) { frame++; continue; } time = (F32)frame * mFrameTime; if (mergeParent) { mergeParentRot = mayaQ( mergeParent->mKeys[frame-1].mRot[0], mergeParent->mKeys[frame-1].mRot[1], mergeParent->mKeys[frame-1].mRot[2], bvhStringToOrder(mergeParent->mOrder) ); LLQuaternion parentFrameRot( mergeParent->mFrameMatrix ); LLQuaternion parentOffsetRot( mergeParent->mOffsetMatrix ); mergeParentRot = ~parentFrameRot * mergeParentRot * parentFrameRot * parentOffsetRot; } else { mergeParentRot.loadIdentity(); } if (mergeChild) { mergeChildRot = mayaQ( mergeChild->mKeys[frame-1].mRot[0], mergeChild->mKeys[frame-1].mRot[1], mergeChild->mKeys[frame-1].mRot[2], bvhStringToOrder(mergeChild->mOrder) ); LLQuaternion childFrameRot( mergeChild->mFrameMatrix ); LLQuaternion childOffsetRot( mergeChild->mOffsetMatrix ); mergeChildRot = ~childFrameRot * mergeChildRot * childFrameRot * childOffsetRot; } else { mergeChildRot.loadIdentity(); } LLQuaternion inRot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); LLQuaternion outRot = frameRotInv* mergeChildRot * inRot * mergeParentRot * ~first_frame_rot * frameRot * offsetRot; U16 time_short = F32_to_U16(time, 0.f, mDuration); dp.packU16(time_short, "time"); U16 x, y, z; LLVector3 rot_vec = outRot.packToVector3(); rot_vec.quantize16(-1.f, 1.f, -1.f, 1.f); x = F32_to_U16(rot_vec.mV[VX], -1.f, 1.f); y = F32_to_U16(rot_vec.mV[VY], -1.f, 1.f); z = F32_to_U16(rot_vec.mV[VZ], -1.f, 1.f); dp.packU16(x, "rot_angle_x"); dp.packU16(y, "rot_angle_y"); dp.packU16(z, "rot_angle_z"); outcount++; frame++; } // output position keys (only for 1st joint) if ( ji == mJoints.begin() && !joint->mIgnorePositions ) { dp.packS32(joint->mNumPosKeys, "num_pos_keys"); LLVector3 relPos = joint->mRelativePosition; LLVector3 relKey; frame = 1; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { if ((frame == 1) && joint->mRelativePositionKey) { relKey.setVec(ki->mPos); } if (ki->mIgnorePos) { frame++; continue; } time = (F32)frame * mFrameTime; LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot; LLVector3 outPos = inPos * frameRot * offsetRot; outPos *= INCHES_TO_METERS; outPos -= relPos; outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); U16 time_short = F32_to_U16(time, 0.f, mDuration); dp.packU16(time_short, "time"); U16 x, y, z; outPos.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); x = F32_to_U16(outPos.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); y = F32_to_U16(outPos.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); z = F32_to_U16(outPos.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); dp.packU16(x, "pos_x"); dp.packU16(y, "pos_y"); dp.packU16(z, "pos_z"); frame++; } } else { dp.packS32(0, "num_pos_keys"); } } S32 num_constraints = (S32)mConstraints.size(); dp.packS32(num_constraints, "num_constraints"); for (ConstraintVector::iterator constraint_it = mConstraints.begin(); constraint_it != mConstraints.end(); constraint_it++) { U8 byte = constraint_it->mChainLength; dp.packU8(byte, "chain_lenght"); byte = constraint_it->mConstraintType; dp.packU8(byte, "constraint_type"); dp.packBinaryDataFixed((U8*)constraint_it->mSourceJointName, 16, "source_volume"); dp.packVector3(constraint_it->mSourceOffset, "source_offset"); dp.packBinaryDataFixed((U8*)constraint_it->mTargetJointName, 16, "target_volume"); dp.packVector3(constraint_it->mTargetOffset, "target_offset"); dp.packVector3(constraint_it->mTargetDir, "target_dir"); dp.packF32(constraint_it->mEaseInStart, "ease_in_start"); dp.packF32(constraint_it->mEaseInStop, "ease_in_stop"); dp.packF32(constraint_it->mEaseOutStart, "ease_out_start"); dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop"); } return TRUE; }
BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) { LLVector3 ray_start_region; LLVector3 ray_end_region; LLViewerRegion* regionp = NULL; BOOL b_hit_land = FALSE; S32 hit_face = -1; LLViewerObject* hit_obj = NULL; U8 state = 0; BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp ); if( !success ) { return FALSE; } if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) ) { // Can't create objects on avatars or attachments return FALSE; } if (NULL == regionp) { llwarns << "regionp was NULL; aborting function." << llendl; return FALSE; } if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX) { LLFirstUse::useSandbox(); } // Set params for new object based on its PCode. LLQuaternion rotation; LLVector3 scale = DEFAULT_OBJECT_SCALE; U8 material = LL_MCODE_WOOD; BOOL create_selected = FALSE; LLVolumeParams volume_params; switch (pcode) { case LL_PCODE_LEGACY_GRASS: // Randomize size of grass patch scale.setVec(10.f + ll_frand(20.f), 10.f + ll_frand(20.f), 1.f + ll_frand(2.f)); state = rand() % LLVOGrass::sMaxGrassSpecies; break; case LL_PCODE_LEGACY_TREE: case LL_PCODE_TREE_NEW: state = rand() % LLVOTree::sMaxTreeSpecies; break; case LL_PCODE_SPHERE: case LL_PCODE_CONE: case LL_PCODE_CUBE: case LL_PCODE_CYLINDER: case LL_PCODE_TORUS: case LLViewerObject::LL_VO_SQUARE_TORUS: case LLViewerObject::LL_VO_TRIANGLE_TORUS: default: create_selected = TRUE; break; } // Play creation sound if (gAudiop) { F32 volume = gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI"); gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), volume); } gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU8Fast(_PREHASH_Material, material); U32 flags = 0; // not selected if (use_physics) { flags |= FLAGS_USE_PHYSICS; } if (create_selected) { flags |= FLAGS_CREATE_SELECTED; } gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags ); LLPCode volume_pcode; // ...PCODE_VOLUME, or the original on error switch (pcode) { case LL_PCODE_SPHERE: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_TORUS: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1.f, 0.25f ); // "top size" volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LLViewerObject::LL_VO_SQUARE_TORUS: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1.f, 0.25f ); // "top size" volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LLViewerObject::LL_VO_TRIANGLE_TORUS: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1.f, 0.25f ); // "top size" volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_SPHERE_HEMI: volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); //volume_params.setBeginAndEndS( 0.5f, 1.f ); volume_params.setBeginAndEndT( 0.f, 0.5f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CUBE: volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_PRISM: volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 1 ); volume_params.setShear ( -0.5f, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_PYRAMID: volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_TETRAHEDRON: volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CYLINDER: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CYLINDER_HEMI: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.25f, 0.75f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CONE: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CONE_HEMI: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.25f, 0.75f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; default: LLVolumeMessage::packVolumeParams(0, gMessageSystem); volume_pcode = pcode; break; } gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode); gMessageSystem->addVector3Fast(_PREHASH_Scale, scale ); gMessageSystem->addQuatFast(_PREHASH_Rotation, rotation ); gMessageSystem->addVector3Fast(_PREHASH_RayStart, ray_start_region ); gMessageSystem->addVector3Fast(_PREHASH_RayEnd, ray_end_region ); gMessageSystem->addU8Fast(_PREHASH_BypassRaycast, (U8)b_hit_land ); gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE ); gMessageSystem->addU8Fast(_PREHASH_State, state); // Limit raycast to a single object. // Speeds up server raycast + avoid problems with server ray hitting objects // that were clipped by the near plane or culled on the viewer. LLUUID ray_target_id; if( hit_obj ) { ray_target_id = hit_obj->getID(); } else { ray_target_id.setNull(); } gMessageSystem->addUUIDFast(_PREHASH_RayTargetID, ray_target_id ); // Pack in name value pairs gMessageSystem->sendReliable(regionp->getHost()); // Spawns a message, so must be after above send if (create_selected) { gSelectMgr->deselectAll(); gViewerWindow->getWindow()->incBusyCount(); } // VEFFECT: AddObject LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); effectp->setSourceObject((LLViewerObject*)gAgent.getAvatarObject()); effectp->setPositionGlobal(regionp->getPosGlobalFromRegion(ray_end_region)); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); gViewerStats->incStat(LLViewerStats::ST_CREATE_COUNT); return TRUE; }
void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data) { // copy the blocks // counting variables used to encode multiple block info S32 block_count = 0; char* block_name = NULL; // loop through msg blocks to loop through variables, totalling up size // data and filling the new (send) message LLMsgData::msg_blk_data_map_t::const_iterator iter = data.mMemberBlocks.begin(); LLMsgData::msg_blk_data_map_t::const_iterator end = data.mMemberBlocks.end(); for(; iter != end; ++iter) { const LLMsgBlkData* mbci = iter->second; if(!mbci) continue; // do we need to encode a block code? if (block_count == 0) { block_count = mbci->mBlockNumber; block_name = (char*)mbci->mName; } // counting down mutliple blocks block_count--; nextBlock(block_name); // now loop through the variables LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); for(; dit != dend; ++dit) { const LLMsgVarData& mvci = *dit; const char* varname = mvci.getName(); switch(mvci.getType()) { case MVT_FIXED: addBinaryData(varname, mvci.getData(), mvci.getSize()); break; case MVT_VARIABLE: { const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated if (mvci.getDataSize() == 1 && end == 0) { addString(varname, (const char*)mvci.getData()); } else { addBinaryData(varname, mvci.getData(), mvci.getSize()); } break; } case MVT_U8: addU8(varname, *(U8*)mvci.getData()); break; case MVT_U16: addU16(varname, *(U16*)mvci.getData()); break; case MVT_U32: addU32(varname, *(U32*)mvci.getData()); break; case MVT_U64: addU64(varname, *(U64*)mvci.getData()); break; case MVT_S8: addS8(varname, *(S8*)mvci.getData()); break; case MVT_S16: addS16(varname, *(S16*)mvci.getData()); break; case MVT_S32: addS32(varname, *(S32*)mvci.getData()); break; // S64 not supported in LLSD so we just truncate it case MVT_S64: addS32(varname, *(S64*)mvci.getData()); break; case MVT_F32: addF32(varname, *(F32*)mvci.getData()); break; case MVT_F64: addF64(varname, *(F64*)mvci.getData()); break; case MVT_LLVector3: addVector3(varname, *(LLVector3*)mvci.getData()); break; case MVT_LLVector3d: addVector3d(varname, *(LLVector3d*)mvci.getData()); break; case MVT_LLVector4: addVector4(varname, *(LLVector4*)mvci.getData()); break; case MVT_LLQuaternion: { LLVector3 v = *(LLVector3*)mvci.getData(); LLQuaternion q; q.unpackFromVector3(v); addQuat(varname, q); break; } case MVT_LLUUID: addUUID(varname, *(LLUUID*)mvci.getData()); break; case MVT_BOOL: addBOOL(varname, *(BOOL*)mvci.getData()); break; case MVT_IP_ADDR: addIPAddr(varname, *(U32*)mvci.getData()); break; case MVT_IP_PORT: addIPPort(varname, *(U16*)mvci.getData()); break; case MVT_U16Vec3: //treated as an array of 6 bytes addBinaryData(varname, mvci.getData(), 6); break; case MVT_U16Quat: //treated as an array of 8 bytes addBinaryData(varname, mvci.getData(), 8); break; case MVT_S16Array: addBinaryData(varname, mvci.getData(), mvci.getSize()); break; default: llwarns << "Unknown type in conversion of message to LLSD" << llendl; break; } } } }
//----------------------------------------------------------------------------- // solve() //----------------------------------------------------------------------------- void LLJointSolverRP3::solve() { // llinfos << llendl; // llinfos << "LLJointSolverRP3::solve()" << llendl; //------------------------------------------------------------------------- // setup joints in their base rotations //------------------------------------------------------------------------- mJointA->setRotation( mJointABaseRotation ); mJointB->setRotation( mJointBBaseRotation ); //------------------------------------------------------------------------- // get joint positions in world space //------------------------------------------------------------------------- LLVector3 aPos = mJointA->getWorldPosition(); LLVector3 bPos = mJointB->getWorldPosition(); LLVector3 cPos = mJointC->getWorldPosition(); LLVector3 gPos = mJointGoal->getWorldPosition(); // llinfos << "bPosLocal = " << mJointB->getPosition() << llendl; // llinfos << "cPosLocal = " << mJointC->getPosition() << llendl; // llinfos << "bRotLocal = " << mJointB->getRotation() << llendl; // llinfos << "cRotLocal = " << mJointC->getRotation() << llendl; // llinfos << "aPos : " << aPos << llendl; // llinfos << "bPos : " << bPos << llendl; // llinfos << "cPos : " << cPos << llendl; // llinfos << "gPos : " << gPos << llendl; //------------------------------------------------------------------------- // get the poleVector in world space //------------------------------------------------------------------------- LLVector3 poleVec = mPoleVector; if ( mJointA->getParent() ) { LLVector4a pole_veca; pole_veca.load3(mPoleVector.mV); mJointA->getParent()->getWorldMatrix().rotate(pole_veca,pole_veca); poleVec.set(pole_veca.getF32ptr()); } //------------------------------------------------------------------------- // compute the following: // vector from A to B // vector from B to C // vector from A to C // vector from A to G (goal) //------------------------------------------------------------------------- LLVector3 abVec = bPos - aPos; LLVector3 bcVec = cPos - bPos; LLVector3 acVec = cPos - aPos; LLVector3 agVec = gPos - aPos; // llinfos << "abVec : " << abVec << llendl; // llinfos << "bcVec : " << bcVec << llendl; // llinfos << "acVec : " << acVec << llendl; // llinfos << "agVec : " << agVec << llendl; //------------------------------------------------------------------------- // compute needed lengths of those vectors //------------------------------------------------------------------------- F32 abLen = abVec.magVec(); F32 bcLen = bcVec.magVec(); F32 agLen = agVec.magVec(); // llinfos << "abLen : " << abLen << llendl; // llinfos << "bcLen : " << bcLen << llendl; // llinfos << "agLen : " << agLen << llendl; //------------------------------------------------------------------------- // compute component vector of (A->B) orthogonal to (A->C) //------------------------------------------------------------------------- LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); // llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl; //------------------------------------------------------------------------- // compute the normal of the original ABC plane (and store for later) //------------------------------------------------------------------------- LLVector3 abcNorm; if (!mbUseBAxis) { if( are_parallel(abVec, bcVec, 0.001f) ) { // the current solution is maxed out, so we use the axis that is // orthogonal to both poleVec and A->B if ( are_parallel(poleVec, abVec, 0.001f) ) { // ACK! the problem is singular if ( are_parallel(poleVec, agVec, 0.001f) ) { // the solutions is also singular return; } else { abcNorm = poleVec % agVec; } } else { abcNorm = poleVec % abVec; } } else { abcNorm = abVec % bcVec; } } else { abcNorm = mBAxis * mJointB->getWorldRotation(); } //------------------------------------------------------------------------- // compute rotation of B //------------------------------------------------------------------------- // angle between A->B and B->C F32 abbcAng = angle_between(abVec, bcVec); // vector orthogonal to A->B and B->C LLVector3 abbcOrthoVec = abVec % bcVec; if (abbcOrthoVec.magVecSquared() < 0.001f) { abbcOrthoVec = poleVec % abVec; abacCompOrthoVec = poleVec; } abbcOrthoVec.normVec(); F32 agLenSq = agLen * agLen; // angle arm for extension F32 cosTheta = (agLenSq - abLen*abLen - bcLen*bcLen) / (2.0f * abLen * bcLen); if (cosTheta > 1.0f) cosTheta = 1.0f; else if (cosTheta < -1.0f) cosTheta = -1.0f; F32 theta = acos(cosTheta); LLQuaternion bRot(theta - abbcAng, abbcOrthoVec); // llinfos << "abbcAng : " << abbcAng << llendl; // llinfos << "abbcOrthoVec : " << abbcOrthoVec << llendl; // llinfos << "agLenSq : " << agLenSq << llendl; // llinfos << "cosTheta : " << cosTheta << llendl; // llinfos << "theta : " << theta << llendl; // llinfos << "bRot : " << bRot << llendl; // llinfos << "theta abbcAng theta-abbcAng: " << theta*180.0/F_PI << " " << abbcAng*180.0f/F_PI << " " << (theta - abbcAng)*180.0f/F_PI << llendl; //------------------------------------------------------------------------- // compute rotation that rotates new A->C to A->G //------------------------------------------------------------------------- // rotate B->C by bRot bcVec = bcVec * bRot; // update A->C acVec = abVec + bcVec; LLQuaternion cgRot; cgRot.shortestArc( acVec, agVec ); // llinfos << "bcVec : " << bcVec << llendl; // llinfos << "acVec : " << acVec << llendl; // llinfos << "cgRot : " << cgRot << llendl; // update A->B and B->C with rotation from C to G abVec = abVec * cgRot; bcVec = bcVec * cgRot; abcNorm = abcNorm * cgRot; acVec = abVec + bcVec; //------------------------------------------------------------------------- // compute the normal of the APG plane //------------------------------------------------------------------------- if (are_parallel(agVec, poleVec, 0.001f)) { // the solution plane is undefined ==> we're done return; } LLVector3 apgNorm = poleVec % agVec; apgNorm.normVec(); if (!mbUseBAxis) { //--------------------------------------------------------------------- // compute the normal of the new ABC plane // (only necessary if we're NOT using mBAxis) //--------------------------------------------------------------------- if( are_parallel(abVec, bcVec, 0.001f) ) { // G is either too close or too far away // we'll use the old ABCnormal } else { abcNorm = abVec % bcVec; } abcNorm.normVec(); } //------------------------------------------------------------------------- // calcuate plane rotation //------------------------------------------------------------------------- LLQuaternion pRot; if ( are_parallel( abcNorm, apgNorm, 0.001f) ) { if (abcNorm * apgNorm < 0.0f) { // we must be PI radians off ==> rotate by PI around agVec pRot.setQuat(F_PI, agVec); } else { // we're done } } else { pRot.shortestArc( abcNorm, apgNorm ); } // llinfos << "abcNorm = " << abcNorm << llendl; // llinfos << "apgNorm = " << apgNorm << llendl; // llinfos << "pRot = " << pRot << llendl; //------------------------------------------------------------------------- // compute twist rotation //------------------------------------------------------------------------- LLQuaternion twistRot( mTwist, agVec ); // llinfos << "twist : " << mTwist*180.0/F_PI << llendl; // llinfos << "agNormVec: " << agNormVec << llendl; // llinfos << "twistRot : " << twistRot << llendl; //------------------------------------------------------------------------- // compute rotation of A //------------------------------------------------------------------------- LLQuaternion aRot = cgRot * pRot * twistRot; //------------------------------------------------------------------------- // apply the rotations //------------------------------------------------------------------------- mJointB->setWorldRotation( mJointB->getWorldRotation() * bRot ); mJointA->setWorldRotation( mJointA->getWorldRotation() * aRot ); }
BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) { LLVector3 ray_start_region; LLVector3 ray_end_region; LLViewerRegion* regionp = NULL; BOOL b_hit_land = FALSE; S32 hit_face = -1; LLViewerObject* hit_obj = NULL; U8 state = 0; BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp ); if( !success ) { return FALSE; } if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) ) { // Can't create objects on avatars or attachments return FALSE; } if (NULL == regionp) { llwarns << "regionp was NULL; aborting function." << llendl; return FALSE; } if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX) { LLFirstUse::useSandbox(); } // Set params for new object based on its PCode. LLQuaternion rotation; LLVector3 scale = LLVector3( gSavedSettings.getF32("EmeraldBuildPrefs_Xsize"), gSavedSettings.getF32("EmeraldBuildPrefs_Ysize"), gSavedSettings.getF32("EmeraldBuildPrefs_Zsize")); U8 material = LL_MCODE_WOOD; if(gSavedSettings.getString("EmeraldBuildPrefs_Material")== "Stone") material = LL_MCODE_STONE; if(gSavedSettings.getString("EmeraldBuildPrefs_Material")== "Metal") material = LL_MCODE_METAL; if(gSavedSettings.getString("EmeraldBuildPrefs_Material")== "Wood") material = LL_MCODE_WOOD; if(gSavedSettings.getString("EmeraldBuildPrefs_Material")== "Flesh") material = LL_MCODE_FLESH; if(gSavedSettings.getString("EmeraldBuildPrefs_Material")== "Rubber") material = LL_MCODE_RUBBER; if(gSavedSettings.getString("EmeraldBuildPrefs_Material")== "Plastic") material = LL_MCODE_PLASTIC; BOOL create_selected = FALSE; LLVolumeParams volume_params; switch (pcode) { case LL_PCODE_LEGACY_GRASS: // Randomize size of grass patch scale.setVec(10.f + ll_frand(20.f), 10.f + ll_frand(20.f), 1.f + ll_frand(2.f)); state = rand() % LLVOGrass::sMaxGrassSpecies; break; case LL_PCODE_LEGACY_TREE: case LL_PCODE_TREE_NEW: state = rand() % LLVOTree::sMaxTreeSpecies; break; case LL_PCODE_SPHERE: case LL_PCODE_CONE: case LL_PCODE_CUBE: case LL_PCODE_CYLINDER: case LL_PCODE_TORUS: case LLViewerObject::LL_VO_SQUARE_TORUS: case LLViewerObject::LL_VO_TRIANGLE_TORUS: default: create_selected = TRUE; break; } // Play creation sound if (gAudiop) { gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); } gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); //MOYMOD 2009-05, If avatar is in land group/land owner group, // it rezzes it with it to prevent autoreturn/whatever if(gSavedSettings.getBOOL("mm_alwaysRezWithLandGroup")){ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if(gAgent.isInGroup(parcel->getGroupID())){ gMessageSystem->addUUIDFast(_PREHASH_GroupID, parcel->getGroupID()); }else if(gAgent.isInGroup(parcel->getOwnerID())){ gMessageSystem->addUUIDFast(_PREHASH_GroupID, parcel->getOwnerID()); }else gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); }else gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU8Fast(_PREHASH_Material, material); U32 flags = 0; // not selected if (use_physics || gSavedSettings.getBOOL("EmeraldBuildPrefs_Physical")) { flags |= FLAGS_USE_PHYSICS; } //if (create_selected) // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | Added: RLVa-1.0.0b if ( (create_selected) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) ) // [/RLVa:KB] { flags |= FLAGS_CREATE_SELECTED; } gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags ); LLPCode volume_pcode; // ...PCODE_VOLUME, or the original on error switch (pcode) { case LL_PCODE_SPHERE: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_TORUS: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1.f, 0.25f ); // "top size" volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LLViewerObject::LL_VO_SQUARE_TORUS: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1.f, 0.25f ); // "top size" volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LLViewerObject::LL_VO_TRIANGLE_TORUS: rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_CIRCLE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1.f, 0.25f ); // "top size" volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_SPHERE_HEMI: volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); //volume_params.setBeginAndEndS( 0.5f, 1.f ); volume_params.setBeginAndEndT( 0.f, 0.5f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CUBE: volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_PRISM: volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 1 ); volume_params.setShear ( -0.5f, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_PYRAMID: volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_TETRAHEDRON: volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CYLINDER: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CYLINDER_HEMI: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.25f, 0.75f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 1, 1 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CONE: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.f, 1.f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; case LL_PCODE_CONE_HEMI: volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); volume_params.setBeginAndEndS( 0.25f, 0.75f ); volume_params.setBeginAndEndT( 0.f, 1.f ); volume_params.setRatio ( 0, 0 ); volume_params.setShear ( 0, 0 ); LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); volume_pcode = LL_PCODE_VOLUME; break; default: LLVolumeMessage::packVolumeParams(0, gMessageSystem); volume_pcode = pcode; break; } gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode); gMessageSystem->addVector3Fast(_PREHASH_Scale, scale ); gMessageSystem->addQuatFast(_PREHASH_Rotation, rotation ); gMessageSystem->addVector3Fast(_PREHASH_RayStart, ray_start_region ); gMessageSystem->addVector3Fast(_PREHASH_RayEnd, ray_end_region ); gMessageSystem->addU8Fast(_PREHASH_BypassRaycast, (U8)b_hit_land ); gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE ); gMessageSystem->addU8Fast(_PREHASH_State, state); // Limit raycast to a single object. // Speeds up server raycast + avoid problems with server ray hitting objects // that were clipped by the near plane or culled on the viewer. LLUUID ray_target_id; if( hit_obj ) { ray_target_id = hit_obj->getID(); } else { ray_target_id.setNull(); } gMessageSystem->addUUIDFast(_PREHASH_RayTargetID, ray_target_id ); // Pack in name value pairs gMessageSystem->sendReliable(regionp->getHost()); //lgg set flag to set texture here gImportTracker.expectRez(); // Spawns a message, so must be after above send if (create_selected) { LLSelectMgr::getInstance()->deselectAll(); gViewerWindow->getWindow()->incBusyCount(); } // VEFFECT: AddObject LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); effectp->setSourceObject((LLViewerObject*)gAgent.getAvatarObject()); effectp->setPositionGlobal(regionp->getPosGlobalFromRegion(ray_end_region)); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT); return TRUE; }
void LLTemplateMessageBuilder::addQuat(const char *varname, const LLQuaternion& quat) { addData(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3)); }
BOOL LLEasyMessageSender::addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex) { LLStringUtil::trim(input); if(input.length() < 1 && var_type != MVT_VARIABLE) return FALSE; U8 valueU8; U16 valueU16; U32 valueU32; U64 valueU64; S8 valueS8; S16 valueS16; S32 valueS32; // S64 valueS64; F32 valueF32; F64 valueF64; LLVector3 valueVector3; LLVector3d valueVector3d; LLVector4 valueVector4; LLQuaternion valueQuaternion; LLUUID valueLLUUID; BOOL valueBOOL; std::string input_lower = input; LLStringUtil::toLower(input_lower); if(input_lower == "$agentid") input = gAgent.getID().asString(); else if(input_lower == "$sessionid") input = gAgent.getSessionID().asString(); else if(input_lower == "$uuid") { LLUUID id; id.generate(); input = id.asString(); } else if(input_lower == "$circuitcode") { std::stringstream temp_stream; temp_stream << gMessageSystem->mOurCircuitCode; input = temp_stream.str(); } else if(input_lower == "$regionhandle") { std::stringstream temp_stream; temp_stream << (gAgent.getRegion() ? gAgent.getRegion()->getHandle() : 0); input = temp_stream.str(); } else if(input_lower == "$position" || input_lower == "$pos") { std::stringstream temp_stream; valueVector3 = gAgent.getPositionAgent(); temp_stream << "<" << valueVector3[0] << ", " << valueVector3[1] << ", " << valueVector3[2] << ">"; input = temp_stream.str(); } //convert from a text representation of hex to binary if(hex) { if(var_type != MVT_VARIABLE && var_type != MVT_FIXED) return FALSE; int len = input_lower.length(); const char* cstr = input_lower.c_str(); std::string new_input(""); BOOL nibble = FALSE; char byte = 0; for(int i = 0; i < len; i++) { char c = cstr[i]; if(c >= 0x30 && c <= 0x39) c -= 0x30; else if(c >= 0x61 && c <= 0x66) c -= 0x57; else if(c != 0x20) return FALSE; else continue; if(!nibble) byte = c << 4; else new_input.push_back(byte | c); nibble = !nibble; } if(nibble) return FALSE; input = new_input; } std::stringstream stream(input); std::vector<std::string> tokens; switch(var_type) { case MVT_U8: if(input.substr(0, 1) == "-") return FALSE; if((stream >> valueU32).fail()) return FALSE; valueU8 = (U8)valueU32; gMessageSystem->addU8(var_name, valueU8); return TRUE; break; case MVT_U16: if(input.substr(0, 1) == "-") return FALSE; if((stream >> valueU16).fail()) return FALSE; gMessageSystem->addU16(var_name, valueU16); return TRUE; break; case MVT_U32: if(input.substr(0, 1) == "-") return FALSE; if((stream >> valueU32).fail()) return FALSE; gMessageSystem->addU32(var_name, valueU32); return TRUE; break; case MVT_U64: if(input.substr(0, 1) == "-") return FALSE; if((stream >> valueU64).fail()) return FALSE; gMessageSystem->addU64(var_name, valueU64); return TRUE; break; case MVT_S8: if((stream >> valueS8).fail()) return FALSE; gMessageSystem->addS8(var_name, valueS8); return TRUE; break; case MVT_S16: if((stream >> valueS16).fail()) return FALSE; gMessageSystem->addS16(var_name, valueS16); return TRUE; break; case MVT_S32: if((stream >> valueS32).fail()) return FALSE; gMessageSystem->addS32(var_name, valueS32); return TRUE; break; /* case MVT_S64: if((stream >> valueS64).fail()) return FALSE; gMessageSystem->addS64(var_name, valueS64); return TRUE; break; */ case MVT_F32: if((stream >> valueF32).fail()) return FALSE; gMessageSystem->addF32(var_name, valueF32); return TRUE; break; case MVT_F64: if((stream >> valueF64).fail()) return FALSE; gMessageSystem->addF64(var_name, valueF64); return TRUE; break; case MVT_LLVector3: LLStringUtil::trim(input); if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") return FALSE; tokens = split(input.substr(1, input.length() - 2), ","); if(tokens.size() != 3) return FALSE; for(int i = 0; i < 3; i++) { stream.clear(); stream.str(tokens[i]); if((stream >> valueF32).fail()) return FALSE; valueVector3.mV[i] = valueF32; } gMessageSystem->addVector3(var_name, valueVector3); return TRUE; break; case MVT_LLVector3d: LLStringUtil::trim(input); if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") return FALSE; tokens = split(input.substr(1, input.length() - 2), ","); if(tokens.size() != 3) return FALSE; for(int i = 0; i < 3; i++) { stream.clear(); stream.str(tokens[i]); if((stream >> valueF64).fail()) return FALSE; valueVector3d.mdV[i] = valueF64; } gMessageSystem->addVector3d(var_name, valueVector3d); return TRUE; break; case MVT_LLVector4: LLStringUtil::trim(input); if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") return FALSE; tokens = split(input.substr(1, input.length() - 2), ","); if(tokens.size() != 4) return FALSE; for(int i = 0; i < 4; i++) { stream.clear(); stream.str(tokens[i]); if((stream >> valueF32).fail()) return FALSE; valueVector4.mV[i] = valueF32; } gMessageSystem->addVector4(var_name, valueVector4); return TRUE; break; case MVT_LLQuaternion: LLStringUtil::trim(input); if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") return FALSE; tokens = split(input.substr(1, input.length() - 2), ","); if(tokens.size() == 3) { for(int i = 0; i < 3; i++) { stream.clear(); stream.str(tokens[i]); if((stream >> valueF32).fail()) return FALSE; valueVector3.mV[i] = valueF32; } valueQuaternion.unpackFromVector3(valueVector3); } else if(tokens.size() == 4) { for(int i = 0; i < 4; i++) { stream.clear(); stream.str(tokens[i]); if((stream >> valueF32).fail()) return FALSE; valueQuaternion.mQ[i] = valueF32; } } else return FALSE;