Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Object collision can't be that hard, can it?

Hawk Horton
Registered User
Join date: 7 Sep 2005
Posts: 26
05-25-2006 13:59
I'm trying to create a script that has a 'bullet' bounce off of a flat surface along a realistic angle. I've put the bouncing part in a collision_start event, which should work okay, but the 'bullet' refuses to detect when it hits something. What am I missing? Do objects need to be physical to have collision?

Here's the script I use:
CODE

default
{
state_entry()
{
llSetTimerEvent(0.5);
//llSetBuoyancy(1);
//llVolumeDetect(TRUE);
//llCollisionFilter("mirror", NULL_KEY, TRUE);
llSetStatus(STATUS_PHYSICS, FALSE);
llPassCollisions(TRUE);
}

timer()
{
vector gPosition = llGetPos();
llOwnerSay("SIM: " +
llGetRegionName() + ", Position: " +
(string)llRound(gPosition.x) +"," +
(string)llRound(gPosition.y) +", Height: " +
(string)llRound(gPosition.z) + ")");

vector currentPos = llGetPos();
vector newPos = currentPos + <0.1, 0, 0>;
llSetPos(newPos);
}

collision_start(integer num_detected)
{
llOwnerSay("Colliding with "+(string)llDetectedKey(0));
rotation mirrorRot = llDetectedRot(1);
rotation ballRot = llGetRot();
rotation angleDiff = (ballRot+<180, 180, 180, 0>)-mirrorRot;
rotation newAngle = mirrorRot - angleDiff;
llSetRot(newAngle);
}
}
Ralph Doctorow
Registered User
Join date: 16 Oct 2005
Posts: 560
05-25-2006 14:07
If your object is phantom due to executing the llVolumeDetect, it will not detect non-physical objects. Try explicitly making the object non-phantom, don't execute llVolumeDetect and try it again.

IMHO this is a bug, but apparently LL doesn't agree.
Draco18s Majestic
Registered User
Join date: 19 Sep 2005
Posts: 2,744
05-25-2006 15:32
From: Hawk Horton

-----------------------------------
(Sorry about the bad formatting. I also like to know how to create such a nice-looking script box.)


Like this:
[ code] code here [ /code] (remove saces inside the [] )
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
05-25-2006 17:24
[ php] and [ /php] without the spaces will give you the colours too.
Hawk Horton
Registered User
Join date: 7 Sep 2005
Posts: 26
05-26-2006 01:19
Thanks Eloise. At least the code looks much better now.

Unfortunately my main problem isn't solved yet. I had already commented llVolumeDetect during my last test, but to make sure I've also added the explicit call for a non-physical object. It doesn't make any difference though.

It looks as though my 'bullet' doesn't detect any objects at all. I just tried to put my avatar in its path and it did push my avatar aside. It didn't respond with its llOwnerSay message though, so I assume it was my avatar detecting the 'bullet', not the other way around.

If anyone has any more ideas, please send them this way.
Bitzer Balderdash
Dazed and Confused
Join date: 21 Dec 2005
Posts: 246
05-26-2006 03:10
Why do you have the call to llPassCollisions() in there?

if your script in is a child prim, that will tell the scripts in the prim to ignore the collision and allow the root prim to handle it.

If it is in the root prim, I'm not sure _what_ it will do, but probably nothing good.
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
05-26-2006 03:13
I didn't really look at the code last night, it was after 1am over here.

The thing that looks to me like it's causing problems is in your collision event.

What's the llDetectedRot(1) detecting? I suspect there's only 1 collision, so it should be llDetectedRot(0).

The transform for the reflection is wrong too, the 180's suggest you're working in an euler and in degrees. There's no conversion to an euler, nor to degrees in the code though... Have a read of Rotations on the wiki.

I'm really not an expert at rotations. I have a suspicion what you want might be something like llSetRot(llGetRot() * llRotBetween(llGetRot(), llDetectedRot(0)) * llRotBetween(llGetRot(), llDetectedRot(0))); but there is probably a much, much nicer way to do it than that, and no guarantees that that's the right thing either. Hopefully someone who actually understands them (rather than abuses them like I do) will have a look soon!
Bitzer Balderdash
Dazed and Confused
Join date: 21 Dec 2005
Posts: 246
05-26-2006 03:24
More than that on the angles - the rotation of the detected object has little or nothing to do with the angle at which you need to bounce off it.

The angle for a realistic deflection would be based around mirroring your motion against the plane tangetial to the object at the point of impact. Consider if you are hitting a sphere - the rotation of the sphere relative to the in-world coordinates has no effect on the direction of your new path, but the point on the sphere that you hit would be critical.

As fas as I know, the ONLY way to get that sort of information is to let the physics engine do it for you - that is what it is for, after all.

Is there any reason why you're not making the bullet physical and letting it do all the hard work for you?
Hawk Horton
Registered User
Join date: 7 Sep 2005
Posts: 26
05-27-2006 03:56
I messed around with the script some more, but I just can't get a collision.
As you can see the first thing I ask when a collision is detected is for the script to speak to me. This never happens, therefore I assume the collision event is never activated.

I also added the euler-conversion, so my ball won't go spinning in unpredictable directions, but this won't show until that collision problem is solved.

Earlier I played around with physical objects, but they prove to be too unpredictable to be useful for the game I'm building. Players will have to guess the deflection angle of the 'bullet' as it comes towards them and bounce it in a preferred direction.
The physics engine is just to erratic for this. When I put one of the deflection objects (a flat surface) at a 45 degree angle in front of the 'bullet', the 'bullet' slid along the surface for a second before rolling off the edge.

I tested a model for the deflection mechanics in Flash Actionscript. You can find the result on my weblog: www.openbrainsurgery.wordpress.com

This is the code in Actionscript:
CODE

function collisionDetect(laser, playerHit) {
if (playerHit.mirror.hitTest(laser._x, laser._y)) {
mirrorRot = playerHit._rotation;
laserRot = laser._rotation;
angleDiff = (laserRot+180)-mirrorRot;
newLaserAngle = mirrorRot-angleDiff;
laser._rotation = newLaserAngle;
}
}


And this is the latest version of my LSL script:
CODE

default
{
state_entry()
{
llSetTimerEvent(0.5);
//llSetBuoyancy(1);
//llVolumeDetect(TRUE);
//llCollisionFilter("mirror", NULL_KEY, TRUE);
llSetStatus(STATUS_PHYSICS, FALSE);
//llPassCollisions(TRUE);
}
timer()
{
vector gPosition = llGetPos();
llOwnerSay("SIM: " +
llGetRegionName() + ", Position: " +
(string)llRound(gPosition.x) +"," +
(string)llRound(gPosition.y) +", Height: " +
(string)llRound(gPosition.z) + ")");

vector currentPos = llGetPos();
vector newPos = currentPos + <0.1, 0, 0>;
llSetPos(newPos);
}
collision(integer num_detected)
{
llOwnerSay("Colliding with "+(string)llDetectedKey(0));
rotation mirrorRot = llDetectedRot(0);
rotation ballRot = llGetRot();
rotation angleDiff = (ballRot+llEuler2Rot(<180, 180, 180>))-mirrorRot;
rotation newAngle = mirrorRot - angleDiff;
llSetRot(newAngle);
}
}
Bitzer Balderdash
Dazed and Confused
Join date: 21 Dec 2005
Posts: 246
05-27-2006 08:48
Just tried playing with your script in-world.

AS far as I can see - and this is what I thought was the case - the entire collision system is based on the physics engine - i.e. it only works for physical objects.

That also fits with my past experiences of llSetPos based teleporters being able to trivially move you through any intervening solid objects.

So I strongly suspect that you are going to be out of luck, totally, with this project without using physics.



Also, on the math - I took a look at what you are doing, and popped over to your blog. The code sample is looking at the amazingly special-case of a 2d world, with planar mirrors, where the angle of the plane of the mirror is defined as the rotation in the 2d plane that is the world.

The calls you are using in your LSL return something ever so different to that as a rotation - you are getting a quaternation back (a four element vector), rather than a simple angle, and your maths is.... probably not going to do what you expect.

I assume you are trying to build some kind of game where shots bouce around the game-grid being reflected off movable rotatable obstacles - the mirrors.

All I can suggest as avenues would be to look at llVolumeDetect on a phantom prim to see when a target comes into range, perhaps with llSay based comms between the items to report exact positions so you can work out the maths for the new departure vector.
Hawk Horton
Registered User
Join date: 7 Sep 2005
Posts: 26
05-28-2006 08:43
Thanks for the elaborate explanation Bitzer.
I'll see what I can achieve with the physics engine or llVolumeDetect in the coming week. I still have a lot to learn about LSL. If some of my ideas don't work out I could perhaps alter my game to work with the possibilities.

If I run into any strange obstacles again I'll reopen the thread.