* added some functions for use in raytracing. They're kind of crappy now, so they only display 'guesses' on the console when you rez a prim.
* any math gurus who'd like to improve rezzing need only to make the raytracer in SceneObjectPart work :Dafrisby
parent
4af84b0bb2
commit
1ecd803e87
|
@ -145,6 +145,31 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
return (EntityBase) MemberwiseClone();
|
return (EntityBase) MemberwiseClone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract void SetText(string text, Vector3 color, double alpha);
|
public abstract void SetText(string text, Vector3 color, double alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Nested Classes
|
||||||
|
public class EntityIntersection
|
||||||
|
{
|
||||||
|
public Vector3 ipoint = new Vector3(0, 0, 0);
|
||||||
|
public float normal = 0;
|
||||||
|
public bool HitTF = false;
|
||||||
|
public SceneObjectPart obj;
|
||||||
|
public float distance = 0;
|
||||||
|
|
||||||
|
public EntityIntersection()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public EntityIntersection(Vector3 _ipoint, float _normal, bool _HitTF)
|
||||||
|
{
|
||||||
|
ipoint = _ipoint;
|
||||||
|
normal = _normal;
|
||||||
|
HitTF = _HitTF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -253,6 +253,33 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityIntersection GetClosestIntersectingPrim(Ray hray)
|
||||||
|
{
|
||||||
|
// Primitive Ray Tracing
|
||||||
|
bool gothit = false;
|
||||||
|
float closestDistance = 280f;
|
||||||
|
EntityIntersection returnResult = new EntityIntersection();
|
||||||
|
foreach (EntityBase ent in Entities.Values)
|
||||||
|
{
|
||||||
|
if (ent is SceneObjectGroup)
|
||||||
|
{
|
||||||
|
SceneObjectGroup reportingG = (SceneObjectGroup)ent;
|
||||||
|
EntityIntersection result = reportingG.testIntersection(hray);
|
||||||
|
if (result.HitTF)
|
||||||
|
{
|
||||||
|
if (result.distance < closestDistance)
|
||||||
|
{
|
||||||
|
gothit = true;
|
||||||
|
closestDistance = result.distance;
|
||||||
|
returnResult = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return returnResult;
|
||||||
|
}
|
||||||
|
|
||||||
public SceneObjectPart GetSceneObjectPart(uint localID)
|
public SceneObjectPart GetSceneObjectPart(uint localID)
|
||||||
{
|
{
|
||||||
SceneObjectGroup group = GetGroupByPrim(localID);
|
SceneObjectGroup group = GetGroupByPrim(localID);
|
||||||
|
|
|
@ -635,8 +635,52 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <param name="ownerID"></param>
|
/// <param name="ownerID"></param>
|
||||||
public void AddNewPrim(LLUUID ownerID, LLVector3 pos, LLQuaternion rot, PrimitiveBaseShape shape)
|
public void AddNewPrim(LLUUID ownerID, LLVector3 pos, LLQuaternion rot, PrimitiveBaseShape shape)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// What we're *supposed* to do is raytrace from the camera position given by the client to the nearest collision
|
||||||
|
// in the direction the client supplies (the ground level that we clicked)
|
||||||
|
// This function is pretty crappy right now.. so we're not affecting where the newly rezzed objects go
|
||||||
|
// Test it if you like. The console will write where it guesses a collision took place. if it thinks one did.
|
||||||
|
// It's wrong many times though.
|
||||||
|
|
||||||
if (PermissionsMngr.CanRezObject(ownerID, pos))
|
if (PermissionsMngr.CanRezObject(ownerID, pos))
|
||||||
{
|
{
|
||||||
|
Vector3 CameraPosition = ((ScenePresence)GetScenePresence(ownerID)).CameraPosition;
|
||||||
|
Vector3 rayEnd = new Vector3(pos.X, pos.Y, pos.Z);
|
||||||
|
|
||||||
|
float raydistance = m_innerScene.Vector3Distance(CameraPosition, rayEnd);
|
||||||
|
|
||||||
|
Vector3 rayDirection = new Vector3(rayEnd.x / raydistance, rayEnd.y / raydistance, rayEnd.z / raydistance);
|
||||||
|
|
||||||
|
Ray rezRay = new Ray(CameraPosition, rayDirection);
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 RezDirectionFromCamera = rezRay.Direction;
|
||||||
|
|
||||||
|
EntityIntersection rayTracing = m_innerScene.GetClosestIntersectingPrim(rezRay);
|
||||||
|
|
||||||
|
if (rayTracing.HitTF)
|
||||||
|
{
|
||||||
|
// We raytraced and found a prim in the way of the ground.. so
|
||||||
|
// We will rez the object somewhere close to the prim. Better math needed. This is a Stub
|
||||||
|
//Vector3 Newpos = new Vector3(rayTracing.obj.AbsolutePosition.X,rayTracing.obj.AbsolutePosition.Y,rayTracing.obj.AbsolutePosition.Z);
|
||||||
|
Vector3 Newpos = rayTracing.ipoint;
|
||||||
|
Vector3 NewScale = new Vector3(rayTracing.obj.Scale.X,rayTracing.obj.Scale.Y,rayTracing.obj.Scale.Z);
|
||||||
|
|
||||||
|
Quaternion ParentRot = rayTracing.obj.ParentGroup.Rotation;
|
||||||
|
//Quaternion ParentRot = new Quaternion(primParentRot.W,primParentRot.X,primParentRot.Y,primParentRot.Z);
|
||||||
|
|
||||||
|
LLQuaternion primLocalRot = rayTracing.obj.RotationOffset;
|
||||||
|
Quaternion LocalRot = new Quaternion(primLocalRot.W,primLocalRot.X,primLocalRot.Y,primLocalRot.Z);
|
||||||
|
|
||||||
|
Quaternion NewRot = LocalRot * ParentRot;
|
||||||
|
|
||||||
|
Vector3 RezPoint = Newpos;
|
||||||
|
|
||||||
|
MainLog.Instance.Verbose("REZINFO","Possible Rez Point:" + RezPoint.ToString());
|
||||||
|
//pos = new LLVector3(RezPoint.x, RezPoint.y, RezPoint.z);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SceneObjectGroup sceneOb =
|
SceneObjectGroup sceneOb =
|
||||||
new SceneObjectGroup(this, m_regionHandle, ownerID, PrimIDAllocate(), pos, rot, shape);
|
new SceneObjectGroup(this, m_regionHandle, ownerID, PrimIDAllocate(), pos, rot, shape);
|
||||||
AddEntity(sceneOb);
|
AddEntity(sceneOb);
|
||||||
|
|
|
@ -353,6 +353,44 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityIntersection testIntersection(Ray hRay)
|
||||||
|
{
|
||||||
|
EntityIntersection returnresult = new EntityIntersection();
|
||||||
|
bool gothit = false;
|
||||||
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
SceneObjectPart returnThisPart = null;
|
||||||
|
Vector3 partPosition = new Vector3(part.AbsolutePosition.X,part.AbsolutePosition.Y,part.AbsolutePosition.Z);
|
||||||
|
Quaternion parentrotation = new Quaternion(GroupRotation.W,GroupRotation.X,GroupRotation.Y,GroupRotation.Z);
|
||||||
|
EntityIntersection inter = part.testIntersection(hRay,parentrotation);
|
||||||
|
|
||||||
|
float idist = 256f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (inter.HitTF) {
|
||||||
|
// We need to find the closest prim to return to the testcaller along the ray
|
||||||
|
if (inter.distance < idist) {
|
||||||
|
|
||||||
|
idist = inter.distance;
|
||||||
|
returnresult.HitTF = true;
|
||||||
|
returnresult.ipoint = inter.ipoint;
|
||||||
|
returnresult.obj = part;
|
||||||
|
returnresult.normal = inter.normal;
|
||||||
|
returnresult.distance = inter.distance;
|
||||||
|
gothit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return returnresult;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -535,6 +535,91 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
serializer.Serialize(xmlWriter, this);
|
serializer.Serialize(xmlWriter, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityIntersection testIntersection(Ray iray, Quaternion parentrot)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Sphere dummysphere = new Sphere();
|
||||||
|
|
||||||
|
EntityIntersection returnresult = new EntityIntersection();
|
||||||
|
Vector3 vAbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
|
||||||
|
Vector3 vScale = new Vector3(Scale.X, Scale.Y, Scale.Z);
|
||||||
|
Quaternion qRotation = new Quaternion(RotationOffset.W, RotationOffset.X, RotationOffset.Y, RotationOffset.Z);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Quaternion worldRotation = (qRotation * parentrot);
|
||||||
|
Matrix3 worldRotM = worldRotation.ToRotationMatrix();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 rOrigin = iray.Origin;
|
||||||
|
Vector3 rDirection = iray.Direction;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 r2ndDirection = rDirection * rDirection;
|
||||||
|
|
||||||
|
float itestPart1 = r2ndDirection.x + r2ndDirection.y + r2ndDirection.z;
|
||||||
|
|
||||||
|
Vector3 tmVal2 = rOrigin - vAbsolutePosition;
|
||||||
|
|
||||||
|
Vector3 r2Direction = rDirection * 2.0f;
|
||||||
|
Vector3 tmVal3 = r2Direction * tmVal2;
|
||||||
|
|
||||||
|
float itestPart2 = tmVal3.x + tmVal3.y + tmVal3.z;
|
||||||
|
|
||||||
|
Vector3 tmVal4 = rOrigin * rOrigin;
|
||||||
|
Vector3 tmVal5 = vAbsolutePosition * vAbsolutePosition;
|
||||||
|
|
||||||
|
Vector3 tmVal6 = vAbsolutePosition * rOrigin;
|
||||||
|
|
||||||
|
float radius = 0f;
|
||||||
|
if (vScale.x > radius)
|
||||||
|
radius = vScale.x;
|
||||||
|
if (vScale.y > radius)
|
||||||
|
radius = vScale.y;
|
||||||
|
if (vScale.z > radius)
|
||||||
|
radius = vScale.z;
|
||||||
|
|
||||||
|
//radius = radius;
|
||||||
|
|
||||||
|
float itestPart3 = tmVal4.x + tmVal4.y + tmVal4.z + tmVal5.x + tmVal5.y + tmVal5.z -(2.0f * (tmVal6.x + tmVal6.y + tmVal6.z + (radius * radius)));
|
||||||
|
|
||||||
|
// Yuk Quadradrics
|
||||||
|
float rootsqr = (itestPart2 * itestPart2) - (4.0f * itestPart1 * itestPart3);
|
||||||
|
if (rootsqr < 0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
return returnresult;
|
||||||
|
}
|
||||||
|
float root = ((-itestPart2) - (float)Math.Sqrt((double)rootsqr)) / (itestPart1 * 2.0f);
|
||||||
|
|
||||||
|
if (root < 0.0f)
|
||||||
|
{
|
||||||
|
// perform second quadratic root solution
|
||||||
|
root = ((-itestPart2) + (float)Math.Sqrt((double)rootsqr)) / (itestPart1 * 2.0f);
|
||||||
|
|
||||||
|
// is there any intersection?
|
||||||
|
if (root < 0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
return returnresult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 ipoint = new Vector3(iray.Origin.x + (iray.Direction.x * root),iray.Origin.y + (iray.Direction.y * root),iray.Origin.z + (iray.Direction.z * root));
|
||||||
|
|
||||||
|
returnresult.HitTF = true;
|
||||||
|
returnresult.ipoint = ipoint;
|
||||||
|
Vector3 normalpart = ipoint-vAbsolutePosition;
|
||||||
|
returnresult.normal = normalpart.Normalize();
|
||||||
|
returnresult.distance = ParentGroup.m_scene.m_innerScene.Vector3Distance(iray.Origin, ipoint);
|
||||||
|
|
||||||
|
return returnresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -147,6 +147,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
get { return m_regionHandle; }
|
get { return m_regionHandle; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3 CameraPosition
|
||||||
|
{
|
||||||
|
get { return m_CameraCenter; }
|
||||||
|
}
|
||||||
|
|
||||||
private readonly string m_firstname;
|
private readonly string m_firstname;
|
||||||
|
|
||||||
public string Firstname
|
public string Firstname
|
||||||
|
|
Loading…
Reference in New Issue