1-- Ribbon trail demo. 2-- This sample demonstrates how to use both trail types of RibbonTrail component. 3 4require "LuaScripts/Utilities/Sample" 5 6local boxNode1 = nil 7local boxNode2 = nil 8local swordTrail = nil 9local ninjaAnimCtrl = nil 10local timeStepSum = 0.0 11local swordTrailStartTime = 0.2 12local swordTrailEndTime = 0.46 13 14function Start() 15 -- Execute the common startup for samples 16 SampleStart() 17 18 -- Create the scene content 19 CreateScene() 20 21 -- Create the UI content 22 CreateInstructions() 23 24 -- Setup the viewport for displaying the scene 25 SetupViewport() 26 27 -- Set the mouse mode to use in the sample 28 SampleInitMouseMode(MM_RELATIVE) 29 30 -- Hook up to the frame update events 31 SubscribeToEvents() 32end 33 34function CreateScene() 35 scene_ = Scene() 36 37 -- Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) 38 scene_:CreateComponent("Octree") 39 40 -- Create scene node & StaticModel component for showing a static plane 41 local planeNode = scene_:CreateChild("Plane") 42 planeNode.scale = Vector3(100.0, 1.0, 100.0) 43 local planeObject = planeNode:CreateComponent("StaticModel") 44 planeObject.model = cache:GetResource("Model", "Models/Plane.mdl") 45 planeObject.material = cache:GetResource("Material", "Materials/StoneTiled.xml") 46 47 -- Create a directional light to the world. 48 local lightNode = scene_:CreateChild("DirectionalLight") 49 lightNode.direction = Vector3(0.6, -1.0, 0.8) -- The direction vector does not need to be normalized 50 local light = lightNode:CreateComponent("Light") 51 light.lightType = LIGHT_DIRECTIONAL 52 light.castShadows = true 53 light.shadowBias = BiasParameters(0.00005, 0.5) 54 -- Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance 55 light.shadowCascade = CascadeParameters(10.0, 50.0, 200.0, 0.0, 0.8) 56 57 -- Create first box for face camera trail demo with 1 column. 58 boxNode1 = scene_:CreateChild("Box1") 59 local box1 = boxNode1:CreateComponent("StaticModel") 60 box1.model = cache:GetResource("Model", "Models/Box.mdl") 61 box1.castShadows = true 62 local boxTrail1 = boxNode1:CreateComponent("RibbonTrail") 63 boxTrail1.material = cache:GetResource("Material", "Materials/RibbonTrail.xml") 64 boxTrail1.startColor = Color(1.0, 0.5, 0.0, 1.0) 65 boxTrail1.endColor = Color(1.0, 1.0, 0.0, 0.0) 66 boxTrail1.width = 0.5 67 boxTrail1.updateInvisible = true 68 69 -- Create second box for face camera trail demo with 4 column. 70 -- This will produce less distortion than first trail. 71 boxNode2 = scene_:CreateChild("Box2") 72 local box2 = boxNode2:CreateComponent("StaticModel") 73 box2.model = cache:GetResource("Model", "Models/Box.mdl") 74 box2.castShadows = true 75 local boxTrail2 = boxNode2:CreateComponent("RibbonTrail") 76 boxTrail2.material = cache:GetResource("Material", "Materials/RibbonTrail.xml") 77 boxTrail2.startColor = Color(1.0, 0.5, 0.0, 1.0) 78 boxTrail2.endColor = Color(1.0, 1.0, 0.0, 0.0) 79 boxTrail2.width = 0.5 80 boxTrail2.tailColumn = 4 81 boxTrail2.updateInvisible = true 82 83 -- Load ninja animated model for bone trail demo. 84 local ninjaNode = scene_:CreateChild("Ninja") 85 ninjaNode.position = Vector3(5.0, 0.0, 0.0) 86 ninjaNode.rotation = Quaternion(0.0, 180.0, 0.0) 87 local ninja = ninjaNode:CreateComponent("AnimatedModel") 88 ninja.model = cache:GetResource("Model", "Models/NinjaSnowWar/Ninja.mdl") 89 ninja.material = cache:GetResource("Material", "Materials/NinjaSnowWar/Ninja.xml") 90 ninja.castShadows = true 91 92 -- Create animation controller and play attack animation. 93 ninjaAnimCtrl = ninjaNode:CreateComponent("AnimationController") 94 ninjaAnimCtrl:PlayExclusive("Models/NinjaSnowWar/Ninja_Attack3.ani", 0, true, 0.0) 95 96 -- Add ribbon trail to tip of sword. 97 local swordTip = ninjaNode:GetChild("Joint29", true) 98 swordTrail = swordTip:CreateComponent("RibbonTrail") 99 100 -- Set sword trail type to bone and set other parameters. 101 swordTrail.trailType = TT_BONE 102 swordTrail.material = cache:GetResource("Material", "Materials/SlashTrail.xml") 103 swordTrail.lifetime = 0.22 104 swordTrail.startColor = Color(1.0, 1.0, 1.0, 0.75) 105 swordTrail.endColor = Color(0.2, 0.5, 1.0, 0.0) 106 swordTrail.tailColumn = 4 107 swordTrail.updateInvisible = true 108 109 -- Add floating text for info. 110 local boxTextNode1 = scene_:CreateChild("BoxText1") 111 boxTextNode1.position = Vector3(-1.0, 2.0, 0.0) 112 local boxText1 = boxTextNode1:CreateComponent("Text3D") 113 boxText1.text = "Face Camera Trail (4 Column)" 114 boxText1:SetFont(cache:GetResource("Font", "Fonts/BlueHighway.sdf"), 24) 115 116 local boxTextNode2 = scene_:CreateChild("BoxText2") 117 boxTextNode2.position = Vector3(-6.0, 2.0, 0.0) 118 local boxText2 = boxTextNode2:CreateComponent("Text3D") 119 boxText2.text = "Face Camera Trail (1 Column)" 120 boxText2:SetFont(cache:GetResource("Font", "Fonts/BlueHighway.sdf"), 24) 121 122 local ninjaTextNode2 = scene_:CreateChild("NinjaText") 123 ninjaTextNode2.position = Vector3(4.0, 2.5, 0.0) 124 local ninjaText = ninjaTextNode2:CreateComponent("Text3D") 125 ninjaText.text = "Bone Trail (4 Column)" 126 ninjaText:SetFont(cache:GetResource("Font", "Fonts/BlueHighway.sdf"), 24) 127 128 -- Create the camera. 129 cameraNode = scene_:CreateChild("Camera") 130 cameraNode:CreateComponent("Camera") 131 132 -- Set an initial position for the camera scene node above the plane 133 cameraNode.position = Vector3(0.0, 2.0, -14.0) 134end 135 136function CreateInstructions() 137 -- Construct new Text object, set string to display and font to use 138 local instructionText = ui.root:CreateChild("Text") 139 instructionText:SetText("Use WASD keys and mouse to move") 140 instructionText:SetFont(cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15) 141 142 -- Position the text relative to the screen center 143 instructionText.horizontalAlignment = HA_CENTER 144 instructionText.verticalAlignment = VA_CENTER 145 instructionText:SetPosition(0, ui.root.height / 4) 146end 147 148function SetupViewport() 149 -- Set up a viewport to the Renderer subsystem so that the 3D scene can be seen. We need to define the scene and the camera 150 -- at minimum. Additionally we could configure the viewport screen size and the rendering path (eg. forward / deferred) to 151 -- use, but now we just use full screen and default render path configured in the engine command line options 152 local viewport = Viewport:new(scene_, cameraNode:GetComponent("Camera")) 153 renderer:SetViewport(0, viewport) 154end 155 156function MoveCamera(timeStep) 157 -- Do not move if the UI has a focused element (the console) 158 if ui.focusElement ~= nil then 159 return 160 end 161 162 -- Movement speed as world units per second 163 local MOVE_SPEED = 20.0 164 -- Mouse sensitivity as degrees per pixel 165 local MOUSE_SENSITIVITY = 0.1 166 167 -- Use this frame's mouse motion to adjust camera node yaw and pitch. Clamp the pitch between -90 and 90 degrees 168 local mouseMove = input.mouseMove 169 yaw = yaw +MOUSE_SENSITIVITY * mouseMove.x 170 pitch = pitch + MOUSE_SENSITIVITY * mouseMove.y 171 pitch = Clamp(pitch, -90.0, 90.0) 172 173 -- Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero 174 cameraNode.rotation = Quaternion(pitch, yaw, 0.0) 175 176 -- Read WASD keys and move the camera scene node to the corresponding direction if they are pressed 177 -- Use the Translate() function (default local space) to move relative to the node's orientation. 178 if input:GetKeyDown(KEY_W) then 179 cameraNode:Translate(Vector3(0.0, 0.0, 1.0) * MOVE_SPEED * timeStep) 180 end 181 if input:GetKeyDown(KEY_S) then 182 cameraNode:Translate(Vector3(0.0, 0.0, -1.0) * MOVE_SPEED * timeStep) 183 end 184 if input:GetKeyDown(KEY_A) then 185 cameraNode:Translate(Vector3(-1.0, 0.0, 0.0) * MOVE_SPEED * timeStep) 186 end 187 if input:GetKeyDown(KEY_D) then 188 cameraNode:Translate(Vector3(1.0, 0.0, 0.0) * MOVE_SPEED * timeStep) 189 end 190end 191 192function SubscribeToEvents() 193 -- Subscribe HandleUpdate() function for processing update events 194 SubscribeToEvent("Update", "HandleUpdate") 195end 196 197function HandleUpdate(eventType, eventData) 198 -- Take the frame time step, which is stored as a float 199 local timeStep = eventData["TimeStep"]:GetFloat() 200 201 -- Move the camera, scale movement with time step 202 MoveCamera(timeStep) 203 204 -- Sum of timesteps. 205 timeStepSum = timeStepSum + timeStep 206 207 -- Move first box with pattern. 208 boxNode1:SetTransform(Vector3(-4.0 + 3.0 * Cos(100.0 * timeStepSum), 0.5, -2.0 * Cos(400.0 * timeStepSum)), Quaternion()) 209 210 -- Move second box with pattern. 211 boxNode2:SetTransform(Vector3(0.0 + 3.0 * Cos(100.0 * timeStepSum), 0.5, -2.0 * Cos(400.0 * timeStepSum)), Quaternion()) 212 213 -- Get elapsed attack animation time. 214 local swordAnimTime = ninjaAnimCtrl:GetAnimationState("Models/NinjaSnowWar/Ninja_Attack3.ani").time 215 216 -- Stop emitting trail when sword is finished slashing. 217 if not swordTrail.emitting and swordAnimTime > swordTrailStartTime and swordAnimTime < swordTrailEndTime then 218 swordTrail.emitting = true 219 elseif swordTrail.emitting and swordAnimTime >= swordTrailEndTime then 220 swordTrail.emitting = false 221 end 222end 223