public Vector3 CalculateRezLocation( RezObjectParams rezparams, Vector3 scale) { Vector3 pos = rezparams.RayEnd + new Vector3(0, 0, scale.Z / 2f); if (rezparams.RayEndIsIntersection) { return(rezparams.RayEnd); } Vector3 projectedWaterLocation = Vector3.Zero; double waterHeight = RegionSettings.WaterHeight; if (rezparams.RayStart.Z > waterHeight && rezparams.RayEnd.Z < waterHeight) { Vector3 dir = rezparams.RayEnd - rezparams.RayStart; double ratio = (waterHeight - rezparams.RayStart.Z) / dir.Z; projectedWaterLocation = rezparams.RayStart; projectedWaterLocation.X += ratio * dir.X; projectedWaterLocation.Y += ratio * dir.Y; projectedWaterLocation.Z = waterHeight; } else { projectedWaterLocation.Z = waterHeight; } ObjectPart target; if (Primitives.TryGetValue(rezparams.RayTargetID, out target)) { pos = target.GlobalPosition; } RayResult[] results = PhysicsScene.RayTest(rezparams.RayStart, pos); if (rezparams.RayTargetID != UUID.Zero) { foreach (RayResult ray in results) { if (ray.PartId == rezparams.RayTargetID) { return(CalculateTargetedRezLocation(ray, scale, projectedWaterLocation)); } } } else { foreach (RayResult ray in results) { if (ray.IsTerrain) { return(CalculateTargetedRezLocation(ray, scale, projectedWaterLocation)); } } } if (results.Length > 0) { return(CalculateTargetedRezLocation(results[0], scale, projectedWaterLocation)); } else { pos = rezparams.RayEnd; LocationInfo info = GetLocationInfoProvider().At(pos); pos.Z = info.GroundHeight; if (pos.Z < info.WaterHeight && rezparams.RayStart.Z >= info.WaterHeight) { pos.Z = info.WaterHeight; } pos.Z += scale.Z * 0.5; } return(pos); }