Jump to content

Josh

Staff
  • Posts

    23,272
  • Joined

  • Last visited

Everything posted by Josh

  1. Josh

    Future Ideas

    That's probably accurate. It's probably impossible to make a networked system with the problems I described.
  2. Josh

    Vec3 setting

    And it's better to use require() than dofile()!
  3. For the crawler model, I ended up using the Reset() function to get around the problem of repositioning the controller. This is written for multistate Lua, so it needs some small changes to work: dofile("scripts/base.lua") dofile("scripts/math.lua") dofile("scripts/linkedlist.lua") AINodeScanRange=100 AnimationWalk=0 AnimationIdle=1 animspeed={} animspeed[AnimationWalk]=0.036 animspeed[AnimationIdle]=0.01 dummynode=LoadModel("abstract::info_ai_node.gmf") if dummynode~=nil then dummynode:Hide() end function Cleanup() if dummynode~=nil then dummynode:Free() dummynode=nil end end function Reset(model) local entity=entitytable[model] if entity==nil then return end entity.controller:SetPosition(Vec3(model.position.x,model.position.y+0.9,model.position.z)) entity.angle=model.rotation.y+180.0 model:SetTarget(nil,0) end function UnlockKeys(model) model:SetTarget(nil) end function SetKey(model,key,value) local entity=entitytable[model] if entity==nil then return 1 end if key=="enabled" then if entity.controller~=nil then if value=="0" then entity.controller:SetMass(0) else entity.controller:SetMass(10) end end end return base_SetKey(model,key,value) end function Spawn(model) local entity=base_Spawn(model) entity.angle=model.rotation.y entity.controller=CreateController(1.8,0.45,0.25,45) entity.controller:SetPosition(entity.model.position) entity.controller:SetRotation(entity.model.rotation) entity.controller:Move(Vec3(0,0.9,0)) entity.controller:SetCollisionType(1,0) entity.controller:SetMass(10) entity.currentanimation=0 if entity.model:CountAnimations()<2 then --LoadAnimation(entity.model,"abstract::actor_cartoon2.gmf") end function entity:ChooseNewNode(ainode) local nodes={} local i local count=0 local newtarget --Create a table of all AI nodes this node is connected to for i=0,15 do nodes[count]=ainode:GetTarget(i) if nodes[count]~=nil then if nodes[count]~=self.prevnode then --avoid doubling back count=count+1 end end end --Choose a random node if count>0 then newtarget=nodes[math.random(0,count-1)] self.model:SetTarget(newtarget,0) else --no node found, so let's just use the previous node --self.model:SetTarget(self.prevnode,0) self.model:SetTarget(nil,0) end --if ainode~=nil then self.prevnode=ainode --end end function entity:Update() local dx,dz,p local target local ainode local closestainode=nil local closestdistance=10000000.0 local perfectangle local noderadius local movement=0 target=self.model:GetTarget(0) --b=CurrentWorld().entities --If target is nil, we need to choose an AI node to move to if target==nil then if dummynode~=nil then for ainode in iterate(dummynode.reference.instances) do if ainode~=self.prevnode then if ainode:Hidden()==0 then d=EntityDistance(ainode,self.model) if d<AINodeScanRange then --dismiss nodes that are far away if PointVisible(self.model.aabb:Center(),ainode.mat:Translation(),0,COLLISION_AILINEOFSIGHT)==1 then --line-of-sight test if d<closestdistance then closestdistance=d closestainode=ainode end end end end end end --Found a valid AI node, so set the target if closestainode~=nil then self.model:SetTarget(closestainode,0) end end end --We have a target node to move to if target~=nil then --Figure out angle between actor and target dx=target.mat.tx-self.model.mat.tx dz=target.mat.tz-self.model.mat.tz perfectangle=math.deg(math.atan2(-dx,dz)) --Calculate angle between the actor and the target and adjust as necessary. --This provides a smoother more natural movement, and the character takes --the easiest path instead of pointing straight at the target node. local noderadius=tonumber(target:GetKey("radius","4.0")) local noderange=tonumber(target:GetKey("range","1.0")) --Get the distance between the projected entity vector and the node model:SetRotation(Vec3(0,self.angle,0),1) local d=LineCircleDistance(model.mat.tx,model.mat.tz,model.mat.tx+model.mat.kx*100.0,model.mat.tz+model.mat.kz*100.0,target.mat.tx,target.mat.tz,3.0,1,0) --If the distance is over the radius, increment the angle towards the node local turnradius = 1.0 turnradius = turnradius+clamp( 90.0*(1.0 - clamp( d/1.0,0 ,1) ),0,10 ) if math.abs(d)>noderadius then self.angle=IncAngle(perfectangle,self.angle,turnradius*AppSpeed()) end --Choose new node when target node is close enough --We only care about the 2D distance on the XZ plane if math.sqrt(dx*dx+dz*dz)<noderange then self:ChooseNewNode(target) end movement=2 self.currentanimation=0 else movement=0 self.currentanimation=1 end --Update the controller self.controller:Update(self.angle,movement,0,0,40,1) self.model:SetPosition(self.controller.position) self.model:SetRotation(self.controller.rotation) self.model:Move(Vec3(0,-0.9,0)) self.model:Turn(Vec3(0,180,0)) local frame=AppTime()*0.08 frame=math.mod(frame,130-70)+70 if EntityCulled(model,fw.Main.camera)==0 then self.model:Animate(frame,1,0,1) end end return entity end function Update(model) local entity for model,entity in pairs(entitytable) do if entity.model:Hidden()==0 then if entity.enabled~=0 then entity:Update() end end end end function Kill(model) local entity=entitytable[model] if entity~=nil then if entity.controller~=nil then entity.controller:Free() entity.controller=nil end end base_Kill(model) end
  4. I meant a heightfield where there is just a pointer to the height data that can be changed at any time. PhysX heightfields can't be dynamically updated: http://developer.nvi...?showtopic=3548
  5. You should talk to the guy I had make the soldier model.
  6. If anyone wants to make a desk like below, I will add a script to give it physics. The drawers should be separate pieces. A physics shape needs to be created for the desk and each size drawer you use. Each drawer can be a limb in the mesh file, with a name like drawer1, drawer2, etc. The pivot of the drawer should be in the center rear of the drawer. The drawer physics shape should consider this point the origin...the draw physics shape will be loaded from the .phy file and connected at this point with a slider joint, with limits. After I write the script, you will be able to grab the drawers in the editor and pull them open to see what is inside. It might be easier to just make all the drawers the same, since it will probably be a little confusing to set up at first. This is what got me thinking about this: http://www.youtube.com/watch?v=Ux4OwkS9ybA
  7. That's not feasible because each physics library is so different. PhysX does not support heightfield data. A terrain has to be made out of a mesh, and editing the terrain in real-time like we do is not possible. So what is everything considered "disabling physics"? Generation of the .phy files? What about raycasts? They use the physics system. Should they be disabled? What should happen if the user calls a raycast command when physics are disabled?
  8. I think it's very useful for debugging and adjusting the engine for individual needs, but it does require a fair bit of courage. Now that the engine has Lua and is pretty stable I think it's safe to branch off with your own version of the source.
  9. The only time I have seen this occur is when a really detailed collision shape was used with lots of small triangles, and it was a situation that should not have been allowed to happen.
  10. You can also compile files into your EXE, with some languages.
  11. The most I have seen is some boxes falling. I have not seen: -Selective collision system. -Interpolated physics with constant update speed. -Joints -Vehicles -Terrain -Character controllers -Any of the features that motivate people to look at PhysX in the first place. So the most I have seen is some experimental stuff that doesn't have nearly the same feature set as our current implementation. I'm not sure what the motivation is to pursue these alternatives.
  12. Well, we know something is funny in your code. What kind of a rendering setup are you using? Framework, or something of your own? Have you customized the renderer or done anything that could affect the depth buffer?
  13. Josh

    Z Order?

    Enable z-sorting in the material.
  14. That's strange. Maybe the entity view distance is set to a low number?
  15. Josh

    Future Ideas

    Here are some of my thoughts on how a future engine might look. I am not devoting any time to this, and it would not come to exist for several years, but it's fun to think about technology and design: I've been fascinated with the game "Fuel". This game has an enormous playable area that is streamed from the hard drive. You can drive for hours and barely cover a fraction of the map. For some reason the game has been given bad reviews. I played Motorstorm on the PS3, and I think Fuel is a lot better than that game, not even considering the impressive technical features. Anyways, I love the large open world. Fully dynamic lighting was one holy grail of game development, and I think a continuous open world is another. I would start this with a concept of "regions". Each region is a square on the grid, perhaps 1024x1024 units. The region has a terrain heightmap, terrain normal map, and an SBX file for all entities in the region. As you move around the world, regions are loaded from the hard drive in a square of playable area around you. Maybe there are 16 regions active at any given time. This number should be adjustable. Only physics and scripts of the entities within this active region are updated. When a region goes out of the playable area, it is saved to a file, and this new file is loaded if that region re-enters the playable area. So you aren't going to have enemies fighting and moving around when they are a million miles away. The engine just updates the regions nearby, because it would be simply impossible to update millions of entities. The AI in STALKER actually uses a technique similar to this, and I think they originally were planning on a huge continuous world but weren't able to pull it off. Each region can be culled on a separate thread, so this design lends itself to multithreading. So far what I have described is a big challenge, but it seems feasible. The real nightmare begins when we talk about networking. If your friend walks ten miles away and interacts with a person who's attitude towards you changes based on the interaction, well the server needs to be running two simulations. One simulation is for you and everything around you. The other simulation is for your friend and everything around them. What your friend does will change the world outside your playable area, so that when you enter that region it will be different than when you left. Now consider physics. Due to the massive distances, there would need to be two separate physics simulations running. Then they would need to be merged together when you approached each other. Wow, no wonder no one has done this yet! Fuel has a multiplayer mode, but it's just a racing game. Your actions don't have any permanent consequences on the world around you. An FPS, adventure, or RPG game will be quite different. I'm not even sure this is technically possible, without severe restrictions in flexibility. Fortunately, real-time rendering is not going to change much in the next ten years. We'll be able to do more as hardware advances, but I think we'll still be using the same basic techniques for a long time. That means that every feature and technique we add now will still be useful for a long time, even in a new engine.
  16. Transform the point from local to global space.
  17. If you want an AABB you can also make a mesh that represents that shape. If we had a model-less entity you drag into the scene, it creates some design problems. Let's say the entity is an emitter. Where does the class script come from? Does script support have to be added to the base entity class, instead of just the model? If so, how does the script delete whatever entity it starts with, and replace it with an emitter, using the same script? What if the emitter is deleted and recreated, as happens when the particle count changes?
  18. I don't see much point in this because the attempts at implementing other physics libraries have not gone very far.
  19. Josh

    What's missing?

    No, it's not, but alpha masking with antialias doesn't have any of the z-order issues alpha blending has. I think alpha blending was more appropriate when texture resolutions were lower. With higher resolution textures I don't think alpha-blending of leaves and things like that is as useful.
  20. Because in LE a model is the only scripted entity, so a model and a script allow you to create any kind of object you want. Particle emitters, lights, roads, etc., can all be implemented using this convention. If you want to get rid of the extra model when your game loads it, this is pretty simple to do. It shouldn't make any difference though, since the model is invisible and normally will have no collision set. If you want to make the model so it isn't even pickable, replace it with a GMF file that has no surfaces...then you would only be able to select the object by clicking on its node in the objects tree in the side panel.
  21. This thread is marred. Feel free to try again in a more polite manner.
  22. If you just save the script every instance in the scene will be freed (with the old script) and reloaded (with the new script). You should not run a class script.
  23. The reason these entities are linked to a model is because a model has a script, and can be moved around and deleted again. This allows you to make lights, particle emitters, or anything else in script, and the editor doesn't have to have everything hard-coded. If you want to get rid of the model component in your own game loading routine, you can just modify the script to remove the model when your game loads the scene. Something like this: if MyGameIsRunning==1 then object.light:SetParent(nil,1) object.light=nil object.model:Free() end
×
×
  • Create New...