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)