Jump to content

Einlander

Members
  • Posts

    778
  • Joined

  • Last visited

Posts posted by Einlander

  1. Ever made a level in csg and exported it to obj? Well you probably found out that you end up with one massive mess of polygons. This tool fixes that. It will take a leadwerks exported mesh and fix it to something that is easier to handle.

     

    What it does:

    Separates all the objects into mesh groups.

     

    What it doesn't do:

    Anything with textures or uvmaps. Leadwerks doesn't export any of them :(

     

    It was written in vb.net so it should run in wine if your on linux.

     

    leadwerks obj fixer.zip

    • Upvote 4
  2. Is there a reason to not simply convert all strings to wstring to allow utf8 in the fonts that allow them? Or have a global font settings that will take the restrictions off for those who know the risks? Maybe you might gain some customers using logogram based writing systems.

  3. The editor use to be in Meters ( multiples of 10), but Josh changed it to be powers of 2 (256, 512, 1024). I still rather it was in multiples of 10. 256cm has no room for jumping indoors, so I have to make all my interiors 384cm, which is not as pretty in the editor.

  4. Reepblue we seem to have the same idea all the time! I also have a lua based laser beam script for leadwerks. Though I suspect yours will handle materials better than mine can.

     

    These are the notes to the script:

    Notes:            If you want your beam to be see through, the material need to be see through.
                       My Recomendation is to set the material to alpha and to set the last diffuse box to 128
                       Since we are streching a quad (thats what a sprite is in Leadwerks) your material will be unrecognizable
    

     

     

     

    Script in spoiler.

     

     

    
    

    --[[

    Title: Laser Beam

    Author: Einlander

    Version: .01

    Start Date: 1-22-2016

    Description: Draws a laser beam between 2 pivots

    Notes: If you want your beam to be see through, the material need to be see through.

    My Recomendation is to set the material to alpha and to set the last diffuse box to 128

    Since we are streching a quad (thats what a sprite is in Leadwerks) your material will be unrecognizable

    --]]

     

    Script.enabled = true --bool "Enabled"

    Script.EndPoint = nil --entity "End Point:"

    Script.BeamMaterialFile = "" --path "Beam Material:" "Material File (*.mat):mat|Material"

    Script.BeamHeight = .2 --float "Beam Height cm:"

    Script.PhysicsUpdate = true --bool "Update in Physics:"

     

    function Script:Start()

    self.BeamHeight = self.BeamHeight / 10

     

    -- Check End Point

    Debug:Assert(self.EndPoint ~= nil , "End point missing. Was an entity added?")

     

    -- Load the Material

    self.BeamMaterial = Material:Load(self.BeamMaterialFile)

    Debug:Assert(self.BeamMaterial ~= nil , "Error loading the material.")

    self.BeamMaterial = tolua.cast(self.BeamMaterial:Copy(),"Material") -- force a copy of the asset because we will need to modify it.

    self.BeamMaterial:SetSortMode(true) -- force zsorting (It will be used in a sprite,)

     

    -- Create sprite

    self.LaserBeam = Sprite:Create()

    self.LaserBeam:SetSize(self.BeamHeight,.1)

    self.LaserBeam:SetPickMode(0)

    self.LaserBeam:SetMaterial(self.BeamMaterial) -- assign material

    self.LaserBeam:SetShadowMode(2)

    self.LaserBeam:Show()

     

    --draw Initial Beam

    if self.enabled then

    self:DebugRay(self.entity:GetPosition(true), self.EndPoint:GetPosition(true), self.LaserBeam)

    end

    self.OldStartPosition = self.entity:GetPosition(true)

    self.OldEndPosition = self.EndPoint:GetPosition(true)

    end

     

     

    -- Draws the Beam

    function Script:DebugRay(startpos_as_vec3, endpos_as_vec3, spriteEntity_as_sprite)

    local startpos = startpos_as_vec3

    local endpos = endpos_as_vec3

    local spriteEntity = spriteEntity_as_sprite

    local midpoint = ((startpos + endpos) / 2)

     

    local raydistance = math.sqrt((endpos.x - startpos.x)^2 + (endpos.y - startpos.y)^2 + (endpos.z - startpos.z)^2)

     

    spriteEntity:SetPosition(midpoint,true)

    local allignvector = startpos - endpos

    spriteEntity:SetViewMode(6)

    spriteEntity:AlignToVector(allignvector:Normalize(),2)

    spriteEntity:SetSize(self.BeamHeight, raydistance)

    end

     

     

     

    function Script:UpdateWorld()

    --check if the positions moved

    if (self.PhysicsUpdate == false) and self.enabled then

    if ((self.OldStartPosition == self.entity:GetPosition(true)) ~= (self.OldEndPosition == self.EndPoint:GetPosition(true))) then -- Only update if moved

    self:DebugRay(self.entity:GetPosition(true), self.EndPoint:GetPosition(true), self.LaserBeam)

    self.OldStartPosition = self.entity:GetPosition(true)

    self.OldEndPosition = self.EndPoint:GetPosition(true)

    end

    end

     

    end

     

     

     

    function Script:UpdatePhysics() -- update in physics to save some processing cycles

    --check if the positions moved

    if (self.PhysicsUpdate == true) and self.enabled then

    if ((self.OldStartPosition == self.entity:GetPosition(true)) ~= (self.OldEndPosition == self.EndPoint:GetPosition(true))) then -- Only update if moved

    self:DebugRay(self.entity:GetPosition(true), self.EndPoint:GetPosition(true), self.LaserBeam)

    self.OldStartPosition = self.entity:GetPosition(true)

    self.OldEndPosition = self.EndPoint:GetPosition(true)

    end

    end

    end

     

    function Script:Enable()--in

    if self.enabled==false then

    self.enabled=true

    self.component:CallOutputs("_Enabled")

    end

    end

     

    function Script:Disable()--in

    if self.enabled then

    self.enabled=false

    self.component:CallOutputs("_Disabled")

    end

    end

     

    --This function will be called when the entity is deleted.

    function Script:Detach()

    self.BeamMaterial:Release()

    self.LaserBeam:Release()

    end

     

     

     

    • Upvote 1
  5. Currently to expose settings to the editor users have to use the format:

     

    
    

    Script.variable = value --Type "Label"

     

    I propose a breaking change to the way editor properties function.

     

    First the syntax/method would need to change.

     

    Script would become a table:

    
    

    Script = {}

     

    All entries would be become named variables holding tables:

    
    

    Script = {

    --variable = {value, "type as string","label as string"}

    ground_height = {100, "uinteger","Ground Height" },

    jump_height = {4,"uinteger", "Jump Height"},

    player_name = {"","string", "Player Name"}

    }

     

    What this would mean is the editor would need to actually load the script itself, which brings a few drawbacks.

    1. the entire script would need to be able to load without any errors.

    2. if the script fails there is a chance that the properties will fail to load.

    3. if the script property section is malformed or wrong it will not show up.

     

    or just grab it from the debug info (i would assume it's rather hard)

     

    A solution for this would be:

    1. To hold a copy of the properties in memory/cache and restore them when the properties returns.

    2. add a small reset button to reset the value to default. (since the editor will always be remembering the last value).

     

    If this is implemented there is an additional benefit:

    
    

    function Script:test1()

    return {"Good","Neutral","Bad"}

    end

     

    Script = {

    --variable = {value, "type as string","label as string"}

    ground_height = {100, "uinteger","Ground Height" },

    jump_height = {4,"uinteger", "Jump Height"},

    player_name = {"","string", "Player Name"},

    dynamic_list = {self:test1() ,"choice","Team"}

    }

     

     

    You can now dynamically populate lists!!

    1 draw back is you would either need to forward declare functions or put the functions above the script declaration.

     

     

    Even if this is not implemented, it could be useful if editor plugins are ever added.

    • Upvote 1
  6. I've had this issue too. With 3 monitors twitch based gaming can become a pain. This code forcibly puts the mouse back in the windows active area. http://www.leadwerks.com/werkspace/topic/10211-trapping-the-mouse-to-the-current-window/

    The only issue is, as already mentioned in this thread, that if you move the mouse fast enough you can click outside the window. Leadwerks will as usual keep polling for input.

     

    The code is from when Leadwerks use to have an app.lua instead of main.lua.

  7. I also have a trigger script. It is a comprehensive clone of the unity functions. It keeps track of every entity that enters, stays, and leaves a trigger. It also provides 3 functions that other scripts can use to interact with the trigger. It gives you the option of triggering on props, characters, and projectiles

     

    
    

    --[[

    Title: Enhanced Collision Trigger

    By: Einlander

    Version: 1.0 First public release

    Function: Per-Entity collision trigger. With an additional OnTriggerExit output. Made to mimic unity3d collision handler

    Details: Some times you need to have a trigger that will not only know that it is triggered, but know how many entities triggered it, and when any given trigger has left it's trigger area.

    Extras: Provides 3 new trigger functions for other scripts to use.

    Notes:

    -- on collision

    a collision has happened

    Check if the entity is on the entity collision list

    If not, it is placed on the entity list

    call OnEnter

    If it is on the entity list

    call OnStay

    -- check during physics -because it's certian to be run, but not as often as update world

    check to see if collision happened last run

    No collision has happened last time because collision flag is still off

    remove from entity list

    OnTriggerExit

    Collsion happened

    set the entity collision flag to false

    wake up the entity so the trigger will continue detecting it.

    ]]--

    Script.enabled = true --bool "Enable"

    Script.debugtext = false -- bool "Debug Text"

    Script.spoofcollision = false --bool "Spoof Trigger"

    Script.triggerProps = true --bool "Trigger Props"

    Script.triggerCharacters = true --bool "Trigger Characters"

    Script.triggerProjectiles = true --bool "Trigger Projectiles"

     

    function Script:Start()

    if self.spoofcollision then

    -- [spoof collision trigger] dont know if this would actually work

    Collision.EnhancedCollisionTrigger = Collision.Trigger --Masqurade as the original trigger collision

    else

    Collision.EnhancedCollisionTrigger = Time:GetCurrent() -- hopefully no collisions here :)

    end

     

    -- make sure the trigger interacts with most things

    -- should be selectable

    if self.triggerProps then

    Collision:SetResponse(Collision.EnhancedCollisionTrigger, Collision.Prop, Collision.Trigger)

    end

    if self.triggerCharacters then

    Collision:SetResponse(Collision.EnhancedCollisionTrigger, Collision.Character, Collision.Trigger)

    end

    if self.triggerProjectiles then

    Collision:SetResponse(Collision.EnhancedCollisionTrigger, Collision.Projectile, Collision.Trigger)

    end

    self.entity:SetCollisionType(Collision.EnhancedCollisionTrigger)

    self.entitydb = {}

    end

     

     

    function Script:Enable()--in

    if self.enabled==false then

    self.enabled=true

    --self.component:CallOutputs("Enable")

    end

    end

     

    function Script:Disable()--in

    if self.enabled then

    self.enabled=false

    --self.component:CallOutputs("Disable")

    end

    end

     

    function Script:OnTriggerEnter(entity)

    end

     

    function Script:OnTriggerStay(entity)

    end

     

    function Script:OnTriggerExit(entity)

     

    end

     

    function Script:UpdatePhysics()

    if self.enabled then

    -- check to see if entity is still inside the trigger

    for key, value in pairs (self.entitydb) do

    if self.entitydb[key].hadcollision == false then -- check if the entity had a collision from the last check

    -- on exit

    self.component:CallOutputs("OnTriggerExit")

    self:OnTriggerExit(self.entitydb[key].entity)

    if self.entitydb[key].script then

    if type(elf.entitydb[key].script.OnTriggerExit)=="function" then -- Check to see if entity has a script with the right function in it, then call it.

    self.entitydb[key].script:OnTriggerExit(self.entity)

    end

    end

    table.remove(self.entitydb, key) -- got to remove it, or else we will end up indexing nil values

    else

    self.entitydb[key].hadcollision = false -- set it to false because if it is still in the trigger it will get activated again

    self.entitydb[key].entity:AddForce(0,0,0) -- wake up the entit's physics. This is a work around because by default, physics objects go to sleep and the trigger can no longer see them. doesnt actually move entity

    end

    end

    end

    end

     

    function Script:Collision(entity, position, normal, speed)

    if self.enabled == true then

    -- check if entity is in the list

    local entitymatch = false

    for key, value in pairs (self.entitydb) do

    if self.entitydb[key].entity == entity then -- found it in the list

    self.entitydb[key].hadcollision = true

    entitymatch = true

    self.component:CallOutputs("OnTriggerStay")

    self:OnTriggerStay(entity)

    if entity.script then

    if type(entity.script.OnTriggerStay)=="function" then -- Check to see if entity has a script with the right function in it, then call it.

    entity.script:OnTriggerStay(self.entity)

    end

    end

    end

    end

    if entitymatch == false then -- add new object to the list

    local newEntity = {}

    newEntity.entity = entity

    newEntity.hadcollision = true

    table.insert(self.entitydb, newEntity)

    entitymatch = true

    self.component:CallOutputs("OnTriggerEnter")

    self:OnTriggerEnter(entity)

    if entity.script then

    if type(entity.script.OnTriggerEnter)=="function" then -- Check to see if entity has a script with the right function in it, then call it.

    entity.script:OnTriggerEnter(self.entity)

    end

    end

    end

    end

    end

     

     

    --This function will be called when the entity is deleted.

    function Script:Detach()

    ReleaseTableObjects(self.entitydb)

    end

     

     

    function Script:PostRender(context)

    if self.enabled then

    if self.debugtext then

    context:SetBlendMode(1)

    context:SetColor(1,1,1)

    context:DrawText("Total Contained Entities: " .. #self.entitydb,0,36)

    end

    end

    end

     

     

     

    Entities interacting with the trigger can use:

     

    
    

    function Script:OnTriggerEnter(entity)

    end

     

    function Script:OnTriggerStay(entity)

    end

     

    function Script:OnTriggerExit(entity)

    end

    • Upvote 2
  8. you can use luajit ffi, if you have to. http://www.leadwerks.com/werkspace/blog/120/entry-1182-luajit-awesome-luajit-enet-loaded/

     

    the code there is super old, so just take it as inspiration because it's so bad.

    This are some repos that deal with curl in lua.

     

    https://github.com/Playermet/CurLua

    https://gist.github.com/LPGhatguy/09d3955207ab35d96e97

     

    These will not work in the sandbox and thus not in the game player.

     

    As you probably know. You need to have the proper curl lib for the os installed in the same directory as the exe.

  9. Make a material with the 'transparent.shader'

     

    Then use this code:

    function Script:Start()
     if not DEBUG then
       local material = Material:Create()
       material:SetBlendMode(5)--Blend.Invisible
       self.entity:SetMaterial(material)
       material:Release()
     end
    end
    

     

    This will make whatever the object is invisible at runtime (F6), but visible when debugging (f5) or in the editor.

  10. I have done something similar. I had a script that registered players to a playermanager.

     

     

    The player manager is added to a pivot

    
    

    function Script:Start()

    --= self.entity.script:overwatch_registerplayer(playerEntity)

    --[[ REQUIRE A CERTIAN OVERWATCH VERSION AND ABOVE. OVERWATCH VERSION SHOULD ALSO STATE HOW FAR BACK IT STAYS COMPATIBLE ]]

    -- Would prefer that the manager finds the entities itself, but thats not a very easy task without ahead of time preperations before this script is even loaded

    -- so we have the players self register

    -- Register it's existance

    if overwatch ~= nil then

    if overwatch.playermanager == nil then

    overwatch.playermanager = {}

    overwatch.playermanager.players = {}

    overwatch.playermanager.enabled = true

    overwatch.playermanager.entity = self.entity

    overwatch.playermanager.instances = 0

    end

    else

    Debug:Error("Overwatch System Not Loaded")

    end

    overwatch.playermanager.instances = overwatch.playermanager.instances + 1 -- i thought it would be intresting to know how many times an overwatch unit is placed in the map

    -- If the same script that saet the entity first is not the same one doing the test, we have too many entities

    if overwatch.playermanager.entity ~= self.entity then

    Debug:Error("Multiple inscances of Overwatch Player Manager: " .. tostring(overwatch.playermanager.instances) .. " instances")

    -- it wont even get past 2

    end

    end

     

    function Script:overwatch_registerplayer (playerEntity) -- Adds player to the list of forces to be acted apon

    local i

    for i =0, #overwatch.playermanager.players, 1 do

    if overwatch.playermanager.players == playerEntity then

    return false -- its already in it

    end

    end

    table.insert(overwatch.playermanager.players,playerEntity)

    return true

    end

    function Script:overwatch_unRegisterplayer (playerEntity) -- Remove player from the list of forces to be acted apon

    local i

    for i =0, #overwatch.playermanager.players, 1 do

    if overwatch.playermanager.players == playerEntity then

    table.remove(overwatch.playermanager.players,i)

    return true

    end

    end

    return false -- its already removed/never added

    end

     

    function overwatch_registerplayer (playerEntity) -- global function: points to local function

    overwatch.playermanager.entity.script:overwatch_registerplayer(playerEntity)

    end

     

    function overwatch_unRegisterplayer (playerEntity) -- global function: points to local function

    overwatch.playermanager.entity.script:overwatch_unRegisterplayer(playerEntity)

    end

     

    --[[

    function Script:UpdateWorld()

     

    end

    --]]

     

    --[[

    function Script:UpdatePhysics()

     

    end

    --]]

     

    --[[

    function Script:Collision(entity, position, normal, speed)

     

    end

    --]]

     

    --[[

    function Script:Draw()

     

    end

    --]]

     

    --[[

    function Script:DrawEach(camera)

     

    end

    --]]

     

     

    --This function will be called after the world is rendered, before the screen is refreshed.

    --Use this to perform any 2D drawing you want the entity to display.

    function Script:PostRender(context)

    context:SetBlendMode(Blend.Alpha)

    context:SetColor(1,1,1,1)

    context:DrawText("PlayerManager Player Count:" .. tostring(#overwatch.playermanager.players),2,200)

    context:SetBlendMode(1)

    context:SetColor(0,0,0,0.5)

    end

     

     

    --[[

    --This function will be called when the entity is deleted.

    function Script:Detach()

     

    end

    --]]

     

    --[[

    --This function will be called when the last instance of this script is deleted.

    function Script:Cleanup()

     

    end

    --]]

     

     

     

    And in the Fps player script we register it.

     

    function Script:Start()
    overwatch_registerplayer(self.entity)
    end
    

     

    I basically created a global function that pointed to a local function.

     

    If I wanted I could have the player manager poll in the Script:UpdateWorld() and do things to the players. That was the goal, but I never had enough time to do what I envisioned and dropped the project.

     

    Edit--

    This is the base system that everything loads into. Also added into a pivot

     

    if overwatch == nil then -- Create the base table that all Overwatch systems use.
    overwatch = {}
    end
    

     

    it loads a global table for all the other modules to find.

  11. **Operating system or device - Leadwerks Version:**

    • Windows 7 Pro x64
    • Leadwerks 4.2 Beta BuildID:1479910

    **Issue description** (what happened, and what was expected):

    • -Issue:
      • Models added to the terrain vegetation layer do not show up in game. The same model used for vegitation will reflect if manually dragged into the world.

      [*]-What was expected

      • Models to show reflection in the water.

    **Steps to reproduce:**

    • Create scene.
    • Add terrain
    • Add skybox
    • Add models to vegetation layer
    • Run Game

    **Link to minimal example project**

    • No project just an images:
      • hwjIWS6.jpg
      • kRQuVjc.jpg

    **EDIT**


    So It seems that the game defaults to a medium water quality instead of high. :/

  12. Honestly, the bigger question there is should we have single scripts that are 494+ lines long? We should not. If it gets that big it's a great time to try and refactor things out to other scripts (make a system). Now, when I have files this big if I'm prototyping things out, it's always in the back of my mind to refactor out to it's own system/class as it'll improve the readability a ton. It's pretty rare that any sub-system would need to be that big. Just to give an alternative view. smile.png

     

    Great if you are using c++ but the lua export version doesn't support linking to external files.

  13. This is what I found when I was programming something. it also has resources and sources I used linked

     

    function Script:LookAt(start,target)
       --http://www.leadwerks.com/werkspace/topic/10191-short-example-of-mathatan2/page__hl__lookat
       --http://stackoverflow.com/questions/1251828/calculate-rotations-to-look-at-a-3d-point
       --http://leadwerks.wikidot.com/wiki:face-entity
    
       --// Calculate angle from point A towards point B
       local tv = (target - start) 
    
       local tRoty = Math:ATan2(tv.x, tv.z)
       --local tRotx = 
       if tv.z >= 0 then    
           tRotx = -Math:ATan2(tv.y* Math:Cos(tRoty), tv.z)
           else    
           tRotx = Math:ATan2(tv.y* Math:Cos(tRoty), -tv.z)
       end
       tRotz = Math:ATan2( Math:Cos(tRotx), Math:Sin(tRotx) * Math:Sin(tRoty) )
       return Vec3(tRotx,tRoty,tRotz-90)
    end
    

×
×
  • Create New...