diff options
author | Teravus Ovares | 2007-11-23 05:56:35 +0000 |
---|---|---|
committer | Teravus Ovares | 2007-11-23 05:56:35 +0000 |
commit | 1ecd803e87119c0344b91798792130155a82859c (patch) | |
tree | 74cbd2102051d03acfa78f5763438fd0b0a19778 /OpenSim/Region/Environment | |
parent | Fixed Terrain rescale command (diff) | |
download | opensim-SC-1ecd803e87119c0344b91798792130155a82859c.zip opensim-SC-1ecd803e87119c0344b91798792130155a82859c.tar.gz opensim-SC-1ecd803e87119c0344b91798792130155a82859c.tar.bz2 opensim-SC-1ecd803e87119c0344b91798792130155a82859c.tar.xz |
* 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 :D
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/EntityBase.cs | 25 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/InnerScene.cs | 27 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.cs | 44 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | 38 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | 85 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/ScenePresence.cs | 5 |
6 files changed, 224 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/EntityBase.cs b/OpenSim/Region/Environment/Scenes/EntityBase.cs index 1c21159..94e2337 100644 --- a/OpenSim/Region/Environment/Scenes/EntityBase.cs +++ b/OpenSim/Region/Environment/Scenes/EntityBase.cs | |||
@@ -145,6 +145,31 @@ namespace OpenSim.Region.Environment.Scenes | |||
145 | return (EntityBase) MemberwiseClone(); | 145 | return (EntityBase) MemberwiseClone(); |
146 | } | 146 | } |
147 | 147 | ||
148 | |||
149 | |||
148 | public abstract void SetText(string text, Vector3 color, double alpha); | 150 | public abstract void SetText(string text, Vector3 color, double alpha); |
149 | } | 151 | } |
152 | |||
153 | //Nested Classes | ||
154 | public class EntityIntersection | ||
155 | { | ||
156 | public Vector3 ipoint = new Vector3(0, 0, 0); | ||
157 | public float normal = 0; | ||
158 | public bool HitTF = false; | ||
159 | public SceneObjectPart obj; | ||
160 | public float distance = 0; | ||
161 | |||
162 | public EntityIntersection() | ||
163 | { | ||
164 | |||
165 | |||
166 | } | ||
167 | public EntityIntersection(Vector3 _ipoint, float _normal, bool _HitTF) | ||
168 | { | ||
169 | ipoint = _ipoint; | ||
170 | normal = _normal; | ||
171 | HitTF = _HitTF; | ||
172 | } | ||
173 | |||
174 | } | ||
150 | } \ No newline at end of file | 175 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 38a8a06..8f7cbee 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs | |||
@@ -253,6 +253,33 @@ namespace OpenSim.Region.Environment.Scenes | |||
253 | return null; | 253 | return null; |
254 | } | 254 | } |
255 | 255 | ||
256 | public EntityIntersection GetClosestIntersectingPrim(Ray hray) | ||
257 | { | ||
258 | // Primitive Ray Tracing | ||
259 | bool gothit = false; | ||
260 | float closestDistance = 280f; | ||
261 | EntityIntersection returnResult = new EntityIntersection(); | ||
262 | foreach (EntityBase ent in Entities.Values) | ||
263 | { | ||
264 | if (ent is SceneObjectGroup) | ||
265 | { | ||
266 | SceneObjectGroup reportingG = (SceneObjectGroup)ent; | ||
267 | EntityIntersection result = reportingG.testIntersection(hray); | ||
268 | if (result.HitTF) | ||
269 | { | ||
270 | if (result.distance < closestDistance) | ||
271 | { | ||
272 | gothit = true; | ||
273 | closestDistance = result.distance; | ||
274 | returnResult = result; | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | } | ||
280 | return returnResult; | ||
281 | } | ||
282 | |||
256 | public SceneObjectPart GetSceneObjectPart(uint localID) | 283 | public SceneObjectPart GetSceneObjectPart(uint localID) |
257 | { | 284 | { |
258 | SceneObjectGroup group = GetGroupByPrim(localID); | 285 | SceneObjectGroup group = GetGroupByPrim(localID); |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 90306f2..ef96e3d 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -635,8 +635,52 @@ namespace OpenSim.Region.Environment.Scenes | |||
635 | /// <param name="ownerID"></param> | 635 | /// <param name="ownerID"></param> |
636 | public void AddNewPrim(LLUUID ownerID, LLVector3 pos, LLQuaternion rot, PrimitiveBaseShape shape) | 636 | public void AddNewPrim(LLUUID ownerID, LLVector3 pos, LLQuaternion rot, PrimitiveBaseShape shape) |
637 | { | 637 | { |
638 | |||
639 | // What we're *supposed* to do is raytrace from the camera position given by the client to the nearest collision | ||
640 | // in the direction the client supplies (the ground level that we clicked) | ||
641 | // This function is pretty crappy right now.. so we're not affecting where the newly rezzed objects go | ||
642 | // Test it if you like. The console will write where it guesses a collision took place. if it thinks one did. | ||
643 | // It's wrong many times though. | ||
644 | |||
638 | if (PermissionsMngr.CanRezObject(ownerID, pos)) | 645 | if (PermissionsMngr.CanRezObject(ownerID, pos)) |
639 | { | 646 | { |
647 | Vector3 CameraPosition = ((ScenePresence)GetScenePresence(ownerID)).CameraPosition; | ||
648 | Vector3 rayEnd = new Vector3(pos.X, pos.Y, pos.Z); | ||
649 | |||
650 | float raydistance = m_innerScene.Vector3Distance(CameraPosition, rayEnd); | ||
651 | |||
652 | Vector3 rayDirection = new Vector3(rayEnd.x / raydistance, rayEnd.y / raydistance, rayEnd.z / raydistance); | ||
653 | |||
654 | Ray rezRay = new Ray(CameraPosition, rayDirection); | ||
655 | |||
656 | |||
657 | Vector3 RezDirectionFromCamera = rezRay.Direction; | ||
658 | |||
659 | EntityIntersection rayTracing = m_innerScene.GetClosestIntersectingPrim(rezRay); | ||
660 | |||
661 | if (rayTracing.HitTF) | ||
662 | { | ||
663 | // We raytraced and found a prim in the way of the ground.. so | ||
664 | // We will rez the object somewhere close to the prim. Better math needed. This is a Stub | ||
665 | //Vector3 Newpos = new Vector3(rayTracing.obj.AbsolutePosition.X,rayTracing.obj.AbsolutePosition.Y,rayTracing.obj.AbsolutePosition.Z); | ||
666 | Vector3 Newpos = rayTracing.ipoint; | ||
667 | Vector3 NewScale = new Vector3(rayTracing.obj.Scale.X,rayTracing.obj.Scale.Y,rayTracing.obj.Scale.Z); | ||
668 | |||
669 | Quaternion ParentRot = rayTracing.obj.ParentGroup.Rotation; | ||
670 | //Quaternion ParentRot = new Quaternion(primParentRot.W,primParentRot.X,primParentRot.Y,primParentRot.Z); | ||
671 | |||
672 | LLQuaternion primLocalRot = rayTracing.obj.RotationOffset; | ||
673 | Quaternion LocalRot = new Quaternion(primLocalRot.W,primLocalRot.X,primLocalRot.Y,primLocalRot.Z); | ||
674 | |||
675 | Quaternion NewRot = LocalRot * ParentRot; | ||
676 | |||
677 | Vector3 RezPoint = Newpos; | ||
678 | |||
679 | MainLog.Instance.Verbose("REZINFO","Possible Rez Point:" + RezPoint.ToString()); | ||
680 | //pos = new LLVector3(RezPoint.x, RezPoint.y, RezPoint.z); | ||
681 | |||
682 | } | ||
683 | |||
640 | SceneObjectGroup sceneOb = | 684 | SceneObjectGroup sceneOb = |
641 | new SceneObjectGroup(this, m_regionHandle, ownerID, PrimIDAllocate(), pos, rot, shape); | 685 | new SceneObjectGroup(this, m_regionHandle, ownerID, PrimIDAllocate(), pos, rot, shape); |
642 | AddEntity(sceneOb); | 686 | AddEntity(sceneOb); |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 474d434..45581c5 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs | |||
@@ -353,6 +353,44 @@ namespace OpenSim.Region.Environment.Scenes | |||
353 | } | 353 | } |
354 | } | 354 | } |
355 | 355 | ||
356 | public EntityIntersection testIntersection(Ray hRay) | ||
357 | { | ||
358 | EntityIntersection returnresult = new EntityIntersection(); | ||
359 | bool gothit = false; | ||
360 | foreach (SceneObjectPart part in m_parts.Values) | ||
361 | { | ||
362 | SceneObjectPart returnThisPart = null; | ||
363 | Vector3 partPosition = new Vector3(part.AbsolutePosition.X,part.AbsolutePosition.Y,part.AbsolutePosition.Z); | ||
364 | Quaternion parentrotation = new Quaternion(GroupRotation.W,GroupRotation.X,GroupRotation.Y,GroupRotation.Z); | ||
365 | EntityIntersection inter = part.testIntersection(hRay,parentrotation); | ||
366 | |||
367 | float idist = 256f; | ||
368 | |||
369 | |||
370 | |||
371 | |||
372 | if (inter.HitTF) { | ||
373 | // We need to find the closest prim to return to the testcaller along the ray | ||
374 | if (inter.distance < idist) { | ||
375 | |||
376 | idist = inter.distance; | ||
377 | returnresult.HitTF = true; | ||
378 | returnresult.ipoint = inter.ipoint; | ||
379 | returnresult.obj = part; | ||
380 | returnresult.normal = inter.normal; | ||
381 | returnresult.distance = inter.distance; | ||
382 | gothit = true; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | |||
387 | } | ||
388 | return returnresult; | ||
389 | |||
390 | } | ||
391 | |||
392 | |||
393 | |||
356 | /// <summary> | 394 | /// <summary> |
357 | /// | 395 | /// |
358 | /// </summary> | 396 | /// </summary> |
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 7bab3b6..e68632b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs | |||
@@ -535,6 +535,91 @@ namespace OpenSim.Region.Environment.Scenes | |||
535 | serializer.Serialize(xmlWriter, this); | 535 | serializer.Serialize(xmlWriter, this); |
536 | } | 536 | } |
537 | 537 | ||
538 | public EntityIntersection testIntersection(Ray iray, Quaternion parentrot) | ||
539 | { | ||
540 | |||
541 | //Sphere dummysphere = new Sphere(); | ||
542 | |||
543 | EntityIntersection returnresult = new EntityIntersection(); | ||
544 | Vector3 vAbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); | ||
545 | Vector3 vScale = new Vector3(Scale.X, Scale.Y, Scale.Z); | ||
546 | Quaternion qRotation = new Quaternion(RotationOffset.W, RotationOffset.X, RotationOffset.Y, RotationOffset.Z); | ||
547 | |||
548 | |||
549 | |||
550 | Quaternion worldRotation = (qRotation * parentrot); | ||
551 | Matrix3 worldRotM = worldRotation.ToRotationMatrix(); | ||
552 | |||
553 | |||
554 | |||
555 | Vector3 rOrigin = iray.Origin; | ||
556 | Vector3 rDirection = iray.Direction; | ||
557 | |||
558 | |||
559 | |||
560 | Vector3 r2ndDirection = rDirection * rDirection; | ||
561 | |||
562 | float itestPart1 = r2ndDirection.x + r2ndDirection.y + r2ndDirection.z; | ||
563 | |||
564 | Vector3 tmVal2 = rOrigin - vAbsolutePosition; | ||
565 | |||
566 | Vector3 r2Direction = rDirection * 2.0f; | ||
567 | Vector3 tmVal3 = r2Direction * tmVal2; | ||
568 | |||
569 | float itestPart2 = tmVal3.x + tmVal3.y + tmVal3.z; | ||
570 | |||
571 | Vector3 tmVal4 = rOrigin * rOrigin; | ||
572 | Vector3 tmVal5 = vAbsolutePosition * vAbsolutePosition; | ||
573 | |||
574 | Vector3 tmVal6 = vAbsolutePosition * rOrigin; | ||
575 | |||
576 | float radius = 0f; | ||
577 | if (vScale.x > radius) | ||
578 | radius = vScale.x; | ||
579 | if (vScale.y > radius) | ||
580 | radius = vScale.y; | ||
581 | if (vScale.z > radius) | ||
582 | radius = vScale.z; | ||
583 | |||
584 | //radius = radius; | ||
585 | |||
586 | float itestPart3 = tmVal4.x + tmVal4.y + tmVal4.z + tmVal5.x + tmVal5.y + tmVal5.z -(2.0f * (tmVal6.x + tmVal6.y + tmVal6.z + (radius * radius))); | ||
587 | |||
588 | // Yuk Quadradrics | ||
589 | float rootsqr = (itestPart2 * itestPart2) - (4.0f * itestPart1 * itestPart3); | ||
590 | if (rootsqr < 0.0f) | ||
591 | { | ||
592 | |||
593 | return returnresult; | ||
594 | } | ||
595 | float root = ((-itestPart2) - (float)Math.Sqrt((double)rootsqr)) / (itestPart1 * 2.0f); | ||
596 | |||
597 | if (root < 0.0f) | ||
598 | { | ||
599 | // perform second quadratic root solution | ||
600 | root = ((-itestPart2) + (float)Math.Sqrt((double)rootsqr)) / (itestPart1 * 2.0f); | ||
601 | |||
602 | // is there any intersection? | ||
603 | if (root < 0.0f) | ||
604 | { | ||
605 | |||
606 | return returnresult; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | 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)); | ||
611 | |||
612 | returnresult.HitTF = true; | ||
613 | returnresult.ipoint = ipoint; | ||
614 | Vector3 normalpart = ipoint-vAbsolutePosition; | ||
615 | returnresult.normal = normalpart.Normalize(); | ||
616 | returnresult.distance = ParentGroup.m_scene.m_innerScene.Vector3Distance(iray.Origin, ipoint); | ||
617 | |||
618 | return returnresult; | ||
619 | } | ||
620 | |||
621 | |||
622 | |||
538 | /// <summary> | 623 | /// <summary> |
539 | /// | 624 | /// |
540 | /// </summary> | 625 | /// </summary> |
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 3929f0f..850d3a4 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs | |||
@@ -147,6 +147,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
147 | get { return m_regionHandle; } | 147 | get { return m_regionHandle; } |
148 | } | 148 | } |
149 | 149 | ||
150 | public Vector3 CameraPosition | ||
151 | { | ||
152 | get { return m_CameraCenter; } | ||
153 | } | ||
154 | |||
150 | private readonly string m_firstname; | 155 | private readonly string m_firstname; |
151 | 156 | ||
152 | public string Firstname | 157 | public string Firstname |