Capricorn 76
Terrain example.
ScriptENGINE can model terrains in the graphics and physics engines.
Terrains a modelled using a heightmap: a 2D image (usually grayscale)
that defines the terrain height (lighter colors define higher terrain).

Terrains have a lot of parameters, to control
both their rendering optimisation and texturing.

---------------------------
---------------------------
-- Terrain example
-- Copyright (c) 2007-09 Capricorn 76 Pty. Ltd.
--
-- ScriptENGINE can model terrains in the graphics and physics engines.
-- Terrains a modelled using a heightmap: a 2D image (usually grayscale)
-- that defines the terrain height (lighter colors define higher terrain).
--
-- Terrains have a lot of parameters, to control
-- both their rendering optimisation and texturing.
-- The terrain's level-of-detail (LOD) determines how detailed the terrain
-- is rendered and physically simulated.
-- The terrain renderer uses a CLOD algorithm, and it recalculates
-- the terrain indices as the viewing camera rotates/moves.
-- These recalculation parameters can also be optimise for best performance.
--
-- NOTE:
-- The ./Demos/runDemo.e76script is a utility script used to run all the examples.
-- It loads the world, calls the OnWorldLoad(), OnWorldUnload() functions, and runs the graphics engine loop, waiting for the user to press escape.
---------------------------
---------------------------

local subMouseButton;


---------------------------
-- runDemo.e76script calls this function when the world is loaded
---------------------------
function OnWorldLoad(worldName)
    --print('OnWorldLoad');

    ---------------------------
    -- The SDK world editor creates a worldIds.e76script when the world is saved. It contains all the entity ids.
    -- We load the IDs so that we can refer to the world entities using friendly names.
    ---------------------------
    IApp:loadScript(IWorld:getNameLong() .. '/worldIds');

    ---------------------------
    -- Change the global variable defined in the runDemo.e76script
    -- We can turn off the back buffer because the entire screen is redrawn each frame by either the terrain or skybox.
    -- This will increase performance, since the back buffer is never seen.
    ---------------------------
    graphicsBackBufferOff = true;

    ---------------------------
    -- Load example's GUI
    ---------------------------
    OnWorldLoadGui();

    ---------------------------
    -- Subscribe to events we're interested in.
    ---------------------------
    -- Want to handle mouse click
    subMouseButton = IEvents:subscribeMouseButton('OnMouseButton');

    ---------------------------
    -- As the camera moves, the terrain indices are recalculated internally by the graphics engine.
    -- This can take up heaps of CPU processing if done too often.
    -- These terrain rendering optimisations control how often the terrain indices are recalculated.
    -- Basically, we are saying that the indices should only be recalculated when these delta values are exceeded.
    -- That is, when the camera moves or rotates more than these specified thresholds...
    ---------------------------

    ---------------------------
    -- These optimisations are pretty severe in this example.
    -- So its obvious when the indices are being recalculated
    ---------------------------
    IWorld:setTerrainMovementDelta(idTerrain_terrain, 30);
    IWorld:setTerrainRotationDelta(idTerrain_terrain, 10);
    IWorld:setTerrainLODDistance(idTerrain_terrain, 3, 50);
    IWorld:setTerrainLODDistance(idTerrain_terrain, 4, 75);
    IWorld:setTerrainLODDistance(idTerrain_terrain, 5, 100);

    ---------------------------
    -- Change the terrain texture scales,
    -- just to show how its done from the scripts.
    ---------------------------
    IWorld:setTerrainTextureScales(idTerrain_terrain, 1, 10);

    ---------------------------
    -- Turn on auto camera management.
    -- The active camera will be moved based upon its type and mouse/key input.
    -- In this example, the active camera is an 'fps' or first-person-shooter' style.
    ---------------------------
    IWorld:setActiveCameraAutoProcessed(true);
end

---------------------------
-- Load this example's GUI
---------------------------
function OnWorldLoadGui()
    ---------------------------
    -- Let's show some help text
    ---------------------------
    IGraphics:loadGui('help');
end

---------------------------
-- runDemo.e76script calls this function when the world is unloaded
---------------------------
function OnWorldUnload(worldName)
    --print('OnWorldUnload');

    ---------------------------
    -- Unsubscribe to events.
    -- We will no longer be notified of events.
    ---------------------------
    IEvents:unsubscribe(subMouseButton);
end

------------------------
-- Handle mouse button event
------------------------
function OnMouseButton(eventType, mouseX, mouseY, mouseWheel, userData)
    ---------------------------
    -- Left button clicked?
    -- Fire a ball into the world
    ---------------------------
    if (IMouse:leftButtonClicked(eventType)) then

        -- Place the new ball where the camera is
        local cameraPos     = IWorld:getEntityPosition(IWorld:getActiveCameraId());

        -- Calculate a direction based upon where the mouse is on the screen
        local mouseDir      = IPhysics:rayCastMousePosition();
        if (mouseDir) then
            mouseDir    = mouseDir['intersection'];
        else
            mouseDir    = IWorld:getCameraLookAt(IWorld:getActiveCameraId());
        end

        -- Fire the ball in the direction we're looking
        local forceVector = IMisc:vectorSubtract(mouseDir, cameraPos);
        forceVector = IMisc:vectorNormaliseFast(forceVector);

        -- Place the ball just in front of the camera, otherwise the camera wll collide with it.
        local newBallPos        = IMisc:vectorAdd(cameraPos, IMisc:vectorMultiply(forceVector, 2));
        IWorld:setEntityPosition(idUnit_ball, newBallPos);

        -- Apply the impulse force to the ball
        forceVector = IMisc:vectorMultiply(forceVector, 1000);
        IPhysics:stopEntityMotion(idUnit_ball);
        IPhysics:addEntityImpulseForce(idUnit_ball, forceVector);

    end
end

Copyright © 2006-23 Sep 2009 Capricorn 76 Pty. Ltd. (created on Wed Sep 23 16:49:12 2009)