--------------------------- --------------------------- -- Raycasting example -- Copyright (c) 2007-09 Capricorn 76 Pty. Ltd. -- -- Raycasting can be performed using either the graphics or physics engines. -- We cast a ray into the ScriptENGINE world and find out what is hit. -- Great for line-of-sight calculations, or mouse-selecting entities. -- -- The graphics engine raycasts graphical entities (things we can see). -- The physics engine raycasts physical entities (things with a mass). -- -- The physics engine returns a more detailed result than the graphics engine. -- -- 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 subMouse; --------------------------- -- 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 this example's GUI --------------------------- OnWorldLoadGui(); --------------------------- -- Expand the physical world bounds a bit. -- This is the zone within which the physics engine simulates its entities. -- It defaults to a zone that just surrounds the world entities. -- But because the boxes are going to be flying about, we expand it. --------------------------- IPhysics:expandBounds('-100 -100 -100', '100 100 100'); --------------------------- -- Subscribe to the mouse button events. -- The graphics engine will call our callback function -- whenever the user clicks a mouse button. -- We can handle these mouse clicks to perform a raycast. --------------------------- subMouse = IEvents:subscribeMouseButton('OnMouseButton'); end --------------------------- -- Load example's GUI --------------------------- function OnWorldLoadGui() 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 any mouse button clicks. --------------------------- IEvents:unsubscribe(subMouse); ISound:unload('shoot'); end --------------------------- -- Mouse button event handler. -- The graphics engine will call this function whenever -- the user clicks a mouse button. --------------------------- function OnMouseButton(eventType, mouseX, mouseY, mouseWheel, userData) --------------------------- -- If the user clicked the left-mouse button then do a raycast and see what we hit. -- We filter what entities we are interested in. We only want units. Not things like waypoints, agents, etc. -- You can raycast in any direction, from any starting position. But we're going to use the mouse position and use the mouse raycast function. --------------------------- if (IMouse:leftButtonClicked(eventType)) then result = IPhysics:rayCastMousePositionFilter(IWorld:getUnitTypeId()); --------------------------- -- Did we hit something? --------------------------- if (result) then boxId = result['entity']; intersection = result['intersection']; -- Calculate a force vector. This is just a vector from our position to the intersection point. ourPosition = IWorld:getEntityPosition(IWorld:getActiveCameraId()); forceVector = IMisc:vectorSubtract(intersection, ourPosition); -- Normalise the vector. This makes its magnitude = 1 (ie. we scale it, still points in the same direction) forceVector = IMisc:vectorNormalise(forceVector); -- Rescale it to a larger force forceVector = IMisc:vectorMultiply(forceVector, 5); -- Apply the force to the entity at the intersection point intersectionOffset = IMisc:vectorSubtract(intersection, IWorld:getEntityPosition(boxId)); IPhysics:addEntityImpulseForceOffset(boxId, forceVector, intersectionOffset); -- Play a sound just for fun if (not(ISound:soundExists('shoot'))) then if (ISound:load('shoot', '../Resources/sfx.wav', false)) then -- This sound is stereo, and therefore is played in 2D by the engine (nb: use mono sounds for 3D) ISound:setVolume('shoot', 1); end end if (ISound:soundExists('shoot')) then ISound:play('shoot'); end end end end
Copyright © 2006-23 Sep 2009 Capricorn 76 Pty. Ltd. (created on Wed Sep 23 16:49:12 2009)