104 | function LightWildlife:createAnimals(name, spawnPosX, spawnPosY, spawnPosZ, nbAnimals) |
105 | if #self.animals == 0 then |
106 | for i = 1, nbAnimals do |
107 | local nodeId = g_i3DManager:loadSharedI3DFile(self.i3dFilename, self.baseDirectory, false, false, false) |
108 | link(getRootNode(), nodeId) |
109 | local shaderNode = I3DUtil.indexToObject(nodeId, self.shaderNodeString) |
110 | local animal = LightWildlifeAnimal:new(self, i, nodeId, shaderNode) |
111 | |
112 | animal:init(spawnPosX, spawnPosZ, self.randomSpawnRadius, self.animalStates) |
113 | table.insert(self.animals, animal) |
114 | end |
115 | setWorldTranslation(self.soundsNode, spawnPosX, spawnPosY, spawnPosZ) |
116 | return 1 |
117 | end |
118 | return 0 |
119 | end |
175 | function LightWildlife:getClosestDistance(refPosX, refPosY, refPosZ) |
176 | local closestDistSq = nil |
177 | |
178 | for _, animal in pairs(self.animals) do |
179 | local x, y, z = getWorldTranslation(animal.i3dNodeId) |
180 | local deltaX = refPosX - x |
181 | local deltaY = refPosY - y |
182 | local deltaZ = refPosZ - z |
183 | local distSq = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ |
184 | |
185 | if closestDistSq == nil or (closestDistSq ~= nil and distSq < closestDistSq) then |
186 | closestDistSq = distSq |
187 | end |
188 | end |
189 | if closestDistSq == nil then |
190 | closestDistSq = 0.0 |
191 | end |
192 | return closestDistSq |
193 | end |
215 | function LightWildlife:getTerrainHeightWithProps(x, z) |
216 | local terrainY = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 0, z) |
217 | local offset = 5.0 |
218 | local distance = 5.0 |
219 | local collisionMask = 63 |
220 | |
221 | self.groundY = -1.0 |
222 | raycastClosest(x, terrainY + offset, z, 0.0, -1.0, 0.0, "groundRaycastCallback", 5.0, self, collisionMask) |
223 | return math.max(terrainY, self.groundY) |
224 | end |
61 | function LightWildlife:load(xmlFilename) |
62 | self.xmlFilename = Utils.getFilename(xmlFilename, self.baseDirectory) |
63 | local xmlFile = loadXMLFile("TempXML", self.xmlFilename) |
64 | if xmlFile == 0 then |
65 | self.xmlFilename = nil |
66 | return false |
67 | end |
68 | local key = "wildlifeAnimal" |
69 | if hasXMLProperty(xmlFile, key) then |
70 | self.type = getXMLString(xmlFile, key .. "#type") |
71 | self.randomSpawnRadius = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#randomSpawnRadius"), 0.0) |
72 | self.i3dFilename = getXMLString(xmlFile, key .. ".asset#filename") |
73 | self.shaderNodeString = getXMLString(xmlFile, key .. ".animations#shaderNode") |
74 | self.shaderParmId = getXMLString(xmlFile, key .. ".animations#shaderParameterId") |
75 | self.shaderParmOpcode = getXMLString(xmlFile, key .. ".animations#shaderParameterOpcode") |
76 | self.shaderParmSpeed = getXMLString(xmlFile, key .. ".animations#shaderParameterSpeed") |
77 | self.animations = {} |
78 | self.animations["default"] = {name="default", opcode=0, speed=0.0, transitionTimer=0.0} |
79 | local i = 0 |
80 | while true do |
81 | local animkey = string.format(key .. ".animations.animation(%d)", i) |
82 | if not hasXMLProperty(xmlFile, animkey) then |
83 | break |
84 | end |
85 | local state = Utils.getNoNil(getXMLString(xmlFile, animkey.."#conditionState"), "") |
86 | local animation = {} |
87 | animation.opcode = Utils.getNoNil(getXMLInt(xmlFile, animkey.."#opcode"), 0) |
88 | animation.speed = Utils.getNoNil(getXMLFloat(xmlFile, animkey.."#speed"), 0.0) |
89 | animation.transitionTimer = Utils.getNoNil(getXMLFloat(xmlFile, animkey.."#transitionTimer"), 1.0) * 1000.0 |
90 | self.animations[state] = animation |
91 | i = i + 1 |
92 | end |
93 | if self.type ~= nil and self.i3dFilename ~= nil then |
94 | delete(xmlFile) |
95 | return true |
96 | end |
97 | end |
98 | delete(xmlFile) |
99 | return false |
100 | end |
149 | function LightWildlife:removeFarAwayAnimals(maxDistance, refPosX, refPosY, refPosZ) |
150 | local removeCount = 0 |
151 | |
152 | for i=#self.animals, 1, -1 do |
153 | local x, y, z = getWorldTranslation(self.animals[i].i3dNodeId) |
154 | local deltaX = refPosX - x |
155 | local deltaY = refPosY - y |
156 | local deltaZ = refPosZ - z |
157 | local distSq = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ |
158 | |
159 | if distSq > (maxDistance * maxDistance) then |
160 | g_i3DManager:releaseSharedI3DFile(self.i3dFilename, self.baseDirectory, false) |
161 | delete(self.animals[i].i3dNodeId) |
162 | table.remove(self.animals, i) |
163 | removeCount = removeCount + 1 |
164 | end |
165 | end |
166 | return removeCount |
167 | end |