This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Frage: Gibt es engines für physikalische Objekte
#1
Hallo zusammen

Ich experimentiere wie blöd für ein Shuttle, das zur Space station fliegen soll. Normalerweise mache ich ja alles mit route scripts und werde es wohl auch wieder so machen müssen, weil ich einfach keinen Engine finde, der das Shuttle physikalisch mit covex hull in features lässt (für mesh objekte) und man einfach über die Rampe von hinten rein laufen kann um dann Platz zu nehmen und dann zur Space station zu fliegen. Wenn man drin sitzt soll es egal sein ob es Phantom ist oder physikalisch bleibt, aber man sollte wenn man wieder stand target aufsteht auch wieder auf dem Boden des Shuttles landen und nicht runter fliegen.

Ausserdem soll der flight engine auch einfach zu handhaben sein und schön smooth fliegen kann bei dem man sich auch unterhalten kann und nur flug korrekturen machen muss. Ich habe so einen engine für mein seaplane und funktioniert grossartig auf bulletsim physics, aber wenn der engine eingebaut ist, dann ist das shuttle automatisch Phantom. Genauso als wenn ich route script eingebaut hätte. Es soll aber überall landen können ohne dass ich extra transparente Legos als Boden irgendwo aufstelle um dann auch normal in und aus dem Shuttle laufen zu können.

Weiss also jemand ob es so einen engine für bulletsim gibt? Wenn es nur mit mesh physics in feature funktioniert ist es auch gut. Hauptsache es funktioniert überhaupt.
Mein Zuhause ist hier:
decadence.ddns.net:8002:big city life
decadence.ddns.net:8002:decadence
Zitieren
#2
Hallo Cheryl, möglicherweise könnte Ziggy Cagney auf der Region "Studio29" (vrplayground.ca:8002:Studio29) da weiter helfen.

Kann nicht sagen ob Ziggy helfen wird, aber ein Verusch ist es wert.

LG

Lukas
All done!
Zitieren
#3
Hallo Cheryl, ich denke du kannst es einfacher haben.

Ich hatte ein ähnliches Problem bei meiner Seilbahn. An beiden Stationen sollten man korrekt gehen können, und dazwischen bei der Fahrt auf einem PMAC Poser stehen.

Die Lösung war sehr einfach. Da beide Positionen in den Seilbahnstationen je Gondel immer exakt gleich sind, habe ich auf beiden Stationen die Physik statisch als unsichtbare Lauf Prims ausgeführt. Die Gondeln selber können dann phantom sein (siehe Anmerkung unten).

Das ist auch vorteilhaft wenn mal eine Gondel evakuiert weden müsste, was ja Rl immer wieder mal vorkommt...... aufstehen, abspringen.

Wie du dann dazwischen dein Schuttle bewegst bleibt sich dann egal.

Physikalisch ginge zwar, aber das erfordert ein Steuerungsprogramm mit soll-Ist Vergleich von Position, Geschwindigkeits-Vektor, 3D-Drehung.
Entsprechend musst du dann Angular und Linear Motor mit Kraft füttern damit die Soll Bewegung einigermaßen stattfindet.
Genau ist da nicht. Sowas könnte man machen wenn die genaue Route egal ist, und der Endpunkt nicht erreicht werden muss.
Das klingt aber nicht nach deinem Anwendungsfall.

Ach ja- und per Physik bewegte Objekte können nie phantom sein, zumindest das root Prim muss eine aktive physikalische Form haben.
Schaltest du alles auf Phantom, so bewegt sich dein Fahrzeug nicht mehr.

Bei anderen Bewegungsarten (Key framed Motion, oder in Microsteps) ist das egal.

Gruß Tron
Zitieren
#4
Hallo Lukas

Danke werde mal schauen. (region not found.)

Hallo Tron

Ja ich mache das ja auch mit meinen Flugzeugen und Schiffen. Läuft mit routescript und wenn man einsteigt läuft man auf transparenten Legos. Das wollte ich aber diesmal anders haben. Man soll selber mit dem Shuttle fliegen können und überall landen können. Nicht auf vorgegegebener Route.

Den Rest deines Postings habe ich nicht verstanden.

Aber ich habe mir mal dein Speedboat angeschaut. Da steht man ja drauf. Du hast zu Anfang bei deinem engine script die Anzahl der Prims angegeben, aus denen das Speedboot besteht. Ist es kein Engine wie die anderen sondern ein animiertes Boot? So lese ich es aus dem Script heraus.

liebe Grüße

Cheryl
Mein Zuhause ist hier:
decadence.ddns.net:8002:big city life
decadence.ddns.net:8002:decadence
Zitieren
#5
Hallo nochmal

Vielleicht ein wenig plastischer erklärt. Ich habe mehrere Shuttles um damit zur Raumstation zu fliegen. Eigentlich würde ich ein Route script nutzen um dann vom Flughafen/Weltraumbahnhof die Shuttle dorthin fliegen zu lassen. Wäre eine Keyframe Lösung und eine fest Start und Landeposition würde es dann ermöglichen fest Lego Plattformen dort zu bauen um dann einsteigen zu können. So habe ich es auch bei meinem Flugzeugen und Schiffen gemacht.

Jetzt möchte ich aber das Shuttle von überall her fliegen lassen und auch einsteigen können um dann Platz zu nehmen.

Ich habe eine super non physics engine gefunden, der auch, wenn man nah über Wasser fliegt das Wasser aufspritzen lässt und bei meinem bulletsim Sim auch super Eigenschaften besitzt wie man ein Shuttle fliegen lassen würde. Sieht sehr realistisch aus und ist smooth. Zudem muss man nur Kurskorrekturen machen und nicht die ganze Zeit Geschwindigkeit halten. Kann also sogar während dessen chatten. Natürlich nur wenn die Sim gross genug für sowas ist. Dieser Engine wäre also genau passend für mein Shuttle, nur wenn ich den Engine einbaue, dann ist mein 135 Prim shuttle phantom und ich kann nicht einsteigen. Auch mein mesh Tür script zum öffnen der Shuttle Rampe scheint wohl erst nach mehrmaligem click sich zu öffnen. Aber das ist eher Luxusproblem. Worum es mir geht ist, dass dieses Shuttle, wenn man nicht drin sitzt physikalisch ist und man reingehen kann um sich dann zu setzen auf PMAC poser. Danach kann das Shuttle gerne Phantom sein. Aber wenn keiner drin sitzt, dann soll es physikalisch sein.

Ich habe keine Ahnung wie man sowas coden kann. Alle Hinweise, die mir gegeben wurde verstehe ich zwar im Ansatz, aber kann es ja nicht umsetzen im praktischen, denn ich bin ja kein Coder.

Ich habe hier mal mein non physics engine script kopiert um zu zeigen, ob es möglich wäre dieses umzuschreiben.

// 2018-05-23 by Shinobar Martinek
integer DEBUG = FALSE;  // verbose messages to the owner

integer REGION_SIZE = 0;    // normally 256, varregion 512, 768, and etc., 0 for no limit
integer OWNER_ONLY = FALSE; // only the owner can drive
integer SUBMARINE = FALSE;  // no landing on the water
integer BOAT = FALSE;        // never land, never fly

float GROUND_LEVEL = 0.1;  //meter, lower surface of the root prim position above the ground
float FLOAT_LEVEL = -0.9;    //meter form the water, <-20.0 for submarine
float SINK_LEVEL = -3.5;    //meter, splashing stops but bubbles below this level
float FLIGHT_LEVEL= 10.0;  //meter, warning under this level

list ENGINE_SOUNDS= [ "bashaan", "s_idle", "engine2", "drone"];  //[ dummy, idle, run, fast ]
string START_SOUND = "Startup";
float START_MOMENT = 3.0;  //sexonds
string STOP_SOUND = "Shutdown";
float STOP_MOMENT = 2.0;    //seconds
string NOTE_SOUND = "airplane-pa";
string TOOLOW_SOUND = "TooLow";  // should be shorter than INTERVAL
string docking_FALSE;
//string WELCOME = "Thank you for riding.";
string DENY = "Sorry, you have not permission to drive.";
string ANOTHER_WELCOME = "Take the pilot sheet to drive.";
//string GOODBYE = "Thank you and goobye.";
string LAUNCH = "Press [Page Up] key to launch.";
//string LANDING = "Press [Page Down] key for docking.";
string CONTROL = "Use [Page Up]/[Page Down]/arrow keys,
[Shift] + right/left arrow keys to slide right/left.";
string MORE_POWER = "[Page Up] to power up.";
string HEAD_UP = "Down arrow key(↓) to take off.";
string TAKE_OFF = "We are on the air.";
string POWER_DOWN = "[Page Down] to land.";

vector BASE_SPEED = <-4.0, 1.0, 1.0>; //base speed, <X, Y, Z>
float MAX_YAW = 30.0    ;//degree for MAX_LEFTWARD
float MAX_PITCH = 60.0; //0.0 - 180.0 degree for MAX_UPWARD
float MAX_PITCH_GROUND = 15.0;  // degree limit on the ground
float MAX_ROLL = 60.0;  //degree for max sliding speed
float MAX_ROLL_GROUND = 15.0;  //degree
integer UPSTEP = 8;
integer MAX_UPWARD = 16;    //xUPSTEP for MAX_PITCH
integer MAX_FORWARD = -4;    //x BASE_SPEED.x
integer MAX_SLIDER = 8;    //x BASE_SPEED.y
integer LEFTSTEP = 2;
integer MAX_LEFTWARD = 8;  //xLEFTSTEP for MAX_YAW
float INTERVAL = 0.5;  //secind, watching interval
float LINIAR_RISE = 0.5;      //0.0-1.0, speed up rate for liniar movement
//float ANGULAR_RISE = 1.0;
float LINIAR_DECAY = 0.5;      //0.0 - 1.0, slow speed every INTERVAL(1.0: no slower)
float ANGULAR_DECAY = 0.3;  //0.0 - 1.0
float CROSS_DECAY = 0.9;    //0.0 - 1.0, slow in crossing regions
float WAVE_DRAG = 0.5;      //0.0 - 1.0, slower near water surface )1.0: no drag)

integer ABCENT_TIMEOUT = 120;  //xINTERVAL abcient pilot
integer CROSSING_TIMEOUT = 120;  //xINTERVAL
float CROSSING_MOMENT= 0.5;  //second wait time at crossing regions
//float BOUNDARY_MARGIN = 10.0;  // meter back

string DOCKER = "Dock";    //object name of the docker
float RANGE = 95.0;            //0.0 - 95.0 meter search scope
float SENS_ANGLE = 30.0;        //0.0 - 180.0 degree from X-axis
vector DOCKING_POS = <0.0, 3.0, 0.0>; // x, y, z meter from center of docker root prim
float DOCKER_WIDTH = 8.0;    // meter
integer DOCKER_REVERSIBLE = TRUE;  // DOCKING_POS can be reverted

// link messages
list SPIN_LIST = [ 0, 1, 2, 3, 4];
string ENGINE_KEYWORD = "engine";
string LIGHT_KEYWORD = "light";
string SPLASH_KEYWORD = "splash";
string BUBBLE_KEYWORD = "bubble";
string WHEEL_KEYWORD = "wheel";
string SMOKE_KEYWORD = "smoke";
string MESSAGE_KEYWORD = "message";

integer org_prims = 0;
integer passengers = 0;
key agent = NULL_KEY;
key pilot = NULL_KEY;
integer last_power = 0;
string last_engine_sound = "";
integer last_spin = 0;
integer rez_param = 0;
integer region_limit = 0;
float border;
float distance;
float d;
integer break;
string org_region = "";
integer abcent_count = 0;
integer crossing_count = 0;
//integer locking_count = 0;
integer alerm_count = 0;
//vector now_pos;
//vector last_pos = ZERO_VECTOR;
//vector valid_pos = ZERO_VECTOR;
vector next_pos;
vector start_pos;
//float last_span = 0.0;
integer last_level = 0;
integer forward = 0;    // X direction
integer slider = 0;      // Y
integer upward = 0;    // Z
integer leftward = 0;    // turn anti-clockwise
vector last_velocity = ZERO_VECTOR;
vector last_euler = ZERO_VECTOR;
//float drive_level;
float altitude = 0.0;
integer splashing = FALSE;
integer bubbling = FALSE;
integer smoking = FALSE;
integer docker_found;
vector docker_pos;
rotation docker_rot;
vector docking_target;
rotation target_rot;
float docking_start_distance;
integer auto_docking = FALSE;
integer dock_ready = FALSE;
integer docker_noting= FALSE;
integer onland = FALSE;
integer away = FALSE;
vector root_scale;
float root_height = 0.0;

debug(string msg)
{
    if (DEBUG) llOwnerSay(msg);
}

message(key avatar, string msg)
{
    if (msg != "" ) llMessageLinked(LINK_SET, 0, MESSAGE_KEYWORD + " " + msg, avatar);
}

watch()
{
    if ( crossing_count > 0 )
    {
        wait_crossing();
        move(CROSS_DECAY*last_velocity, CROSS_DECAY*last_euler);
        return;
    }
    vector now_pos = llGetPos();
    rotation now_rot = llGetRot();
    rotation h_rot = horizontal_rotation(now_rot);
    vector vel = last_velocity;
    integer power = last_power;
    integer keying = ( upward != 0 ) || (leftward != 0) || (slider != 0 );
    //vector offset = INTERVAL*vel*h_rot;
    //next_pos = now_pos + offset;
    float z = now_pos.z - 0.5*root_height;
    float w = llWater(ZERO_VECTOR);
    altitude = now_pos.z - landing_level(now_pos);
    if (altitude > FLIGHT_LEVEL+ BASE_SPEED.z)
    {
        if (onland)
        {
            attention();
            llSay(0, TAKE_OFF);
            message(pilot, CONTROL);
        }
        onland = FALSE;
        docker_noting = TRUE;
        if (last_power > 2 ) wheel(FALSE);
    }
    else if ((!auto_docking) && (!onland) && (altitude < BASE_SPEED.z))
    {
        if (!SUBMARINE || llGround(ZERO_VECTOR) > llWater(ZERO_VECTOR))
        {
            landed();
            return;
        }
    }
    else if ( TOOLOW_SOUND != "" && (!onland) && alerm_count == 0 && last_power > 2 && altitude < FLIGHT_LEVEL)
    {
        llTriggerSound(TOOLOW_SOUND, 1.0);
        if ( INTERVAL < 1.0 ) alerm_count = llCeil(1.0/INTERVAL);
    }
    if ( alerm_count > 0 ) --alerm_count;
    float distance = llVecMag(start_pos - now_pos);
    if ( distance > 2.0*BASE_SPEED.x )
    {
        if (!away)
        {
            debug("Away.");
        }
        away = TRUE;
    }
    integer last_status = dock_ready;
    if (docker_found)  distance = llVecMag(docker_pos - now_pos);
    dock_ready = (docker_found && away && (!onland) && (!auto_docking) && distance < RANGE && llVecMag(docker_pos - next_pos ) < distance  && upward <= 0 );
    if (docker_noting)
    {
        if ((!last_status && dock_ready))
        {
            message(pilot, DOCKER + " found. Press [Page Down] to land.");
            attention();
        }
        else if ( last_status && (!dock_ready) && (!auto_docking)) message(pilot, DOCKER + " lost.");
    }
    if ( dock_ready && (last_power < 3)  )
    {
        auto_docking = TRUE;
        message(pilot, "Auto-docking.");
        get_docking_target();
        distance = llVecMag(docking_target - now_pos);
        docking_start_distance = distance;
    }
    if (auto_docking)
    {
        distance = llVecMag(docking_target - now_pos);
        if (!docker_found) auto_docking = FALSE;
        else if (upward > 0) auto_docking = FALSE;
        else if (last_power > 2 ) docking_FALSE;
        else if ( keying && (llVecMag(docking_target - next_pos ) > distance) ) auto_docking = FALSE;
        if (!auto_docking) message (pilot, "Auto-docking canceled.");
    }
    if (auto_docking)
    {
        if (llVecMag(docking_target - now_pos) > 2.0*RANGE)
        {
            message(pilot, "Auto-docking canceled because the target is too far.");
            auto_docking = FALSE;
        }
    }
    if ( auto_docking && llVecMag(docking_target - now_pos) < INTERVAL*BASE_SPEED.x )
    {
        docked();
        return;
    }
    if (auto_docking)
    {
        h_rot = horizontal_rotation(llGetRot());
        vector arrow = docking_target - now_pos;
        distance = llVecMag(arrow);
        float rate = 1.0 - distance/(docking_start_distance + 0.0*RANGE);
        arrow = llVecNorm(arrow)/llGetRot();
        last_euler = ANGULAR_DECAY*last_euler;
        last_euler.y = -RAD_TO_DEG*4.0*rate*(1.0 - rate)*llAtan2(arrow.z, arrow.x);
        //debug("euler.y=" + (string)last_euler.y + " deg");
        arrow = llVecNorm((1.0 - rate)*<1.0, 0.0, 0.0> + (rate + 0.0)*arrow);
        vel = BASE_SPEED.x*(2.0 -rate)*arrow;
        rotation rot = target_rot/h_rot;
        float angle = llRot2Angle(rot);
        vector axis = llRot2Axis(rot);
        if (axis.z < 0.0) angle = -angle;
        rate = rate*rate;
        angle = rate*angle + (1.0 -rate)*llAtan2(arrow.y, arrow.x);
        last_euler.z = RAD_TO_DEG*angle;
        move(vel, last_euler);
    }
    else
    {
        if ( llAvatarOnSitTarget() != NULL_KEY ) abcent_count = 0;
        else if ( ++abcent_count > ABCENT_TIMEOUT )
        {
            llSay(0, "Pilot abcent.");
            shutdown();
            return;
        }
        if ( away && (!onland) && DOCKER != "" && RANGE > 0.1 ) sens();
       
        power = llAbs(forward);
        if (power > 0 || last_power > 0 ) power += 1;
        if ( power != last_power )
        {
            if (onland)
            {
                if ( power == 2 ) message(pilot, MORE_POWER);
                else if (power > 2) message(pilot, HEAD_UP);
            }
            if (power == 1 ) message(pilot, "Idling.");
            else if (power < last_power && power == 2 && (!onland) ) message(pilot, "Falling down.");
            //else if ( power == MAX_FORWARD + 1 ) message(pilot, "Full power.");
            if ( power != last_power) show_power(power);
            engine_power(power);
        }

        if (power)
        {
            vel = LINIAR_DECAY*last_velocity;
            vel.x = BASE_SPEED.x*forward;
            if (power == 2 && now_pos.z > landing_level(now_pos) + 0.5*BASE_SPEED.z) vel.z = -BASE_SPEED.z;
            last_euler = get_euler(vel);
            if (last_power > 1) move(vel, last_euler);
        }
    }
    if ( power > 0 && ( z < w ) && ( z > w + SINK_LEVEL) )
    {
        if (!splashing)
        {
                splash(TRUE);
                bubble(FALSE);
                //upward = 0;
                //last_velocity.z = landing_level(ZERO_VECTOR) - now_pos.z;
        }
    }
    else if (splashing) splash(FALSE);
    if ( z < w + SINK_LEVEL ) { if (!bubbling) bubble(TRUE); }
    else if (bubbling) bubble(FALSE);
    //last_pos = now_pos;
    clear_key();
}

show_power(integer p)
{
    if ( p > 1 && p <= MAX_FORWARD + 1 ) llSay(0, "Power: " + (string)(p - 1));
}

sens()
{
    llSensor(DOCKER, NULL_KEY, PASSIVE|SCRIPTED, RANGE, PI);
}

get_docking_target()
{
    target_rot = horizontal_rotation(docker_rot);

    docking_target = DOCKING_POS;
    if ( DOCKING_POS.x > 0.01 ) docking_target.x += 0.5*root_scale.x;
    else if ( DOCKING_POS.x < -0.01 ) docking_target.x -= 0.5*root_scale.x;
    if ( DOCKING_POS.y > 0.01 ) docking_target.y += 0.5*root_scale.y;
    else if ( DOCKING_POS.y < -0.01 ) docking_target.y -= 0.5*root_scale.y;
    if ( DOCKING_POS.z > 0.01 ) docking_target.z += 0.5*root_scale.z;
    else if ( DOCKING_POS.z < -0.01 ) docking_target.z -= 0.5*root_scale.z;
    //else docking_target.z = landing_level(docking_target);
    vector arrow = docker_pos - llGetPos();
    arrow = arrow/target_rot; 
    if (DOCKER_REVERSIBLE && arrow.x < 0.0)
    {
        docking_target = docker_pos + <-docking_target.x, docking_target.y, docking_target.z>*target_rot;
        target_rot = target_rot*llAxisAngle2Rot(<0.0, 0.0, 1.0>, PI);
    }
    else docking_target = docker_pos + docking_target*target_rot;
    if ( llFabs(DOCKING_POS.z) < 0.01 ) docking_target.z = landing_level(docking_target);
    docking_target = adjust_height(docking_target);
    debug("Docking target=" + (string)docking_target);
}

docked()
{
    llSay(0, "Nice landing.");
    llSleep(2.0*INTERVAL);
    vector pos = docking_target;
    rotation rot = target_rot;
    llSetPos(pos);
    llSetRot(rot);
    engine_power(0);
    away = FALSE;
    auto_docking = FALSE;
    docker_noting = FALSE;
    init_key();
    start_point();
    //onland = llGround(ZERO_VECTOR) > llWater(ZERO_VECTOR);
    onland = pos.z < landing_level(pos) + BASE_SPEED.x;
    if ( llAvatarOnSitTarget() == NULL_KEY )
    {
        unsit();
        shutdown();
    }
    else if (onland && (!BOAT)) message(pilot, LAUNCH);
    else message(pilot, CONTROL);
}

landed()
{
    llSay(0, "Landed.");
    vector pos = llGetPos() + last_velocity*llGetRot();
    rotation rot = horizontal_rotation(llGetRot());
    pos.z = landing_level(pos);
    llSetKeyframedMotion( [pos - llGetPos(), rot/llGetRot(), 2.0*INTERVAL], []);
    llSleep(2.0*INTERVAL);
    llSetPos(pos);
    llSetRot(rot);
    engine_power(0);
    llSetPos(pos);
    llSetRot(rot);
    onland = TRUE;
    away = FALSE;
    auto_docking = FALSE;
    init_key();
    start_point();
    if ( llAvatarOnSitTarget() == NULL_KEY )
    {
        unsit();
        shutdown();
    }
    else message(pilot, LAUNCH);
}

cross_region()
{
    if ( CROSSING_MOMENT> 0.01 ) llSleep(CROSSING_MOMENT);
    llWhisper(0, "Crossing regions.");
    //llSetStatus(STATUS_PHYSICS, FALSE);
    //correct_position();
    crossing_count = CROSSING_TIMEOUT;
}

wait_crossing()
{
    //if ( llGetNumberOfPrims() >= org_prims + passengers )
    key agent = llAvatarOnSitTarget();
    if ( agent != NULL_KEY )
    {
        crossing_count = 0;
        llSleep(CROSSING_MOMENT);
        //llSetStatus(STATUS_PHYSICS, TRUE);
        //key agent = llAvatarOnSitTarget();
        //if ( agent != NULL_KEY )
        //{
            pilot = agent;
            integer request = 0;
            if ( llGetPermissions() & PERMISSION_TAKE_CONTROLS) take_key();
            else request = PERMISSION_TAKE_CONTROLS;
            //if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION )
            //llStartAnimation(gDrivingAnim);
            //else request = request | PERMISSION_TRIGGER_ANIMATION;
            if (request) llRequestPermissions(agent, request);
        //}
        llWhisper(0, "Crossing regions completed.");   
    }
    else if ( --crossing_count <= 0 )
    {
        llWhisper(0, "Crossing timeout.");
        crossing_count = 0;
        if (forward > 1) forward = 1;
        //unsit();
        //shutdown();
    }
}

vector get_euler(vector vel)
{
    vector euler = ZERO_VECTOR;
    float rate;
    if (upward)
    {
        rate = MAX_PITCH/(float)(UPSTEP*MAX_UPWARD);
        euler.y = -rate*(float)upward;
    }
    if (slider && (!onland) )
    {
        vel.y += BASE_SPEED.y*(float)slider;
        euler.x = -MAX_ROLL*(float)slider/(float)MAX_SLIDER;
    }
    if (leftward)
    {
        rate = MAX_YAW/(float)(LEFTSTEP*MAX_LEFTWARD);
        if (onland) rate = (0.1 + 0.2*llAbs(forward))*rate;
        euler.z = rate*(float)leftward;
        //debug("Ledtward = " + (string)leftward);
        rate = MAX_ROLL;
        if (onland) rate = MAX_ROLL_GROUND;
        euler.x = -rate*(0.5*(float)llAbs(forward)/(float)MAX_FORWARD + 0.5)*(float)leftward/(float)(LEFTSTEP*MAX_LEFTWARD);
    }
    return euler;
}

read_key(integer level, integer edge)
{
    integer go = FALSE;
    vector vel = last_velocity;
    vector euler = last_euler;
    integer up = FALSE;
    integer down = FALSE;
    integer fwd = FALSE;
    integer back = FALSE;
    integer rot_l = FALSE;
    integer rot_r = FALSE;
    integer left = FALSE;
    integer right = FALSE;
    integer max;
    integer min;
    integer step;
    float rate;

    if ( edge & level & CONTROL_UP) up = TRUE;
    if ( edge & level & CONTROL_DOWN) down = TRUE;
    if (up && down) upward = 0;
    else if (up)
    {
        max = MAX_FORWARD;
        if ( forward >= max ) llSay(0, "Full power");
        if (onland)
        {
            max = 2;
            if ( forward >= max ) llSay(0, HEAD_UP);
        }
        if (forward < max) ++forward;
    }
    else if (down)
    {
        min = 1;
        if (onland) min = -1;     
        if (forward > min) --forward;
    }

    if ( (last_level & CONTROL_FWD) == 0 && level & CONTROL_FWD) fwd = TRUE;
    if ( (last_level & CONTROL_BACK) == 0 && level & CONTROL_BACK) back = TRUE;
    max = UPSTEP*MAX_UPWARD;
    min = UPSTEP*-MAX_UPWARD;
    step = llAbs(upward)*UPSTEP/MAX_UPWARD + 1;
    if (step > UPSTEP) step = UPSTEP;
    if (onland)
    {
        if (last_power < 3) max = 0;
        else max = llCeil((float)(UPSTEP*MAX_UPWARD)*MAX_PITCH_GROUND/MAX_PITCH);
        min = 0;
    }
    //if (fwd && back) forward = 0;
    //else
    if (back)
    {
        //debug("Step=" + (string)step + ", Max upward = " + (string)max);
        //if (upward < 0) upward = 0;
        if (upward < max) upward += step;
        else if (MAX_PITCH > 179.0 && (!onland)) upward = min + step;
        go = TRUE;
        //debug("Upward="+ (string)upward);
    }
    else if (fwd)
    {
        //if (upward > 0) upward = 0;
        if (upward > min) upward -= step;
        else if (MAX_PITCH > 179.0 && (!onland)) upward = max - step;
        go = TRUE;
    }

    if ( (last_level & CONTROL_LEFT) == 0 && level & CONTROL_LEFT) left = TRUE;
    if ( (last_level & CONTROL_RIGHT) == 0 && level & CONTROL_RIGHT) right = TRUE;
    if (left && right) slider = 0;
    else if (left)
    {
        if (slider < 0) slider = 0;
        if (slider < MAX_SLIDER) ++slider;
        go = TRUE;
    }
    else if (right)
    {
        if (slider > 0) slider = 0;
        if (slider > -MAX_SLIDER) --slider;
        go = TRUE;
    }

    if ( (last_level & CONTROL_ROT_LEFT) == 0 && level & CONTROL_ROT_LEFT) rot_l = TRUE;
    if ( (last_level & CONTROL_ROT_RIGHT) == 0 && level & CONTROL_ROT_RIGHT) rot_r = TRUE;
    max = LEFTSTEP*MAX_LEFTWARD;
    min = -max;
    step = llAbs(leftward)*LEFTSTEP/MAX_LEFTWARD + 1;
    if (step > LEFTSTEP) step = LEFTSTEP;
    if (rot_l && rot_r) leftward = 0;
    else if (rot_l)
    {
        if (leftward < 0) leftward = 0;
        if (leftward < max) leftward += step;
        go = TRUE;
    }
    else if (rot_r)
    {
        if (leftward > 0) leftward = 0;
        if (leftward > min) leftward -= step;
        go = TRUE;
    }

    if (go)
    {
        euler = get_euler(vel);
        move(vel, euler);
    }
    last_level = level;
}

clear_key()
{
    if ( upward > 0 &&  (last_level & CONTROL_BACK) == 0 ) --upward;
    if ( upward < 0 &&  (last_level & CONTROL_FWD) == 0 ) ++upward;
    //if ( forward > 0 &&  (last_level & CONTROL_FWD) == 0 ) --forward;
    //if ( forward < 0 &&  (last_level & CONTROL_BACK) == 0 ) ++forward;
    if ( slider > 0 &&  (last_level & CONTROL_LEFT) == 0 ) --slider;
    if ( slider < 0 &&  (last_level & CONTROL_RIGHT) == 0 ) ++slider;
    if ( leftward > 0 &&  (last_level & CONTROL_ROT_LEFT) == 0 ) --leftward;
    if ( leftward < 0 &&  (last_level & CONTROL_ROT_RIGHT) == 0 ) ++leftward;
    last_level = 0;
}

init_key()
{
    upward = 0;
    forward = 0;
    slider = 0;
    leftward = 0;
    last_level = 0;
}

take_key()
{
      llTakeControls(
            CONTROL_RIGHT | CONTROL_ROT_RIGHT |
            CONTROL_LEFT | CONTROL_ROT_LEFT |
            CONTROL_FWD | CONTROL_DOWN |
            CONTROL_BACK | CONTROL_UP,
            TRUE, FALSE
    );
    clear_key();
}

move(vector vel, vector euler)
{
    if (splashing) vel = WAVE_DRAG*vel;
    vel = 2.0*INTERVAL*LINIAR_RISE*vel + (1.0 - LINIAR_RISE)*last_velocity;
    //if (upward) debug("Euler=" + (string)euler);
    //euler = 2.0*INTERVAL*ANGULAR_RISE*euler + (1.0 - ANGULAR_RISE)*last_euler;
    //if (upward) debug("Euler=" + (string)euler);
    vector now_pos = llGetPos();
    rotation now_rot = llGetRot();
    rotation h_rot = horizontal_rotation(now_rot);
    vector offset = INTERVAL*vel*now_rot;
    next_pos = now_pos + offset;
    float MARGIN = 0.1;
    if (region_limit)
    {
        if ( next_pos.x < MARGIN || next_pos.x > border - MARGIN || next_pos.y < MARGIN || next_pos.y > border - MARGIN )
        {
            debug("Next posision:" + (string)next_pos + " beyond region border(" + (string)border + ")." );
            vel = ZERO_VECTOR;
            offset = ZERO_VECTOR;
        }
    }
    else if ( BOAT && (!auto_docking) )
    {
        if ( (llGround(offset) + GROUND_LEVEL > llWater(offset) + FLOAT_LEVEL ) && (llGround(offset) > llGround(ZERO_VECTOR)) )
        {
            vel = ZERO_VECTOR;
            offset = ZERO_VECTOR;
        }
    }
    next_pos = now_pos + offset;
    next_pos = adjust_height(next_pos);
    rotation x_rot = llAxisAngle2Rot(<1.0, 0.0, 0.0>, DEG_TO_RAD*euler.x);
    rotation next_rot = x_rot*llAxisAngle2Rot(<0.0, 1.0, 0.0>*x_rot, DEG_TO_RAD*euler.y);
    next_rot = next_rot*llAxisAngle2Rot(<0.0, 0.0, 1.0>, DEG_TO_RAD*euler.z)*h_rot;
    //if (upward) debug("Euler, next euler=" + (string)euler + ", "+ (string)(RAD_TO_DEG*llRot2Euler(next_rot)));
    llSetKeyframedMotion( [next_pos - now_pos, next_rot/now_rot, 2.0*INTERVAL], []);
    last_velocity = vel;
    last_euler = euler;
}

engine_power(integer power)
{
    if (power != last_power) debug("Engine power = " + (string)power);
    if (power > 2 && (!onland)) wheel(FALSE);
    else wheel(TRUE);
    if (power <= 0)
    {
        engine_sound(0);
        if (last_power > 0)
        {
            if ( llGetInventoryKey(STOP_SOUND) != NULL_KEY )
            {
                spin(1);
                llTriggerSound(STOP_SOUND, 1.0);
                llSleep(STOP_MOMENT);
            }
            else if (STOP_SOUND != "") llOwnerSay("Sound '" + STOP_SOUND + " not found.");

        }
        spin(0);
        splash(FALSE);
        bubble(FALSE);
        wheel(TRUE);
        last_velocity = ZERO_VECTOR;
        last_euler = ZERO_VECTOR;
    }
    else
    {
        if (last_power <= 0)
        {
            if ( llGetInventoryKey(START_SOUND) != NULL_KEY )
            {
                spin(1);
                llTriggerSound(START_SOUND, 1.0);
                llSleep(START_MOMENT);
            }
            else if (START_SOUND != "") llOwnerSay("Sound '" + START_SOUND + " not found.");
        }
        if (power != last_power)
        {
            spin(power);
            if (power < 2) splash(FALSE);
            engine_sound(power);
        }
    }
    last_power = power;
}

engine_sound(integer gear)
{
    integer max = llGetListLength(ENGINE_SOUNDS) - 1;
    if (gear > max) gear = max;
    string sound = llList2String(ENGINE_SOUNDS, gear);
    if (sound == "")
    {
        llStopSound();
    }
    else if ( sound != last_engine_sound)
    {
        llStopSound();
        if (llGetInventoryKey(sound) == NULL_KEY)
        {
            llOwnerSay("Sound '" + sound + "' not found.");
            return;
        }
        float vol = 1.0;
        if (gear <= 0 ) vol = 0.0;
        llLoopSound(sound, vol);
    }
    last_engine_sound = sound;
}

spin(integer gear)
{
    integer max = llGetListLength(SPIN_LIST) - 1;
    if (gear > max) gear = max;
    integer spin = llList2Integer(SPIN_LIST, gear);
    if (spin == 0 || spin != last_spin) llMessageLinked(LINK_SET, spin, ENGINE_KEYWORD, NULL_KEY);
    last_spin = spin;
}

splash(integer onoff)
{
    llMessageLinked(LINK_SET, onoff, SPLASH_KEYWORD, NULL_KEY);
    splashing = onoff;
}


bubble(integer onoff)
{
    llMessageLinked(LINK_SET, onoff, BUBBLE_KEYWORD, NULL_KEY);
    bubbling = onoff;
}

light(integer onoff)
{
    llMessageLinked(LINK_SET, onoff, LIGHT_KEYWORD, NULL_KEY);
}

wheel(integer onoff)
{
    llMessageLinked(LINK_SET, onoff, WHEEL_KEYWORD, NULL_KEY);
}

smoke(integer onoff)
{
    llMessageLinked(LINK_SET, onoff, SMOKE_KEYWORD, NULL_KEY);
    smoking = onoff;
}

start_point()
{
        if ( org_region == "" ) org_region = llGetRegionName();
        start_pos = llGetPos();
        //drive_level = start_pos.z;
        //last_pos = llGetPos();
        //valid_pos = last_pos;
        //last_span = 0.0;
}

attention()
{
    if (NOTE_SOUND == "") return;
    llTriggerSound(NOTE_SOUND, 1.0);
    //if (wait) llSleep(0.5);
}

unsit()
{
    key agent = llAvatarOnSitTarget();
    if (agent) { llUnSit(agent); }
    llMessageLinked(LINK_SET,0,"unsit", NULL_KEY);
    llSleep(1.0);
}

vector horizont(vector v)
{
    v.z = 0.0;
    return v;
}

float landing_level(vector pos)
{
    vector offset = pos - llGetPos();
    float g = llGround(offset);
    if (docker_found && DOCKING_POS.z > 0.01)
    {
        vector arrow = docker_pos - llGetPos();
        float distance = llVecMag(arrow);
        if ( distance < RANGE)
        {
            if ( distance > 0.5*DOCKER_WIDTH )
            {
                //arrow = llVecNorm(arrow);
                distance = distance*llFabs(llSin(llAtan2(arrow.y, arrow.x) - llRot2Angle(docker_rot)));
            }
            if ( distance < 0.5*DOCKER_WIDTH ) g = docker_pos.z + DOCKING_POS.z;
        }
    }
    float z = g + 0.5*root_height + GROUND_LEVEL;
    float w = llWater(offset) + 0.5*root_height + FLOAT_LEVEL;
    if ( w > z ) z = w;
    return z;
}

vector adjust_height(vector p)
{
    vector offset = p - llGetPos();
    float z = landing_level(p);
    if (BOAT && p.z > z ) p.z = z;
    if (SUBMARINE) z = llGround(offset) + 0.5*root_height + GROUND_LEVEL;
    if ( p.z < z ) p.z = z;
    return p;
}

rotation horizontal_rotation(rotation rot)
{
    vector roll = llRot2Euler(rot);  //(llGetRot()/STD_ROT);
    roll.x = 0.0; roll.y = 0.0;
    rot = llEuler2Rot(roll);  //STD_ROT*llEuler2Rot(roll);
    return rot;
}

correct_position()
{
    vector pos = llGetPos();
    debug("Correcting position. Landing level=" + (string)landing_level(pos));
    pos = adjust_height(pos);
    rotation rot = horizontal_rotation(llGetRot());
    llSetStatus(STATUS_PHYSICS, FALSE);
    llSetPos(pos);
    llSetRot(rot);
}

initialize()
{
    root_scale = llGetScale();
    root_height = root_scale.z;
    unsit();
    org_prims = llGetNumberOfPrims();
    org_region = "";
    hot_start();
}
hot_start()
{
    shutdown();
    sens();
    start_point();
    passengers = 0;
    pilot = NULL_KEY;
    agent = NULL_KEY;
    docker_noting = FALSE;
    crossing_count = 0;
    //locking_count = 0;
    init_key();
}

shutdown()
{
    llSetTimerEvent(0);
    engine_power(0);
    light(FALSE);
    wheel(TRUE);
    smoke(FALSE);
    //move(ZERO_VECTOR);
    //llSetStatus(STATUS_PHYSICS, FALSE);
    llStopSound();
    llReleaseControls();
    //llReleaseCamera(last_pilot);
}

limit2border()
{
    border = (float)region_limit;
    if (region_limit <= 0) return;
    vector pos = llGetPos();
    float size = pos.x;
    if (pos.y > size) size = pos.y;
    if (size > border)
    {
        region_limit = 256*(llCeil(size + 256.0)/256);
        border = (float)region_limit;
    }
    llSay(0,"Movement limited by " + (string)region_limit + "x" + (string)region_limit);
}

default
{
    state_entry()
    {
        llOwnerSay(llGetScriptName() +  " reset.");
        //comment: not essencial but precaution to avoid passengers be confined in the cabin
        llSetLinkPrimitiveParamsFast(LINK_ALL_CHILDREN, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_NONE]);
        region_limit = REGION_SIZE;
        limit2border();
        initialize();
        correct_position();   
    }
   
    on_rez(integer param)
    {
        debug("Rezzed with parameter: " + (string)param);
        if ( param == 0 ) llResetScript();
        rez_param = param;
        //disposal = TRUE;
        region_limit = 256;
        if (param > 0 && param%256 == 0) region_limit = param;
        limit2border();
        shutdown();
        correct_position();
        org_region = "";
        hot_start();
    }

    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            integer deny = FALSE;
            key last_agent = agent;
            agent = llAvatarOnSitTarget();
            //integer last_passengers = passengers;
            integer prims = llGetNumberOfPrims();
            integer last_passengers = passengers;
            passengers = prims - org_prims;
            if (passengers < 0 )
            {
                org_prims = prims;
                passengers = 0;
            }
            else if ( agent != NULL_KEY && last_agent == NULL_KEY )
            {
                if (OWNER_ONLY && agent != llGetOwner() )
                {
                    message(agent, DENY);
                    llSleep(1.0);
                    unsit();
                }
                else
                {
                    pilot = agent;
                    //message(pilot, WELCOME);
                    light(TRUE);
                    integer perm = PERMISSION_TAKE_CONTROLS;
                    //perm = perm | PERMISSION_CONTROL_CAMERA;
                    llRequestPermissions(pilot, perm);
                    sens();
                    engine_power(1);    //idel
                    start_point();
                    away = FALSE;
                    llSetTimerEvent(INTERVAL);
                }
            }
            else if ( agent == NULL_KEY )
            {
                if (last_agent != NULL_KEY && last_agent == pilot)
                {
                    //llWhisper(0, GOODBYE);
                    unsit();
                }
                if ( passengers > last_passengers) llWhisper(0, ANOTHER_WELCOME);
                pilot = NULL_KEY;
                if ( passengers <= 0 )
                {
                    hot_start();
                }
            }
        }
        if (change & CHANGED_REGION)
        {
            if (passengers > 0) cross_region();
            else if  ( llGetRegionName() == org_region )
            {
                shutdown();
                if (rez_param == 0 ) llResetScript();
            }
        }
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TAKE_CONTROLS) {
            take_key();
            vector now_pos = llGetPos();
            //onland = llGround(ZERO_VECTOR) > llWater(ZERO_VECTOR);
            onland = now_pos.z < landing_level(now_pos) + BASE_SPEED.x;
            if (onland && (!BOAT)) message(pilot, LAUNCH);
            else message(pilot, CONTROL);
            attention();
        }
    }

    control(key id, integer level, integer edge)
    {
        read_key(level, edge);
    }

    touch_start(integer num)
    {
        key agent = llDetectedKey(0);
        if (pilot == NULL_KEY)
        {
            if (agent == llGetOwner()) llResetScript(); //correct_position();
        }
      /*
        else if ( agent == pilot )
        {
            toggle_camera();
            message(pilot, RETOUCH);
        }
        */
    }

    timer()
    {
        watch();
    }

    sensor(integer num)
    {
        integer i;
        vector pos;
        vector now_pos = llGetPos();
        vector arrow;
        float x = llCos(DEG_TO_RAD*SENS_ANGLE);
        distance = 2.0*RANGE;
        integer found = FALSE;
        for (i = 0; i < num; ++i)
        {
            pos = llDetectedPos(i);
            arrow = llVecNorm(pos - llGetPos())/llGetRot();
            if ( arrow.x > x )
            {
                if ( pos.z < now_pos.z && llVecMag(pos - now_pos) < distance)
                {                                                                 
                    docker_pos = pos;
                    docker_rot = llDetectedRot(i);
                    distance = llVecMag(pos - now_pos);
                    found = TRUE;
                }
            }
        }
        docker_found = found;
    }

    no_sensor()
    {
        docker_found = FALSE;
        docker_noting = TRUE;
    }
}


Angehängte Dateien Bild(er)
       
Mein Zuhause ist hier:
decadence.ddns.net:8002:big city life
decadence.ddns.net:8002:decadence
Zitieren
#6
Hallo Cheryl,

wozu physisch? Wenn ich das richtig verstehe, willst du irgendwo einsteigen und irgendwo hinfliegen?
Zitieren
#7
genau. Hinten in das Shuttle rein laufen und dann Platz nehmen. Und wenn man aufsteht nicht durchfallen.
Mein Zuhause ist hier:
decadence.ddns.net:8002:big city life
decadence.ddns.net:8002:decadence
Zitieren
#8
Hallo Cheryl,

das sollte mit keyframe gehen

Siehe Wiki
https://wiki.secondlife.com/wiki/LlSetKeyframedMotion

Physisch ist auch nicht das Thema
llSetPrimitiveParams([PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);

Und mit dem AvSitter hätte ich Dir auch zeigen können, wie Du Flugziele definierst über das AvSitter Menü. Aber AvSitter hast Du ja verbannt, wie ich gelesen habe

Grüße
Zitieren
#9
Hallo Dark

Ich habs jetzt Jimmy gezeigt. Mit dem AVsitter script geht es ganz fix in den Himmel. Ist aber kompliziert eine Route zu setzen, damit es gut aussieht und man richtig fliegt mit Shuttle. Ich nehme dann doch besser das Route script, was ich für Autos, Schiffe, Flugzeuge, Animesh Leute nutze. Mit Lego Plattformen um nicht durchzufallen, wenn ich aussteige ist dann unkomplizierter. Ist einfach und stabil gemacht. Das Script ist auch das stabilste was ich überhaupt habe und macht keine Zicken.

Ich schaue aber weiter nach, ob es für meinen Engine (oben kopiert) eine Lösung gibt, damit man selbst fliegen kann und dabei auch ins Shuttle laufen kann um sich zu setzen und nicht beim Aussteigen durch den Boden fällt. Dieser Engine scheint mir für Shuttle Flüge nämlich sehr realistisch zu sein und hat tolle Eigenschaften. Ich habe diesen Engine in einem Wasserflugzeug gefunden, was auch gut funktioniert, aber ich finde für ein Shuttle wie den Deltaflyer wirkt es viel besser vom physikalischen Verhalten im Flug. Es hat nur das Manko, dass es das Mesh Objekt Phantom macht. Das sollte irgendwie gelöst werden, damit man von hinten über die Rampe rein laufen kann und wenn man aufsteht nicht durch den Boden fällt.
Mein Zuhause ist hier:
decadence.ddns.net:8002:big city life
decadence.ddns.net:8002:decadence
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste