Jump to content

CrazyM

Members
  • Posts

    86
  • Joined

  • Last visited

Everything posted by CrazyM

  1. The cube is using the default flat shading in Blender. I'm using Blender 2.71 and the latest official Leadwerks exporter from github.
  2. Unfortunately, there is no shortage of unappreciative jerks who think tutorial means "Make my game for me". I have really enjoyed your Project Saturn series. Being new to Leadwerks myself, it's been a great series to help me apply my existing knowledge to the Leadwerks workflow, I'd love to see the series continue. I would also enjoy learning how to use C++ and Lua together.
  3. Because digging through the source is not the same as documentation.
  4. I tested this in App.lua, but it should work the same in the App.cpp. it does work. Create a variable to store the window size prevScreenSize = Vec2(0,0) Get the initial window size in start self.prevScreenSize = Vec2(Math:Round(self.window:GetWidth()), Math:Round(self.window:GetHeight())) Check for change, update the variable when change is detected, and call a function if self.prevScreenSize.x ~= Math:Round(self.window:GetWidth()) or self.prevScreenSize.y ~= Math:Round(self.window:GetHeight()) then self.prevScreenSize = Vec2(Math:Round(self.window:GetWidth()), Math:Round(self.window:GetHeight())) self:ScreenSizeChanged() end function App:ScreenSizeChanged() System:Print("ScreenSizeChanged: " .. self.prevScreenSize:ToString()) end
  5. If there isn't a built in function, maybe store the window size in a variable in start, then compare that variable with the current window size and when it's different, update the variable with the current size and call a separate function. If getting the current window size is expensive, you could limit a check to every n iterations of the the loop. Possibly use System::AddHook? I'm not new to programming, but I am new to Leadwerks, so this may be a terrible idea.
  6. In the example output above, the pick was from the -X side, it should have returned (-1,0,0). My test is using a grid aligned cube created in blender, it has a (0,0,0) rotation in the Leadwerks map. The problem does not exist when using a CSG, I am only able to create the problem with the Blender cube import. Interestingly, good values are returned from most of the face surface area from any face, but each face has a seemingly random spot that returns bad values. I have tried a default blender cube, which is off grid by default, with a center origin, a grid aligned blender cube with a center origin, and a grid aligned blender cube with a corner origin, they all produce the same result. I have no idea how a six sided cube can return different normal values from different areas of the same face.
  7. Okay, I made a much simpler script to try to eliminate any other potential causes. It's still not returning clean -1, 0, 1 values, but rather fractions. Script.player = nil --entity "Player" Script.reticle = "" --path "Reticle" "Tex file (*.tex):tex;" window = Window:GetCurrent() world = World:GetCurrent() context = Context:GetCurrent() pickradius = 0.1 pickinfo = nil mousePos = nil reticleOptic = nil function Script:Start() pickinfo = PickInfo() reticleOptic = Texture:Load(self.reticle) end function Script:UpdateWorld() mousePos = window:GetMousePosition() if (self.player.script.camera:Pick(mousePos.x, mousePos.y, pickinfo, pickradius, true)) then if pickinfo ~= nil then if pickinfo.entity:GetKeyValue("name") == "Block" then --System:Print("Entity: " .. pickinfo.entity:GetPosition():ToString()) --System:Print("Position: " .. pickinfo.position:ToString()) System:Print("Normal: " .. pickinfo.normal:ToString()) end end end end function Script:PostRender(context) if reticleOptic ~= nil then context:SetColor(1,1,1,1) context:SetBlendMode(Blend.Alpha) context:DrawImage(reticleOptic, context:GetWidth()/2-32, context:GetHeight()/2-32, 64, 64) context:SetBlendMode(Blend.Solid) end end Normal: -0.968764, -0.175351, 0.175352
  8. This is what I'm getting when camera picking the X face of a cube placed on the ground. if (self.player.script.camera:Pick(mousePos.x, mousePos.y, pickinfo, pickradius, true)) then System:Print("Entity: " .. pickinfo.entity:GetPosition():ToString()) System:Print("Position: " .. pickinfo.position:ToString()) System:Print("Normal: " .. pickinfo.normal:ToString()) end Entity: -3.000000, 1.000000, 0.000000 Position: -2.555588, 1.315765, -0.250583 Normal: 0.740685, 0.526274, -0.417638
  9. Your right, they are correct, it looks like the pickinfo.normal is describing the exact hit position, which is great for adding an impact particle effect at the location a hit occurs, though I wish pickinfo also had a separate return value that simply described the side of the hit. Good for geometric shape placement pickinfo.entity:GetPosition() + pickinfo.normal = exact hit position
  10. Forgive me if this is a silly question, but my previous experience with collision normals is as follows: collision on X should return Vec3(1,0,0) collision on -X should return Vec3(-1,0,0) collision on Y should return Vec3(0,1,0) collision on -Y should return Vec3(0,-1,0) collision on Z should return Vec3(0,0,1) collision on -Z should return Vec3(0,0,-1) Leadwerks pickinfo.normal returns a fraction depending on where on a face the collision occurs. Is pickinfo.face the "normal" function I'm used to, and maybe pickinfo.normal is describing the hit point? If this is the case, how do you use pickinfo.face, I couldn't find much documentation on it? Thanks!
  11. I finally got everything working to some degree. It could use some more refinement, but this was just an API familiarization exercise for me. Thanks everyone for you input and assistance. Just in case anyone is interested in the basis of a Minecraft style block pick/placement script, here it is. 1. Create a one unit (meter?) cube in your favorite 3D app. 2. Import and save as a prefab. 3. Create a pivot, and attached this script to it, then parent the pivot to your FPSPlayer. 4. Link in the player, prefab, a pickup sound, a placement sound, and a texture reticle. Left Ctrl = toggles in and out of block building mode Right mouse click = places a block Left mouse click = removes a block Cheers! EDIT: Updated to fix some issues Script.player = nil --entity "Player" Script.blockPrefab = "" --path "Prefab" "Prefab (*.pfb):pfb" Script.pickSound = "" --path "Pick Sound" "Sound File (*.wav):wav;Ogg Vorbis (*.ogg):ogg" Script.placeSound = "" --path "Place Sound" "Sound File (*.wav):wav;Ogg Vorbis (*.ogg):ogg" Script.reticle = "" --path "Reticle" "Tex file (*.tex):tex;" window = Window:GetCurrent() world = World:GetCurrent() context = Context:GetCurrent() pickradius = 0.1 block = nil blockMode = false pickinfo = nil mousePos = nil pickSnd = nil placeSnd = nil reticleOptic = nil function Script:Start() pickinfo = PickInfo() pickinfoTest = PickInfo() pickSnd = Sound:Load(self.pickSound) placeSnd = Sound:Load(self.placeSound) reticleOptic = Texture:Load(self.reticle) end function Script:UpdateWorld() mousePos = window:GetMousePosition() -- Toggle blockMode if window:KeyHit(Key.ControlKey) then if blockMode == false then blockMode = true else blockMode = false end end -- blockMode if blockMode == true then -- Load a new block if block == nil then block = Prefab:Load(self.blockPrefab) block:SetPickMode(0) -- ignore block:SetCollisionType(4) block:SetKeyValue("name","Block") end -- Position the block grid aligned and normal offset if block ~= nil then if (self.player.script.camera:Pick(mousePos.x, mousePos.y, pickinfo, pickradius, true)) then local blockPos = Vec3(Math:Round(pickinfo.position.x), Math:Round(pickinfo.position.y), Math:Round(pickinfo.position.z)) block:SetPosition(blockPos, true) end end -- Place the block if window:MouseHit(2) then -- right mouse button if placeSnd ~= nil then placeSnd:Play() end block:SetPickMode(2) -- Polygon block:SetCollisionType(2) block:SetShape(Shape:Box()) block:SetRotation(Vec3(0,0,0), true) block = nil end -- Release the block if window:MouseHit(1) then -- left mouse button if pickinfo.entity:GetKeyValue("name") == "Block" then System:Print("Release") pickinfo.entity:Release() if pickSnd ~= nil then pickSnd:Play() end end end else -- Not in blockMode, release the block if block ~= nil then block:Release() block = nil end end end function Script:PostRender(context) if reticleOptic ~= nil then context:SetColor(1,1,1,1) context:SetBlendMode(Blend.Alpha) context:DrawImage(reticleOptic, context:GetWidth()/2-32, context:GetHeight()/2-32, 64, 64) context:SetBlendMode(Blend.Solid) end end
  12. @shadmar - After you mentioned it, I started looking deeper into my prefab and the Leadwerks collision rules. I have made a little progress. I swapped my CSG block for a basic blender cube, and I'm now setting SetPickMode(0) and SetCollisionType(4) on the instantiated prefab so that it won't be picked while positioning for placement. I've adjusted my camera picks to use collision type to (2), and after I place a block I set SetPickMode(1) and SetCollisionType(2) so that it should be pickable again. Once a block is placed however, I can collide with it when walking up to it or jumping on top of it with the FPSPlayer, but I still can't camera pick the placed blocks. I have the exact same scenario using the CSG cube prefab after SetPickMode and SetCollisionType adjustments, the collider stops me from walking through it, but I can't pick it from the camera. These pick failure are what I was perceiving as Key/Value failures. If I place an instance of my prefab in the scene at design time, I can pick it at runtime and read the Key/Value, but not when instantiated during runtime. I tried adding world:Update and world:Render() after block placement just in case some physics update was necessary, but it had no effect. So it seems something must be required to commit pickmode and collisiontype changes at runtime, but I can't seem to figure out what. The current state of my script: Script.player = nil --entity "Player" window = Window:GetCurrent() world = World:GetCurrent() context = Context:GetCurrent() pickradius = 0.1 block = nil blockMode = false pickinfo = nil mousePos = nil function Script:Start() pickinfo = PickInfo() end function Script:UpdateWorld() mousePos = window:GetMousePosition() -- Toggle blockMode if window:KeyHit(Key.ControlKey) then if blockMode == false then blockMode = true else blockMode = false end end -- blockMode if blockMode == true then -- Load a new block if block == nil then block = Prefab:Load("Prefabs/CM/Cube.pfb") block:SetPickMode(0) -- ignore block:SetCollisionType(4) block:SetKeyValue("name","Block") end -- Position the block grid aligned and normal offset if block ~= nil then if (self.player.script.camera:Pick(mousePos.x, mousePos.y, pickinfo, pickradius, true, 2)) then block:SetPosition(Vec3(math.floor(pickinfo.position.x), math.floor(pickinfo.position.y), math.floor(pickinfo.position.z)) + Vec3(pickinfo.normal.x, pickinfo.normal.y, pickinfo.normal.z)) end end -- Place the block if window:MouseHit(2) then -- right mouse button block:SetPickMode(1) -- sphere block:SetCollisionType(2) block = nil end -- Debug if pickinfo ~= nil then if pickinfo.entity ~= nil then System:Print("pickinfo: " .. pickinfo.entity:GetKeyValue("name")) end end -- Release the block if window:MouseHit(1) then -- left mouse button if (self.player.script.camera:Pick(mousePos.x, mousePos.y, pickinfo, pickradius, true, 2)) then if pickinfo.entity:GetKeyValue("name") == "Block" then pickinfo.entity:Release() end end end else -- Not in blockMode, release the block if block ~= nil then block:Release() block = nil end end end
  13. @Aggor - yes the GetKeyValue() with upper case "Name" was a test, I tried upper and lower, they both produce the same error. @Haydenmango - Thanks, I'll try GetClass() and GetClassName() out. @Guppy - This sounds great because it would allow me to categories everything, and in my case I really only need a bool check, but can you spot anything I'm doing wrong with the code above, and why it errors: I instantiate the prefab, then set a key/value pair with name/Block block = Prefab:Load("Prefabs/CM/Block.pfb") block:SetKeyValue("name","Block") then, in the pickinfo I'm attempting to read the key/value pair System:Print(pickinfo.entity:GetKeyValue("name")) But the Print is producing this error: argument #3 is 'string'; '[no object]' expected. Thanks guys!
  14. Let me ask about entity identification another way. If I have a collision with an entity, what is the best way to distinguish the entity from another? For example: instantiated blocks have the name "Block" and the ground the blocks sit on is a CSG with the name "Ground". If I want to Release() blocks, but not the ground, I need to check the collision entity to determine it's a block and to Release it, or if it's the ground and to ignore the collision. Should I use the name of the entity (how do I get this), does Leadwerks have a layer system that I can place items on and check if the collision entity is on that layer, or maybe place a script on the ignore items and check for the type? Thanks
  15. I watched Josh's video importing the monster truck to have the shapes automatically generated, but I wasn't sure how that would work in blender since you can't have multiple items with the same name in blender. Unless Leadwerks is just ignoring iterative numbers after the [Collision] name. I got this working using the above method, mostly just because I wanted to understand it a bit better, but I'll also try it the other way just to test the result. Thanks!
  16. Ahhh, I found it. Right click your model from the Assets tab and select [Generate Shape].
  17. I have created a small building model in blender and included a very low polly version of it for use as a physics shape, but I can't figure out how to make a physics shape out of it in Leadwerks. [save as Shape] is greyed out in the scene browser when I try to right click on the mesh. Any help is appreciated, Mike
  18. I'm familiarizing myself with Leadwerks and so I have a simple test map that lets me place block prefabs like Minecraft. How can I retrieve the name from a pickinfo.entity? I tried the following, but it throws an error in Print in the window:MouseDown(1) check: (argument #3 is 'string'; '[no object]' expected.) function Script:UpdateWorld() if block == nil then block = Prefab:Load("Prefabs/CM/Block.pfb") block:SetKeyValue("name","Block") block:SetCollisionType(Collision.Prop) end local pickinfo = PickInfo() local mousePos = window:GetMousePosition() if (self.player.script.camera:Pick(mousePos.x, mousePos.y, pickinfo, pickradius, true)) then block:SetPosition(Vec3(math.floor(pickinfo.position.x), math.floor(pickinfo.position.y), math.floor(pickinfo.position.z)) + Vec3(pickinfo.normal.x, pickinfo.normal.y/2, pickinfo.normal.z)) end if window:MouseDown(2) then -- Place the block block = nil end if window:MouseDown(1) then -- Delete the block if pickinfo ~= nil then if pickinfo.entity ~= nil then System:Print(pickinfo.entity:GetKeyValue("name")) end --if pickinfo.entity:GetKeyValue("Name") == "Block" then -- pickinfo.entity:Release() --end end end end The other issue I'm having is that the placed prefabs have no physics collision. Thanks, Mike
  19. Looks like my duplicated cube had a duplicate of the script and the Camera was not bound to the exposed entity property. Removing the script on the second cube, and removing the Vec3 cleared the errors. I moved my self.right setter to the Start function. Thanks for helping, sorry for the Leadwerks noob mistakes!
  20. That solved the raycast problem, But I'm still having issues drawing the line for debugging. I'm getting an error with no error message on the following line: local pos = self.camera:Project(Vec3(self.position)) I have the camera defined outside the function as: Script.camera=Entity--Entity And I linked the scene camera to this property in the editor.
  21. [self.right] is defined outside of the function as: Script.right=Vec3(1, 0, 0)--Vec3 I found the problem, I had accidentally used a lowercase in the [pickInfo] variable in the Pick function. It's working now. Thanks
  22. I'm trying to translate my raycasting experience in Unity and Blender GE to Leadwerks, but I'm having a hard time connecting the dots. My test scene includes one cube on the ground, and another cube next to the first (on X axis) and raised above the ground and above the height of the ground cube so that when the game starts, the raised cube falls next to the ground cube. I have a lua script attached to the ground cube and I'm trying to cast a ray from the ground cubes position to a position farther down the x axis so that the raised cube will intersect when it falls. This is my code in the UpdateWorld function. I get an blank error window. I'm very inexperienced with Leadwerks, so I may be going about it all wrong, but this is what I've gathered from the docs. Thanks for any help you can provide. function Script:UpdateWorld() self.position = self.entity:GetPosition() self.right = Vec3(self.position.x + self.right.x, self.position.y, self.position.z); local pickInfo = PickInfo() local clear = true local world = World:GetCurrent() local context = Context:GetCurrent() local pos = self.camera:Project(Vec3(self.position)) local pRight = self.camera:Project(Vec3(self.right)) context:DrawLine(pos.x, pos.y, pRight.x, pRight.y) if (world:Pick(self.position, self.right, pickinfo, 0.0, true)) then clear= false end end
  23. Thanks, so is the Linux version the same license or a separate license?
×
×
  • Create New...