Capricorn 76
3D Animation example.
ScriptENGINE supports skeletal (eg X-files, B3D-files) and MD2 files.
Animations can be accessed by name, or by frame numbers.

---------------------------
---------------------------
-- 3D Animation example
-- Copyright (c) 2007-09 Capricorn 76 Pty. Ltd.
--
-- ScriptENGINE supports skeletal (eg X-files, B3D-files) and MD2 files.
-- Animations can be accessed by name, or by frame numbers.
--
-- 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 subTick;
local subAnim;

---------------------------
-- 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');
    IWorld:setActiveCameraId(idCamera_cam1);

    ---------------------------
    -- Load the GUI
    ---------------------------
    OnWorldLoadGui();

    ---------------------------
    -- Subscribe to the graphics engine 'tick' event.
    -- Our callback will be periodically fired by the graphics engine,
    -- so we can do some extra processing.
    --
    -- Could create a thread to manage this,
    -- but we're showing how this can be done from the graphics engine thread.
    --
    -- Note that you should do minimal processing this way,
    -- because the graphics can become jerky as the processing load increases.
    --
    -- The returned identifier is later used to unsubscribe.
    ---------------------------
    subTick = IEvents:subscribeTickPeriodic('OnRotateCube', 30);

    ---------------------------
    -- Set the agent's animation
    -- We want to know when the animation completes so we subscribe to the AnimationComplete event.
    -- The graphics engine will notify us when sherman's animation completes via the callback function.
    ---------------------------
    subAnim = IEvents:subscribeAnimationComplete('OnAnimComplete');
    IGraphics:setEntityAnimationEx(idAgent_Mech, 0, 14, false, 10);
end

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

    ---------------------------
    -- Create a label to show the animation loop number
    ---------------------------
    IGraphics:createText('agent', 'Agent', '0.8 0.9 0.98 0.95', true, false, true, '1 0 0 1');
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 the events.
    ---------------------------
    IEvents:unsubscribe(subTick);
    IEvents:unsubscribe(subAnim);
end

------------------------
-- Handle graphics tick event.
-- The graphics engine will periodically call this function.
------------------------
function OnRotateCube(currentTime, lastTime, isWindowActive, userData)

    ---------------------------
    -- Rotate the cube a little bit each tick.
    ---------------------------
    IWorld:manipulateEntity(idUnit_box, 'rotate', 0, 1, 1);

    ---------------------------
    -- The following shows an example
    -- of how we can perform line-of-sight calculations.
    -- Uncomment the following lines to see it in action.
    ---------------------------
--[[
    camPos = IWorld:getEntityPosition(IWorld:getActiveCameraId());
    tgtPos = IWorld:getCameraLookAt(IWorld:getActiveCameraId());
    dir = IMisc:vectorSubtract(tgtPos, camPos);
    dir = IMisc:vectorNormalise(dir);
    startPos    = IMisc:vectorAdd(camPos, IMisc:vectorMultiply(dir, 1));
    endPos      = IMisc:vectorAdd(camPos, IMisc:vectorMultiply(dir, 20));

    -- Can we see 10 units in front of us? Or is something in the way?
    if (not(IGraphics:isInLineOfSight(startPos, endPos))) then
        print('Out of line of sight:', startPos, endPos);
    end
]]

end

------------------------
-- Animation complete handler.
-- The graphics engine will call this function
-- whenever an animation completes.
-- We can check the entity id, and act accordingly.
------------------------
local animationLoop = 1;
function OnAnimComplete(entityId)
--  print('Animation complete for ' .. IWorld:getEntityName(entityId));
    IGraphics:setControlText('agent', 'Animation Loop ' .. animationLoop);
    animationLoop = animationLoop  + 1;

    -- Reset the animation to the starting frame
    IGraphics:setEntityAnimationEx(idAgent_Mech, 0, 14, false, 10);
end

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