--------------------------- --------------------------- -- Tutorial: Physics engine. Test 1 -- Starting up the physics engine. -- -- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd. --------------------------- --------------------------- --------------------------- --------------------------- -- PROGRAM STARTS HERE --------------------------- --------------------------- --------------------------- -- Initialise the graphics engine, using a software renderer. -- Then initialise the physics engine. --------------------------- local graphicsInitialised = IGraphics:init( 'SOFTWARE', -- Instead of using hard-coded strings, we could IApp:loadScript('constantsVideoDrivers.e76script') and use the pre-defined constants. 640, 480, -- Width/height false, -- Fullscreen 16, -- Bits/color depth false, -- Shadows false, -- Antialiasing false, -- VSync 30, -- Frame rate false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right local physicsInitialised = IPhysics:init( 1, -- Adaptive solver model 1, -- Adaptive friction model 0.5, -- Default static friction 0.4, -- Default dynamic friction 0, -- Min mass. Any entities with a mass < this are not simulated 1000, -- Max mass, Any entities with a mass > this are simulated as static bodies true, -- Optimise 3D meshes when loading 50, -- Physics frame rate. Should be as high as possible to give the physics engine plenty of samples when simulating collisions etc. false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right if (graphicsInitialised and physicsInitialised) then --------------------------- -- Run the app processing loop for 5 seconds --------------------------- IApp:run(5000); --------------------------- -- Close the engine, the window will close, and the program will terminate --------------------------- IPhysics:destroy(); IGraphics:destroy(); end
---------------------------
---------------------------
-- Tutorial: Physics engine. Test 2
-- Starting up the physics engine, create a box and give it mass.
--
-- Create a 3D camera, floor and box directly in script.
-- Normally, you would use the ScriptENGINE World Editor to create your 3D worlds, then use IWorld:load() to load them in.
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------
---------------------------
---------------------------
-- PROGRAM STARTS HERE
---------------------------
---------------------------
---------------------------
-- Initialise the graphics engine, using OPENGL.
-- If you try to use the software renderer, you'll find that the graphics engine is using a lot of CPU, which slows the physics.
-- So, only use software rendering when absolutely necessary, but always try to use hardware acceleration for the graphics.
-- Then initialise the physics engine.
---------------------------
local graphicsInitialised = IGraphics:init( 'OPENGL', -- Instead of using hard-coded strings, we could IApp:loadScript('constantsVideoDrivers.e76script') and use the pre-defined constants.
640, 480, -- Width/height
false, -- Fullscreen
16, -- Bits/color depth
false, -- Shadows
false, -- Antialiasing
false, -- VSync
30, -- Frame rate
false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right
local physicsInitialised = IPhysics:init( 1, -- Adaptive solver model
1, -- Adaptive friction model
0.5, -- Default static friction
0.4, -- Default dynamic friction
0, -- Default elasticity
0, -- Min mass. Any entities with a mass < this are not simulated
1000, -- Max mass, Any entities with a mass > this are simulated as static bodies
true, -- Optimise 3D meshes when loading
50, -- Physics frame rate. Should be as high as possible to give the physics engine plenty of samples when simulating collisions etc.
false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right
if (graphicsInitialised and physicsInitialised) then
---------------------------
-- At this point, you might add some resource folders to the ScriptENGINE filesystem.
-- ScriptENGINE will search its filesystem when loading scripts, 3D models, textures etc...
-- In you final programs, you should copy the ScriptENGINE constants files into your own program folders, so they'll be distributed with your program...
---------------------------
IApp:addSearchPath('../../Common/Models');
IApp:addSearchPath(IApp:getExeFilePath() .. './Constants'); -- IApp:getExeFilePath() returns the path to the ScriptENGINE.exe
---------------------------
-- Load some constants into our script
---------------------------
IApp:loadScript(IApp:getExeFilePath() .. '/Scripts/constantsMaterialTypes.e76script');
---------------------------
-- Create the camera, so we can view the world
---------------------------
local cameraId = IWorld:createCamera(); -- Create a camera entity (but it's still not added to the world yet)
IWorld:setEntityPosition(cameraId, '0 5 -10'); -- 3D Vectors are formatted as 'X Y Z'
IWorld:setCameraLookAt(cameraId, '0 0 0'); -- Make the camera look at the origin
IWorld:addCamera(cameraId); -- Add the camera to the world
---------------------------
-- Create the floor
-- Use an ScriptENGINE unit.
-- Units are used for non-animated entities (like buildings, floors etc).
-- Use ScriptENGINE agents for with 3D animated models like skeletal (.X) and morph (.MD2) models
---------------------------
local floorId = IWorld:createUnit(); -- Create a unit entity (but it's still not added to the world yet)
IWorld:setEntityModelName(floorId, 'plane.x'); -- Set the 3D model used to graphically display the unit.
IGraphics:setEntityMaterialType(floorId, -1, MAT_SOLID); -- Set the graphical material type to 'solid',
IGraphics:setEntityTextureName(floorId, 0, -1, 'floor.png'); -- Asiign a texture to the unit
IWorld:setEntityScale(floorId, '10 1 10'); -- Make the unit bigger
-- This is the line that asks the physics engine to simulate the unit.
-- It's at the engine's max defined mass, so will be simulated as a static body.
-- Static bodies are simulated with high detail, using the entity's 3D faces.
-- Compare with dynamic entities that use bounding boxes, ellipses or complex hulls
IPhysics:setEntityMass(floorId, 1000);
IWorld:addUnit(floorId); -- Add the unit to the world
---------------------------
-- Create the box
-- Use an ScriptENGINE unit.
---------------------------
local boxId = IWorld:createUnit(); -- Create a unit entity (but it's still not added to the world yet)
IWorld:setEntityModelName(boxId, 'cube.x'); -- Set the 3D model used to graphically display the unit.
IGraphics:setEntityMaterialType(boxId, -1, MAT_SOLID); -- Set the graphical material type to 'solid',
IGraphics:setEntityTextureName(boxId, 0, -1, 'crate.jpg'); -- Asiign a texture to the unit
IWorld:setEntityPosition(boxId, '0 5 0'); -- Change the unit's position
-- This is the line that asks the physics engine to simulate the unit.
-- It's between the engine's min/max defined mass, so will be simulated as a dynamic body.
-- By default, ScriptENGINE will use a bounding box...
IPhysics:setEntityMass(boxId, 10);
IWorld:addUnit(boxId); -- Add the unit to the world
-- Start simulating entity.
-- When entities are at rest, the physics engine will stop simulating them (by default). This setting is controllable via the IPhysics interface
-- The physics engine will automatically restart the entity's simulation when it interacts in a collision, has a force/torque applied, or you call activateEntity()
IPhysics:activateEntity(boxId);
---------------------------
-- Run the app processing loop for 5 seconds
---------------------------
IApp:run(5000);
---------------------------
-- Close the engine, the window will close, and the program will terminate
---------------------------
IPhysics:destroy();
IGraphics:destroy();
end
--------------------------- --------------------------- -- Tutorial: Physics engine. Test 3 -- Starting up the physics engine, creating a box and giving it mass. -- -- Load a 3D scene from disk. We saved the scene from Test 2... -- Add a force and torque to the box. -- -- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd. --------------------------- --------------------------- --------------------------- --------------------------- -- PROGRAM STARTS HERE --------------------------- --------------------------- --------------------------- -- Initialise the graphics engine, using OPENGL. -- If you try to use the software renderer, you'll find that the graphics engine is using a lot of CPU, which slows the physics. -- So, only use software rendering when absolutely necessary, but always try to use hardware acceleration for the graphics. --------------------------- local graphicsInitialised = IGraphics:init( 'OPENGL', -- Instead of using hard-coded strings, we could IApp:loadScript('constantsVideoDrivers.e76script') and use the pre-defined constants. 640, 480, -- Width/height false, -- Fullscreen 16, -- Bits/color depth false, -- Shadows false, -- Antialiasing false, -- VSync 30, -- Frame rate false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right local physicsInitialised = IPhysics:init( 1, -- Adaptive solver model 1, -- Adaptive friction model 0.5, -- Default static friction 0.4, -- Default dynamic friction 0, -- Default elasticity 0, -- Min mass. Any entities with a mass < this are not simulated 1000, -- Max mass, Any entities with a mass > this are simulated as static bodies true, -- Optimise 3D meshes when loading 50, -- Physics frame rate. Should be as high as possible to give the physics engine plenty of samples when simulating collisions etc. false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right if (graphicsInitialised and physicsInitialised) then --------------------------- -- At this point, you might add some resource folders to the ScriptENGINE filesystem. -- ScriptENGINE will search its filesystem when loading scripts, 3D models, textures etc... -- In you final programs, you should copy the ScriptENGINE constants files into your own program folders, so they'll be distributed with your program... --------------------------- IApp:addSearchPath('./Common/Models'); IApp:addSearchPath(IApp:getExeFilePath() .. './Constants'); -- IApp:getExeFilePath() is the path to the ScriptENGINE.exe --------------------------- -- Load some constants into our script --------------------------- IApp:loadScript(IApp:getExeFilePath() .. '/Scripts/constantsMaterialTypes.e76script'); --------------------------- -- Load the 3D world instead of creating all the entities here. -- Use the ScriptENGINE World Editor to create your 3D worlds. -- The Editor also generates a worldIds.e76script with all your entity identifiers. --------------------------- IWorld:load('./', 'worldData'); IApp:loadScript('worldIds'); -- This script was created by the ScriptENGINE World Editor, and holds all the entity Ids in the world. --------------------------- -- Add a force and torque to the box --------------------------- IPhysics:addEntityImpulseForce(idUnit_box, '1000 1000 0'); IPhysics:addEntityImpulseTorque(idUnit_box, '0 1000 0'); --------------------------- -- Run the app processing loop for 5 seconds --------------------------- IApp:run(5000); --------------------------- -- Close the engine, the window will close, and the program will terminate --------------------------- IPhysics:destroy(); IGraphics:destroy(); end
--------------------------- --------------------------- -- Tutorial: Physics engine. Test 4 -- Performing physics raycasts. -- -- Load a 3D scene from disk. We saved the scene from Test 2... -- Add a force to the box using physics raycasts to determine the intersection point. -- -- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd. --------------------------- --------------------------- --------------------------- -- Mouse button subscriber callback function --------------------------- function OnMouseClick(eventType, mouseX, mouseY, mouseWheel, userData) --------------------------- -- Left button clicked? --------------------------- if (IMouse:leftButtonClicked(eventType)) then -- Use the 'Filter' version of this function to only raycast Units. -- Multiple entity types can be filtered by adding the unit types... local entityHit = IPhysics:rayCastMousePositionFilter(IWorld:getUnitTypeId()); -- If an intersection is found, ScriptENGINE will return a Lua table holding the entity id, and the intersection point. if (entityHit) then local entityId = entityHit['entity']; local intersection = entityHit['intersection']; -- Add a force to the entity, but not at its centre-of-mass. -- Instead, we add the force at an offset position, defined by the raycast intersection. IPhysics:addEntityImpulseForceOffset(entityId, '0 0 5', IMisc:vectorSubtract(intersection, IWorld:getEntityPosition(entityId))); end return true; -- Handled event end end --------------------------- --------------------------- -- PROGRAM STARTS HERE --------------------------- --------------------------- --------------------------- -- Initialise the graphics engine, using OPENGL. -- If you try to use the software renderer, you'll find that the graphics engine is using a lot of CPU, which slows the physics. -- So, only use software rendering when absolutely necessary, but always try to use hardware acceleration for the graphics. --------------------------- local graphicsInitialised = IGraphics:init( 'OPENGL', -- Instead of using hard-coded strings, we could IApp:loadScript('constantsVideoDrivers.e76script') and use the pre-defined constants. 640, 480, -- Width/height false, -- Fullscreen 16, -- Bits/color depth false, -- Shadows false, -- Antialiasing false, -- VSync 30, -- Frame rate false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right local physicsInitialised = IPhysics:init( 1, -- Adaptive solver model 1, -- Adaptive friction model 0.5, -- Default static friction 0.4, -- Default dynamic friction 0, -- Default elasticity 0, -- Min mass. Any entities with a mass < this are not simulated 1000, -- Max mass, Any entities with a mass > this are simulated as static bodies true, -- Optimise 3D meshes when loading 50, -- Physics frame rate. Should be as high as possible to give the physics engine plenty of samples when simulating collisions etc. false); -- Silent errors are off, so ScriptENGINE will raise an error is something's not right if (graphicsInitialised and physicsInitialised) then --------------------------- -- At this point, you might add some resource folders to the ScriptENGINE filesystem. -- ScriptENGINE will search its filesystem when loading scripts, 3D models, textures etc... -- In you final programs, you should copy the ScriptENGINE constants files into your own program folders, so they'll be distributed with your program... --------------------------- IApp:addSearchPath('./Common/Models'); IApp:addSearchPath(IApp:getExeFilePath() .. './Constants'); -- IApp:getExeFilePath() is the path to the ScriptENGINE.exe --------------------------- -- Load some constants into our script --------------------------- IApp:loadScript(IApp:getExeFilePath() .. '/Scripts/constantsMaterialTypes.e76script'); --------------------------- -- Load the 3D world instead of creating all the entities here. -- Use the ScriptENGINE World Editor to create your 3D worlds. -- The Editor also generates a worldIds.e76script with all your entity identifiers. --------------------------- IWorld:load('./', 'worldData'); IApp:loadScript('worldIds'); -- This script was created by the ScriptENGINE World Editor, and holds all the entity Ids in the world. --------------------------- -- Subscribe to mouse clicks. ScriptENGINE will call our callback function when the user clicks the mouse --------------------------- local subMouse = IEvents:subscribeMouseButton('OnMouseClick'); --------------------------- -- Add a force and torque to the box --------------------------- IPhysics:addEntityImpulseForce(idUnit_box, '1000 1000 0'); IPhysics:addEntityImpulseTorque(idUnit_box, '0 100 0'); --------------------------- -- Run the app processing loop for ever. User has to manually close the window. --------------------------- IGraphics:createText('ctlLabel', 'Click the box to perform a physics raycast. A force will be applied at the intersection point. Close the window when you\'re finished', '0.05 0.05 0.95 0.1', false, true, false, '1 1 1 1'); IApp:run(); --------------------------- -- Always unsubscribe when your finished handling events --------------------------- IEvents:unsubscribe(subMouse); --------------------------- -- Close the engine, the window will close, and the program will terminate --------------------------- IPhysics:destroy(); IGraphics:destroy(); end
Copyright © 2006-23 Sep 2009 Capricorn 76 Pty. Ltd. (created on Wed Sep 23 16:49:12 2009)