Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007061opensim[REGION] Physics Enginespublic2014-03-18 05:432014-03-24 11:47
ReporterEzequielM81 
Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
StatusnewResolutionopen 
PlatformPhenom II 955 - 16GB RAMOSWindows 7OS Version64 bits
Product Version 
Target VersionFixed in Version 
Summary0007061: Collisions and llCastRay
DescriptionI have being trying to reproduce a combat sistem i am actually working on Second Life too, and i have noticed that at speed faster than 15 mts per seconds (while a real bullet would travel at least at 180 mts/sec and i am unsing 100 on my scripts), the collisions are not detected nor the ray-cast does.
Steps To Reproduce- Create a ball as bullet and set it physical and temporal ((size about 2 cm = 0.02 mts or could be 10 cm too)
- Add an script to do someting on collision and to repeat a castray to detect till 5 objects every 0.022 seconds (which is a sim time unit on Second Life).
- Create a popgun
- Set the bullet (llRezObject from the gun) velocity to 20
TagsNo tags attached.
Git Revision or version number
Run Mode Grid (Multiple Regions per Sim)
Physics EngineBulletSim
EnvironmentUnknown
Mono VersionNone
Viewer
Attached Files

- Relationships

-  Notes
(0025480)
EzequielM81 (reporter)
2014-03-19 09:15
edited on: 2014-03-19 09:18

I was checking the OpenSimulator code a little bit and i have tested the timing about llRayCast and it doesn't take much to cast the ray. Tho initialy sometimes it take 127 miliseconds, the next ones are achived between 10 and 100 miliseconds. It's fine so far cuz i have that variation in mind.
What i did to test it, was to build an object with a timer triggered every 22 miliseconds that cast a ray measuring 15 meters forward.
Which suprise me is that the RayCast function is called by the script only twice in a second, even when the ray casting takes only 60 or 50 miliseconds to return the value, so i think it could be some issue with the script engine.
Hope it helps to find a solution to this issue.

- Edited -
I forgot to mentione that i didn't check whether the RayCast funciton return any detection.

(0025534)
EzequielM81 (reporter)
2014-03-23 19:44

I was testing the scripts performaces about timers and collision again, and so far ray casting responds on a reasonable time, but i was surprised to find out that the timer even have a minimun even time about 500 miliseconds.
To see this i created an script that take 10 measures and this was the result:

[19:28] Primitive: Iniciando medición...
[19:28] Primitive: Medición completa en 5.130296 segundos.
[19:28] Primitive: Reporte:
probe 0 time 51.002900 mS
probe 1 time 49.002800 mS
probe 2 time 78.004400 mS
probe 3 time 48.002700 mS
probe 4 time 48.002700 mS
probe 5 time 49.002800 mS
probe 6 time 50.002800 mS
probe 7 time 49.002800 mS
probe 8 time 95.005400 mS
probe 9 time 52.004400 mS
timer 0 time 632.036200 mS
timer 1 time 495.028300 mS
timer 2 time 529.031700 mS
timer 3 time 470.026900 mS
timer 4 time 500.028600 mS
timer 5 time 501.028700 mS
timer 6 time 502.028700 mS
timer 7 time 498.028500 mS
timer 8 time 546.031200 mS
timer 9 time 457.027600 mS

This is the script i used to test it. Additionally i made an script without the ray casting call and the result was around the same, the minimun trigger timer even was about 500 miliseconds, which as far as Second Life script reference tells should be a sim "tick" (22 miliseconds).

float timerPeriod = 0.022;
integer measuresMax = 10;

list lstMeasures = [];
list lstTimer = [];
integer measures = 0;
float measureInitTime = 0;
float lastTimerCall = 0;

getRayCastCollision()
{
    float initTime = llGetTime();
    // Obtengo las colisiones con varios desplazamientos para asegurarme que aunque
    // se mueva poco el avatar, sigo apuntando
    list lista = castRayWithOffset(<0,0,0>, <9,0,0>);
    
    float endTime = llGetTime();
    lstMeasures += ((endTime - initTime) * 1000);
    
    // Chequeo si le estoy apuntando a algun avatar.
    integer count = llGetListLength(lista);
    if (count > 0)
    {
            
    }
}
    
list castRayWithOffset(vector start_offset, vector rez_offset)
{
    // Offset
    // +x = Forward
    // +y = Left
    // +z = Up
    
    vector posicion = llGetPos();
    rotation rotacion = llGetRot();
    
    vector start = posicion + (start_offset * rotacion);
    vector end = posicion + (rez_offset * rotacion);
    
    list detectados = [];

    list results = llCastRay(start, end, [RC_REJECT_TYPES, 0,
                                          RC_MAX_HITS, 5] );
    
    integer hitNum = 0;
    integer hitCount = llList2Integer(results, -1);
 
    // Handle error conditions here by checking llList2Integer(results, -1) >= 0
    while (hitNum < llList2Integer(results, -1))
    {
        // Stride is 2 because we didn't request normals or link numbers
        key uuid = llList2Key(results, 2*hitNum);
        detectados += [uuid];
           
        ++hitNum;
    }
    
    return detectados;
}



init()
{
    llOwnerSay("Script Iniciado");
    llSetTimerEvent(0);
}

default
{
    state_entry()
    {
        init();
    }

    on_rez(integer start_param)
    {
        llResetScript();
    }
    
    touch_start(integer num_detected)
    {
        llOwnerSay("Iniciando medición...");
        
        measures = 0;
        lstMeasures = [];
        lstTimer = [];
        measureInitTime = llGetTime();
        lastTimerCall = measureInitTime;
        llSetTimerEvent(timerPeriod);
    }
    
    timer()
    {
        getRayCastCollision();
        float now = llGetTime();
        lstTimer += ((now - lastTimerCall) * 1000);
        lastTimerCall = now;
        
        measures++;
        
        if (measures == measuresMax)
        {
            llSetTimerEvent(0);
            llOwnerSay("Medición completa en " + (string)(llGetTime() - measureInitTime) +
                        " segundos.");
            string measuresElapsed = "Reporte:\n";
            integer readCount = 0;
            integer count = llGetListLength(lstMeasures);
            while (readCount < count)
            {
                measuresElapsed += "probe " + (string)readCount +
                                   " time " + (string)llList2String(lstMeasures, readCount) +
                                   " mS\n";
                  readCount++;
            }
            readCount = 0;
            while (readCount < count)
            {
                measuresElapsed += "timer " + (string)readCount +
                                   " time " + (string)llList2String(lstTimer, readCount) +
                                   " mS\n";
                  readCount++;
            }
            llOwnerSay(measuresElapsed);
        }
    }
    
}
(0025535)
melanie (administrator)
2014-03-23 20:00

Timers in OpenSim are throttled because OpenSim will not work if they are run at full speed, the sim doesn't get to do anything else anymore then. This has been discussed a number of times. There is a parameter you can use to make them faster on your sims, though.

I really don't understand what you're trying to do, though.

For a gun, you would normally use either physics or raycast, not both.

Physics step size corresponds to 11fps internally, so the usual length of 1m for a bullet "tail" in SL needs to be changed. Either the bullet needs to fly slower, or be longer. Sorry, them's the breaks with physics. Bullet may change that.

So you either "throw" a physical bullet, or you cast a ray and then chat the result to the opponents combat meter. I see no point in combining raycast and physics in a single weapon, as they are orthogonal for combat use.

Ray cast, in a gun, would usually be performed once when the trigger is pulled, so I don't see why you need fast timers for this.
(0025536)
nebadon (administrator)
2014-03-23 20:02
edited on: 2014-03-23 20:03

try setting this in your OpenSim.ini [Xengine] section

    MinTimerInterval = 0.08

see if it improves the numbers, i could not get to 20ms though but mine did considerably better than yours did.

[19:58] Primitive: Iniciando medición...
[19:58] Primitive: Medición completa en 1.093689 segundos.
[19:58] Primitive: Reporte:
probe 0 time 57.785000 mS
probe 1 time 50.622000 mS
probe 2 time 52.819000 mS
probe 3 time 54.437000 mS
probe 4 time 48.586000 mS
probe 5 time 54.103000 mS
probe 6 time 56.762000 mS
probe 7 time 56.061000 mS
probe 8 time 64.436000 mS
probe 9 time 48.186000 mS
timer 0 time 185.896000 mS
timer 1 time 93.438000 mS
timer 2 time 102.087000 mS
timer 3 time 101.874000 mS
timer 4 time 94.928000 mS
timer 5 time 104.942000 mS
timer 6 time 102.893000 mS
timer 7 time 99.270000 mS
timer 8 time 109.439000 mS
timer 9 time 98.895000 mS

(0025537)
melanie (administrator)
2014-03-23 20:05

Nebadon, the goal is to avoid fast timers. In busy sims, they are not good for stability. Code should be based on events as much as possible, not on polling by a timer.
(0025538)
nebadon (administrator)
2014-03-23 20:09

I run most of my simulators with 0.08 and have never experienced any stability issues, but I don't disagree either, if your doing a high performance app though there is not much harm in experimenting with this variable and pushing beyond what some might consider sane :)
(0025539)
melanie (administrator)
2014-03-23 20:13

Combat is one of the most taxing things you can do in a sim. In SL, combat meters and weapons must be highly optimized because often you have more than 50 people just bashing each other, a real firework of events.
I strongly recommend against any timer shorter than 0.5s in any combat sim. It WILL break. I have the t-shirt. Several in fact.
Anything that needs a fast timer is misdesigned.
(0025540)
nebadon (administrator)
2014-03-23 20:21

what is the best way to improve the performance?
(0025541)
melanie (administrator)
2014-03-23 20:28

NO listeners if they can be avoided, ABSOLUTELY NO LISTENERS on channel 0. Voice commands are overrated. Equipment worn on a single avatar that needs to communicate should use the osMessage* functions or create a unique channel from the avatar ID so chat is sent to as few recipients as possible. Every script receiving chat needs to wake up, even if all it does is discard it.

Stuff that uses chat commands, like draw/holster gestures, should use specific listeners so the filtering is done by the sim, not the script.

No fast timers. Anything that can be event driven should be. No polling of anything. If timers are needed, use ONE timer script in the object and let everything else register timers with it. It's cheaper to wake one script multiple times than all scripts all of the time.

Use link numbers in llMessageLinked, don't use LINK_SET unless you intend to broadcast. Link message fireworks can be minimized if not all scripts are in the same prim.

Avoid physics like the plague.

Don't integrate any radar or tracking abilities unless absolutely required, the repeated raycasts and/or sensors can KILL a sim dead.

If you know that only you use a channel, like because it's random, use llRegionSay on it. It avoids the square root neede for distance calculation, so saves time.

BEWARE, RegionSay is RegionSay - if the channel ins not private, it will cause more lag, not less.

Use a packed message protocol, messages have overhead so of you can pack more than one message, DO IT.

Always think "does this cause a script to be woken up?" and work to avoid that.

That's what I can think of right now. These rules apply to both OpenSim and SL.
(0025542)
nebadon (administrator)
2014-03-23 20:32

all very good tips, but I was thinking more how can we improve the performance of the engine itself, so it provides closer to SL like abilities? or even exceed SL's performance? which at this point feels like we are pretty far from.
(0025543)
dahlia (administrator)
2014-03-23 20:35

Shouldn't the physics engine collision test "stretch" the object along the direction and distance traveled between frames? Perhaps there is a misconfiguration somewhere in the physics interface code?
(0025544)
melanie (administrator)
2014-03-23 20:35

It's always tradeoffs. If you don't use AppDoains you can use more threads and lower timer intervals, but timer speed is NOT "performance". Performance is when you have a sim with 3000+ scripts and it doesn't lag and I believe we have that.

AppDomains muck it up, but are needed for development.
(0025545)
melanie (administrator)
2014-03-23 20:36

No, at least Havok and ODE don't do that. That is why a bullet in SL is a meter long stick.
(0025546)
dahlia (administrator)
2014-03-23 20:40

maybe they don't, but its not uncommon in many physics implementations and it's probably implemented in Bullet
(0025547)
EzequielM81 (reporter)
2014-03-23 21:17

Ok, what you suggest about the timers is something very true, but the facts points about i can not make a bullet travel at 100 meters per seconds and get the collision if the bullet is not 10 meters long or even more since at runtime the bullet jumps, it doesnt move every 10 meters.
So would be a very nice thing to can avoid such a fast timers, but it's not possible to detect collisions on that way.
For what i was seeing collision are checked by soft... and i was thinking about something that could sound a little stupid, but i could do that at Unity and it would works great... so, why cant we use the Collision functions on the video card to avoid this task? i know it would mean to "render" a whole scene about the sim objects, but since it doesnt need to be rendered on the screen, wouldnt it add a better performance on these kind of tasks?

Talking about the messages between the objects, i could not use osMessage since it's specific from OpenSim... and i want the CS to work on both.. SL and OS

In the other hand i have ran the script i posted here at SL and the result was this one:

[21:04] Object: Iniciando medición...
[21:04] Object: Medición completa en 0.466144 segundos.
[21:04] Object: Reporte:
timer 0 time 44.404030 mS
timer 1 time 66.795350 mS
timer 2 time 44.003490 mS
timer 3 time 44.065480 mS
timer 4 time 44.590950 mS
timer 5 time 45.126910 mS
timer 6 time 45.564650 mS
timer 7 time 43.106080 mS
timer 8 time 44.615750 mS
timer 9 time 43.870930 mS

I will try to change the XEngine setting.. and another thing i was thinking is... Unity use Mono a script engine and i know SL uses it aswell... couldnt it be possible to implement Mono as script engine on OS?
(0025548)
dahlia (administrator)
2014-03-23 21:33

Video cards don't have "collision functions", they have vertex and fragment processors; this is moot anyway as in OpenSimulator, collisions are calculated on the server which in most cases does not have a video card.

If you need a faster timer, consider using the not_at_target() event. Your script will need an active target in order for this event to fire, and if you do have one, the event will be called once every simulation frame. Any events which fire more frequently than once per frame are essentially wasted anyway as the scene will be in an inconsistent state, and any actions which occur more frequently risk being overridden as they may not have been propagated before the next event occurs.

Collision events should be sent to a script regardless of the existence of a timer, assuming the collision was detected by the physics engine. You don't need a timer to detect collisions.
(0025549)
EzequielM81 (reporter)
2014-03-23 22:59
edited on: 2014-03-23 23:11

Well i dont use the collision cuz i dont get the collision, but instead i use a timer and cast a ray to know if is there anything 10 meters in front of the bullet, on this way it does detect most of the agents in front the bullet... and maybe you are right, i was thinking about ray casting not about collisions, and anyway what i mean is that an advanced and low level library as OpenGL should resolve it much faster that any other code, using or not a video. A video card inst another than a much avanced mathematic processor specialy optimized to work with matrix. Even is the server doesnt have a video card, the graphic library have much optimized code to achieve it than to reinvent it again on most of the cases. Anyway, whether a server have or doesnt have a video card (which arent expensive) would improve the simulator performace in case it have one. Most of people that run OpenSim, use it on a home-made server, so i bet many of the have a video card installed....

Other thing i have noticed about, it's that when i give the bullet light and i fire it, the lights is shown on ramdom places over the sim and not on straight line... which give me doubts about what really the bullet does when it have velocity....

I have left the collision even cuz it's nice for slow things, but on a bullet that travel at 100 meters per second (when should be a little more, like 180) it's practically impossible to detect a success collision with the 1st object.

Another thing is.... my script (which i didnt post here) works great on SL, but i am having problems at OS on an empty sim. Yes, it gives my processor a big load as it's and i could make it on many other ways, but the most realistic way to do it.

(0025556)
melanie (administrator)
2014-03-24 06:25

That is so incredibly wasteful! Why are you throwing a slug at all? A single raycast from the gun would tell you if it's hit someone or not! Imagine 100+ of those bullets in the air - the sim would stone cold crash, even in SL!

When you use combat meters, you don't even need physical projectiles anymore! Just cast a ray and inform the target he's hit!
(0025557)
EzequielM81 (reporter)
2014-03-24 08:03

No, it will not be good anough just casting a ray and this is a not a report about how to make a combat system.... So how do i do it or not doesnt matter. The thing is the timers dont run as fast as should
(0025558)
EzequielM81 (reporter)
2014-03-24 08:06

And the thing is not only about the timers. On OS the collision are not detected very well. When i turned off on first place the ray casting and only have set the collisions, i could see the bullet hitting the wall i made but never ever sent me the message about the collision.
(0025559)
nebadon (administrator)
2014-03-24 08:10

I imagine that llCastRay as it is in core code is prone to failure on many levels, like not being able to shoot through hollow and cut prims, I use it in my vehicles to reset the vehicle when you flip upside down or crash, and it works ok about 90% of the time, but that 10% error margin seems a bit high to totally rely on it right now for a production level combat system, or really anything that needs like 99.9% accuracy.
(0025560)
melanie (administrator)
2014-03-24 08:12

Timers run as fast as they should. They should run at 500ms intervals. This is OpenSim and although OpenSim loosely follows SL technology, OpenSim is NOT a SL clone. There is no requirement for OpenSim to be like SL. This is one of the points where it is different.
Generally, we try to be as similar as possible, but where that can't be done we do diverge. There is no valid "should" that can be based on SL.
(0025561)
EzequielM81 (reporter)
2014-03-24 08:45

Melanie, got it. On the way you are talking about just get used as OS works and not to improve them it's really hard to make things go better and even hard make ppl from SL get interested into this. SL scripting is very bad already to have it even worse on OS. So instead to argue about what does OS does or not? why dont we get hands on work? and i said WE, cuz yes... i want to solve it too
(0025573)
EzequielM81 (reporter)
2014-03-24 11:47

Thanx nebadon, i changed the setting you told me and it got better, but i had to add the line cuz as i am using it since some time ago,i guess it didnt have that configuration line before. Now this is the report i get from the timer... tho i will look for the way to make it works better:

Iniciando medición...
[11:46] Primitive: Medición completa en 0.985086 segundos.
[11:46] Primitive: Reporte:
probe 0 time 54.005300 mS
probe 1 time 83.008700 mS
probe 2 time 53.504100 mS
probe 3 time 53.003000 mS
probe 4 time 60.505500 mS
probe 5 time 89.509700 mS
probe 6 time 91.507700 mS
probe 7 time 55.004400 mS
probe 8 time 69.008200 mS
probe 9 time 51.002900 mS
timer 0 time 89.007300 mS
timer 1 time 126.011100 mS
timer 2 time 71.006100 mS
timer 3 time 99.007500 mS
timer 4 time 107.508200 mS
timer 5 time 129.513600 mS
timer 6 time 102.009000 mS
timer 7 time 63.004800 mS
timer 8 time 116.013200 mS
timer 9 time 82.004700 mS

- Issue History
Date Modified Username Field Change
2014-03-18 05:43 EzequielM81 New Issue
2014-03-18 06:34 EzequielM81 Summary Collisions and rayCast => Collisions and llCastRay
2014-03-18 06:34 EzequielM81 Steps to Reproduce Updated View Revisions
2014-03-19 09:15 EzequielM81 Note Added: 0025480
2014-03-19 09:18 EzequielM81 Note Edited: 0025480 View Revisions
2014-03-23 19:44 EzequielM81 Note Added: 0025534
2014-03-23 20:00 melanie Note Added: 0025535
2014-03-23 20:02 nebadon Note Added: 0025536
2014-03-23 20:03 nebadon Note Edited: 0025536 View Revisions
2014-03-23 20:05 melanie Note Added: 0025537
2014-03-23 20:09 nebadon Note Added: 0025538
2014-03-23 20:13 melanie Note Added: 0025539
2014-03-23 20:21 nebadon Note Added: 0025540
2014-03-23 20:28 melanie Note Added: 0025541
2014-03-23 20:32 nebadon Note Added: 0025542
2014-03-23 20:35 dahlia Note Added: 0025543
2014-03-23 20:35 melanie Note Added: 0025544
2014-03-23 20:36 melanie Note Added: 0025545
2014-03-23 20:40 dahlia Note Added: 0025546
2014-03-23 21:17 EzequielM81 Note Added: 0025547
2014-03-23 21:33 dahlia Note Added: 0025548
2014-03-23 22:59 EzequielM81 Note Added: 0025549
2014-03-23 23:07 EzequielM81 Note Edited: 0025549 View Revisions
2014-03-23 23:11 EzequielM81 Note Edited: 0025549 View Revisions
2014-03-24 06:25 melanie Note Added: 0025556
2014-03-24 08:03 EzequielM81 Note Added: 0025557
2014-03-24 08:06 EzequielM81 Note Added: 0025558
2014-03-24 08:10 nebadon Note Added: 0025559
2014-03-24 08:12 melanie Note Added: 0025560
2014-03-24 08:45 EzequielM81 Note Added: 0025561
2014-03-24 11:47 EzequielM81 Note Added: 0025573


Copyright © 2000 - 2012 MantisBT Group
Powered by Mantis Bugtracker