F32 LLWorld::resolveLandHeightGlobal(const LLVector3d &pos_global) { LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); if (regionp) { return regionp->getLand().resolveHeightGlobal(pos_global); } return 0.0f; }
LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global) { LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); if (!regionp) { return LLVector3::z_axis; } return regionp->getLand().resolveNormalGlobal(pos_global); }
LLSurfacePatch * LLWorld::resolveLandPatchGlobal(const LLVector3d &pos_global) { // returns a pointer to the patch at this location LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); if (!regionp) { return NULL; } return regionp->getLand().resolvePatchGlobal(pos_global); }
LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global) { LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); if (regionp) { pos_region = regionp->getPosRegionFromGlobal(pos_global); return regionp; } return NULL; }
LLViewerRegion* LLWorld::resolveRegionAgent(LLVector3 &pos_region, const LLVector3 &pos_agent) { LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global); if (regionp) { pos_region = regionp->getPosRegionFromGlobal(pos_global); return regionp; } return NULL; }
// Takes a line defined by "point_a" and "point_b" and determines the closest (to point_a) // point where the the line intersects an object or the land surface. Stores the results // in "intersection" and "intersection_normal" and returns a scalar value that represents // the normalized distance along the line from "point_a" to "intersection". // // Currently assumes point_a and point_b only differ in z-direction, // but it may eventually become more general. F32 LLWorld::resolveStepHeightGlobal(const LLVOAvatar* avatarp, const LLVector3d &point_a, const LLVector3d &point_b, LLVector3d &intersection, LLVector3 &intersection_normal, LLViewerObject **viewerObjectPtr) { // initialize return value to null if (viewerObjectPtr) { *viewerObjectPtr = NULL; } LLViewerRegion *regionp = getRegionFromPosGlobal(point_a); if (!regionp) { // We're outside the world intersection = 0.5f * (point_a + point_b); intersection_normal.setVec(0.0f, 0.0f, 1.0f); return 0.5f; } // calculate the length of the segment F32 segment_length = (F32)((point_a - point_b).length()); if (0.0f == segment_length) { intersection = point_a; intersection_normal.setVec(0.0f, 0.0f, 1.0f); return segment_length; } // get land height // Note: we assume that the line is parallel to z-axis here LLVector3d land_intersection = point_a; F32 normalized_land_distance; land_intersection.mdV[VZ] = regionp->getLand().resolveHeightGlobal(point_a); normalized_land_distance = (F32)(point_a.mdV[VZ] - land_intersection.mdV[VZ]) / segment_length; intersection = land_intersection; intersection_normal = resolveLandNormalGlobal(land_intersection); if (avatarp && !avatarp->mFootPlane.isExactlyClear()) { LLVector3 foot_plane_normal(avatarp->mFootPlane.mV); LLVector3 start_pt = avatarp->getRegion()->getPosRegionFromGlobal(point_a); // added 0.05 meters to compensate for error in foot plane reported by Havok F32 norm_dist_from_plane = ((start_pt * foot_plane_normal) - avatarp->mFootPlane.mV[VW]) + 0.05f; norm_dist_from_plane = llclamp(norm_dist_from_plane / segment_length, 0.f, 1.f); if (norm_dist_from_plane < normalized_land_distance) { // collided with object before land normalized_land_distance = norm_dist_from_plane; intersection = point_a; intersection.mdV[VZ] -= norm_dist_from_plane * segment_length; intersection_normal = foot_plane_normal; } else { intersection = land_intersection; intersection_normal = resolveLandNormalGlobal(land_intersection); } } return normalized_land_distance; }
LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos) { if (positionRegionValidGlobal(end_pos)) { return end_pos; } LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos); if (!regionp) { return start_pos; } LLVector3d delta_pos = end_pos - start_pos; LLVector3d delta_pos_abs; delta_pos_abs.setVec(delta_pos); delta_pos_abs.abs(); LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos); F64 clip_factor = 1.0; F32 region_width = regionp->getWidth(); if (region_coord.mV[VX] < 0.f) { if (region_coord.mV[VY] < region_coord.mV[VX]) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else { // clip along x - clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]); } } else if (region_coord.mV[VX] > region_width) { if (region_coord.mV[VY] > region_coord.mV[VX]) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } else { //clip along x + clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX]; } } else if (region_coord.mV[VY] < 0.f) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else if (region_coord.mV[VY] > region_width) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } // clamp to within region dimensions LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor); final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0, (F64)(region_width - F_ALMOST_ZERO)); final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0, (F64)(region_width - F_ALMOST_ZERO)); final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0, (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO)); return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos)); }
LLViewerRegion* LLWorld::getRegionFromPosAgent(const LLVector3 &pos) { return getRegionFromPosGlobal(gAgent.getPosGlobalFromAgent(pos)); }
LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos) { if (positionRegionValidGlobal(end_pos)) { return end_pos; } LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos); if (!regionp) { return start_pos; } LLVector3d delta_pos = end_pos - start_pos; LLVector3d delta_pos_abs; delta_pos_abs.setVec(delta_pos); delta_pos_abs.abs(); LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos); F64 clip_factor = 1.0; F32 region_width = regionp->getWidth(); if (region_coord.mV[VX] < 0.f) { if (region_coord.mV[VY] < region_coord.mV[VX]) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else { // clip along x - clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]); } } else if (region_coord.mV[VX] > region_width) { if (region_coord.mV[VY] > region_coord.mV[VX]) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } else { //clip along x + clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX]; } } else if (region_coord.mV[VY] < 0.f) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else if (region_coord.mV[VY] > region_width) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } // clamp to < 256 to stay in sim LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor); final_region_pos.clamp(0.0, 255.999); return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos)); }
LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos) { if (positionRegionValidGlobal(end_pos)) { return end_pos; } LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos); if (!regionp) { return start_pos; } LLVector3d delta_pos = end_pos - start_pos; LLVector3d delta_pos_abs; delta_pos_abs.setVec(delta_pos); delta_pos_abs.abs(); LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos); F64 clip_factor = 1.0; F32 region_width = regionp->getWidth(); if (region_coord.mV[VX] < 0.f) { if (region_coord.mV[VY] < region_coord.mV[VX]) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else { // clip along x - clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]); } } else if (region_coord.mV[VX] > region_width) { if (region_coord.mV[VY] > region_coord.mV[VX]) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } else { //clip along x + clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX]; } } else if (region_coord.mV[VY] < 0.f) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else if (region_coord.mV[VY] > region_width) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } // clamp to < 256 to stay in sim LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor); // clamp x, y to [0,256[ and z to [0,REGION_HEIGHT_METERS] (the clamp function cannot be used here) if (final_region_pos.mdV[VX] < 0) final_region_pos.mdV[VX] = 0.0; if (final_region_pos.mdV[VY] < 0) final_region_pos.mdV[VY] = 0.0; if (final_region_pos.mdV[VZ] < 0) final_region_pos.mdV[VZ] = 0.0; if (final_region_pos.mdV[VX] > 255.999) final_region_pos.mdV[VX] = 255.999; if (final_region_pos.mdV[VY] > 255.999) final_region_pos.mdV[VY] = 255.999; if (final_region_pos.mdV[VZ] > REGION_HEIGHT_METERS) final_region_pos.mdV[VZ] = REGION_HEIGHT_METERS; //final_region_pos.clamp(0.0, 255.999); return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos)); }