Andy90 Posted September 27, 2023 Share Posted September 27, 2023 Hello is there a way to recive the height at a given point? Quote Link to comment Share on other sites More sharing options...
klepto2 Posted September 27, 2023 Share Posted September 27, 2023 Hi, if you mean in UltraEngine, then this is what you're looking for: https://www.ultraengine.com/learn/Terrain_GetElevation?lang=cpp https://www.ultraengine.com/learn/Terrain_GetHeight?lang=cpp GetElevation get the global height of the terrain (including the scale), whereas Getheight get the raw height value (0.0 - 1.0) of the heightmap at the specific position. For Leadwerks Engine the same commands exists. 1 Quote Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI Link to comment Share on other sites More sharing options...
Andy90 Posted September 27, 2023 Author Share Posted September 27, 2023 Currently i use the Leadwerks engine. But i get an error in LUA if i want to call GetHeight() or GetElevation(). Quote Link to comment Share on other sites More sharing options...
klepto2 Posted September 27, 2023 Share Posted September 27, 2023 What error do you get? And how does the lua code look like? Quote Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI Link to comment Share on other sites More sharing options...
Andy90 Posted September 27, 2023 Author Share Posted September 27, 2023 The error is Error in function 'GetHeight' this is my code function Script:UpdateWorld() System:Print(Terrain:GetHeight(0,0)); end Quote Link to comment Share on other sites More sharing options...
Solution Alienhead Posted September 27, 2023 Solution Share Posted September 27, 2023 Make sure you have the correct pointer to the terrain object. -- Cycle loaded map for x=0,world:CountEntities()-1 do local entity = world:GetEntity(x) -- get terrain mesh if world:GetEntity(x):GetClass()==Object.TerrainClass then terrain=world:GetEntity(x) terrain=tolua.cast(terrain,"Terrain") end end Your code should be more like this : local y = terrain:GetElevation(x, z) 1 1 Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Andy90 Posted September 27, 2023 Author Share Posted September 27, 2023 ok thanks for some reason i was thinking Terrain is static but now its working. Btw is it possible to remove vegetation at a specific point dynamic? Quote Link to comment Share on other sites More sharing options...
klepto2 Posted September 27, 2023 Share Posted September 27, 2023 No, at least not officially supported. In lua there is no way to achieve this. In the cpp version it is possible by using the not documented Vegetation methods of the terrain class, but as said, these are not supported to be used by the end user. Quote Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI Link to comment Share on other sites More sharing options...
Andy90 Posted September 27, 2023 Author Share Posted September 27, 2023 ah ok. Yeah i got the leadwerks professional version. So i could access it with c++? I would like that the player can harvest trees to gether ressources. The other way to do it would to create a prefab with the tree model and the script and place some tree manualy. What would you prefer in this case? Quote Link to comment Share on other sites More sharing options...
klepto2 Posted September 27, 2023 Share Posted September 27, 2023 A good starting point might be this topic: I haven't worked with LE since the UltraEngine Early Access, but the essential methods should all be located in Terrain.h and Vegetation.h . If i remember correctly it is also possible to use camera picking to get the actual instance, but that is not for sure. Quote Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI Link to comment Share on other sites More sharing options...
Alienhead Posted September 27, 2023 Share Posted September 27, 2023 It's quite easy to mimic the vegetation system in LE. To be honest it proved to be faster creating a pivot system with attached trees to it manually. The only downside is you dont get to use the easy paint-on feature in the LE editor, but with some code you can mimic the paint on feature in your real map and save out the locations to an external file. Doing so you'll have entity pointers to your trees to do as you please. I did this in an experimental project I worked on last year and it year and it had very positive results, actually I'm using the same developed system for my current project. 1 Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Alienhead Posted September 27, 2023 Share Posted September 27, 2023 Also, you'll probably, at some point or another, want to align an object to the terrain slope. This line of code will save you a lot of hunting. entity:AlignToVector(terrain:GetNormal(x,z), 1, 1, entity:GetRotation(true).y) Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Andy90 Posted September 27, 2023 Author Share Posted September 27, 2023 53 minutes ago, klepto2 said: A good starting point might be this topic: I haven't worked with LE since the UltraEngine Early Access, but the essential methods should all be located in Terrain.h and Vegetation.h . If i remember correctly it is also possible to use camera picking to get the actual instance, but that is not for sure. Is there allready an Early Access ? Quote Link to comment Share on other sites More sharing options...
Alienhead Posted September 27, 2023 Share Posted September 27, 2023 3 minutes ago, Andy90 said: Is there allready an Early Access ? Josh has a few members with EA.. but for the majority of us we're sitting in the wings...waiting.. Oh the demos we could already had made with a beta phase. Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Andy90 Posted October 8, 2023 Author Share Posted October 8, 2023 Is there a documentation about the terrain class in lua? Quote Link to comment Share on other sites More sharing options...
Josh Posted October 8, 2023 Share Posted October 8, 2023 In Leadwerks the terrain is just a static object in the map. Terrains are only editable in the editor, and there's no way to retrieve detailed information in-game. In Ultra this is quite a lot more flexible. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Andy90 Posted October 8, 2023 Author Share Posted October 8, 2023 ok, so there is no way to get the position from the trees? I found within the article linked from @klepto2 something like this AABB aabb = world->aabb; std::vector<Mat4> instances; layer->GetInstancesInAABB(aabb, instances); Quote Link to comment Share on other sites More sharing options...
Josh Posted October 8, 2023 Share Posted October 8, 2023 This information is not available in Lua. Sorry. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Andy90 Posted October 8, 2023 Author Share Posted October 8, 2023 Ah, okay. Thanks anyway. I'll give it a shot with C++. If that doesn't work, I'll have to explore alternative methods to add wood to the player's inventory. Perhaps by incorporating additional prefab trees placed around a pivot, similar to the suggestion by @Alienhead. ---- 1 hour ago, Josh said: In Ultra this is quite a lot more flexible. For example, will it be possible to access individual vegetation objects in the Ultra Engine? Quote Link to comment Share on other sites More sharing options...
Josh Posted October 8, 2023 Share Posted October 8, 2023 I have not started on any vegetation system in Ultra. The rendering is so fast that a special system for vegetation might not be needed at all, except in the case of very large environments. But in any case, the Lua and C++ APIs are much better synced together in Ultra than in Leadwerks. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Andy90 Posted October 8, 2023 Author Share Posted October 8, 2023 Ah okey this sounds very nice. I finished my script for a tree spawning based on a pivot Script.terrain = nil Script.player = nil --Entity "Player" Script.playerDistance = 30 --Float "Player Distance" Script.seed = 123456 --Float "Seed" Script.treeCount = 25 --Int "Trees" Script.minDist = 25 --Float "Min Distance" Script.maxDist = 75 --Float "Max Distance" Script.tree = "" --Path "Model" Script.treeMinHeight = 0.5 --Float "Min height" Script.treeMaxHeight = 1.0 --Float "Max height" Script.debug = true --Bool "Debug Mode" function Script:Start() --Find the terrain local world = World:GetCurrent() for i = 0, world:CountEntities() - 1 do local entity = world:GetEntity(i) if entity:GetClass() == Object.TerrainClass then self.terrain = tolua.cast(entity, "Terrain") end end --Sets a tree at the pivot location local x = self.entity:GetPosition(true).x local z = self.entity:GetPosition(true).z local y = self.terrain:GetElevation(x, z) local tree = Model:Load(self.tree) tree:SetPosition(x, y, z) tree:SetParent(self.entity) --Place a sphere at the pivot location if self.debug then local spehre = Model:Sphere() spehre:SetColor(1.0, 0.0, 0.0) spehre:SetScale(1.0) spehre:SetPosition(x, y, z) end math.randomseed(self.seed) for i = 0, self.treeCount do --Calculate the angle and the distance for the new tree local deg = 360 / self.treeCount * i local radians = math.rad(deg) local distance = math.random(self.minDist, self.maxDist) local sin = math.sin(radians) local cos = math.cos(radians) --Calculate the x,y,z cords for the tree local x = self.entity:GetPosition(true).x + distance * cos local z = self.entity:GetPosition(true).z + distance * sin local y = self.terrain:GetElevation(x, z) --Calculates the scale for the tree local scale = math.random(self.treeMinHeight * 100, self.treeMaxHeight * 100) / 100 --Creates the tree within the scene local tree = Model:Load(self.tree) tree:SetPosition(x, y, z) tree:SetScale(scale) tree:SetParent(self.entity) --Creates a debug sphere at the tree location if self.debug then local spehre = Model:Sphere() spehre:SetColor(1.0, 1.0, 0.0) spehre:SetScale(1.0) spehre:SetPosition(x, y, z) end end end function Script:UpdateWorld() --Enables the trees when the player is nearby local distance = self.entity:GetDistance(self.player) if distance > self.playerDistance then self.entity:Hide() else self.entity:Show() end end 1 Quote Link to comment Share on other sites More sharing options...
Andy90 Posted October 9, 2023 Author Share Posted October 9, 2023 I've developed a second iteration of the script, this time utilizing a prefab. This means there are now two scripts in play: the Spawn Manager and the tree itself. 1. Spawn Manager Script.terrain = nil Script.player = nil --Entity "Player" Script.playerDistance = 30 --Float "Player Distance" Script.seed = 123456 --Float "Seed" Script.treeCount = 25 --Int "Trees" Script.minDist = 25 --Float "Min Distance" Script.maxDist = 75 --Float "Max Distance" Script.tree = "" --Path "Model" Script.treeMinHeight = 0.5 --Float "Min height" Script.treeMaxHeight = 1.0 --Float "Max height" Script.aabbCheck = false --Bool "AABB Check" Script.debug = true --Bool "Debug Mode" Script.treeData = {} function Script:Start() self.entity:Hide() --Find the terrain local world = World:GetCurrent() for i = 0, world:CountEntities() - 1 do local entity = world:GetEntity(i) if entity:GetClass() == Object.TerrainClass then self.terrain = tolua.cast(entity, "Terrain") end end local treeData = {} --Creates the tree data for the pivot tree local x = self.entity:GetPosition(true).x local z = self.entity:GetPosition(true).z local y = self.terrain:GetElevation(x, z) local treeInfo = { TreeName = self.entity:GetKeyValue("name") .. "_tree_center", TreeX = x, TreeY = y, TreeZ = z, TreeScale = 1.0, Visible = true, HideTime = 0 } table.insert(treeData, treeInfo) --Place a sphere at the pivot location if self.debug then local spehre = Model:Sphere() spehre:SetColor(1.0, 0.0, 0.0) spehre:SetScale(1.0) spehre:SetPosition(x, y, z) end math.randomseed(self.seed) for i = 0, self.treeCount do --Calculate the angle and the distance for the new tree local deg = 360 / self.treeCount * i local radians = math.rad(deg) local distance = math.random(self.minDist, self.maxDist) local sin = math.sin(radians) local cos = math.cos(radians) --Calculate the x,y,z cords for the tree local x = self.entity:GetPosition(true).x + distance * cos local z = self.entity:GetPosition(true).z + distance * sin local y = self.terrain:GetElevation(x, z) --Calculates the scale for the tree local scale = math.random(self.treeMinHeight * 100, self.treeMaxHeight * 100) / 100 --If AABB Check is enabled check for collision if self.aabbCheck then for _,item in pairs(self.treeData) do if Vec3(item.TreeX, item.TreeY, item.TreeZ):DistanceToPoint(Vec3(x,y,z)) < 0.5 then System:Print("Double Point") goto continue end end for i = 0, world:CountEntities() - 1 do local entity = world:GetEntity(i) if entity:GetClass() == Object.ModelClass and entity:GetParent() == nil then if entity:GetAABB():IntersectsPoint(Vec3(x,y,z), 1) then System:Print("intersect with entity " .. entity:GetKeyValue("name")) goto continue end end end end --Adds the tree info into the table local treeInfo = { TreeName = self.entity:GetKeyValue("name") .. "_tree_" .. i, TreeX = x, TreeY = y, TreeZ = z, TreeScale = scale, Visible = true, HideTime = 0 } table.insert(treeData, treeInfo) ::continue:: end self.treeData = treeData; end function Script:UpdateWorld() --Enables the trees when the player is nearby local distance = self.entity:GetDistance(self.player) if distance > self.playerDistance + self.maxDist and not self.entity:Hidden() then self.entity:Hide() self:HideTrees() elseif distance < self.playerDistance + self.maxDist and self.entity:Hidden() then self.entity:Show() self:ShowTrees() end -- System:Print(self.entity:GetKeyValue("name") .. " Children " .. self.entity:CountChildren() .. " / " .. #self.treeData) end function Script:ShowTrees() System:Print("Show Trees!") for _, item in pairs(self.treeData) do local tree = Prefab:Load(self.tree) tree.script.treeData = item tree:SetPosition(item.TreeX, item.TreeY, item.TreeZ) tree:SetScale(item.TreeScale) tree:SetKeyValue("name", item.TreeName) tree:SetParent(self.entity) if not item.Visible then tree:Hide() end end end function Script:HideTrees() local t = self.entity:CountChildren() for i = 0, self.entity:CountChildren() -1 do local child = self.entity:GetChild(i) child:Release() end end 2. Tree Script Script.treeData = nil Script.respawn = 10 * 60000 function Script:UpdateWorld() if self.entity:Hidden() then local now = Time:GetCurrent() if now > self.treeData.HideTime + self.respawn then self.treeData.Visible = true self.entity:Show() end end end function Script:Collision(entity, position, normal, speed) if entity:GetKeyValue("name") == "player" then if Window:GetCurrent():KeyDown(Key.E) then self.entity:Hide() self.treeData.Visible = false self.treeData.HideTime = Time:GetCurrent() end end end As you can see, the trees are no longer created within the Start function. They are dynamically generated when the player is nearby and released when the player moves away. This enhancement greatly improves performance. For example, if you have 10 spawners each with 50 trees, the old script would add 500 entities to the scene. With the new script, you only add the 10 pivot points, and create the entities for the trees only when the player is nearby. I hope this will help anyone within the future 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.