Jump to content

Josh

Staff
  • Posts

    24,629
  • Joined

  • Last visited

Everything posted by Josh

  1. According to MS, your namespace should actually be "company name"."product name". So the namespace for Leadwerks3D headers should be Leadwerks.Leadwerks3D. That's verbose, but okay if you just call using namespace once. The lack of global functions in C# is problematic, because there really isn't a logical way to name things. In C++, we have commands like Print(), TFormPoint(), CreatePivot(). I'm not going to document different languages separately, you can see how commands are documented here: http://www.leadwerks.com/newwiki/index.php?title=Entity::SetPosition We can try to come up with different categories for global commands, but my problem with that is it won't be documented anywhere, and I think C# programmers will get confused trying to guess the proper prefix for each global command. Log.Print(); Model.Create(); Transform.TFormPoint(); It makes more sense to me to put all global commands in a single class like "Global" or "L3D" or something: L3D.Print(); L3D.CreateModel(); L3D.TFormPoint(); My question for the C# programmers here are: -Does a single class for global functions look totally weird to you, or does it make sense? Have you seen this done before, and can you provide any examples? -What would you call this class in which global functions are kept? -If categories like FileSystem.ReadFile(), Window.Create(), and Log.Print() were used, would you feel comfortable remembering which prefix to use with what global function? These would not be documented on the function page. Please answer only if you are a C# programmer.
  2. The BlitzMax texture.GetPixels() method will return a pixmap. If you retrieve data from the GPU in real-time, the code execution on the CPU will stop and wait for the GPU to catch up. This is something the engine never does, we always keep data flowing to and around in the GPU, never back to the CPU. Occlusion queries are a special case because they have a mechanism to check if the GPU is finished, so we don't wait for the results.
  3. If you have any GUI images, specifically 9-component images (top-left, top, top-right, middle, right, bottom-left, etc.) for buttons, text fields, etc., I would like some images for testing. Thanks.
  4. You actually want to load the animation onto each of the LOD meshes of the model. You can get them with the model:CountLodEntities() and model:GetLodEntity(i) commands. LOD meshes get removed from the model's children dynamically, so going through the children won't do it.
  5. As far as I know, that should work, but laptop cards are funny because you can usually only get the driver from the manufacturer.
  6. Josh

    Collision Decisions

    Another thing I should point out about collision callbacks is you avoid the issue of accessing deleted entities. If collisions are stored, you could delete an entity and then when you are iterating through collisions, come across a collision that occurred with an entity that no longer exists. I experienced this problem a long time ago with Blitz3D. I suppose you could delete an entity inside the callback, if you are a crazy person, but the problem is much less likely to come up.
  7. Josh

    Collision Decisions

    Yes, that is what I was describing. Now you have a model that you want to add your own collision function for. You load the model from a file and then... Oh wait, it's a Model, not a MyEntity. Okay, so I completely rewrite the Model class so that you can create a blank model, then load a file with it. You have your own MyEntity class derived from the Model class, and you load a file: MyEntity* entity = new MyEntity; entity->Load("model.mdl"); That works, except the engine actually has the GraphicsDriver class create a model, containing special functions for rendering:: Model* OpenGL3GraphicsDriver::CreateModel() { return new OpenGL3GraphicsModel; } Let's just ignore that problem for now. What if you want a limb in a model you load to have a special collision function? Now we have to do something like this: ModelGenerator* mymodelgenerator = new MyModelGenerator; world->SetModelGenerator(mymodelgenerator ); MyEntity* entity = new MyEntity; entity->Load("model.mdl"); That wouldn't be confusing, at all. Ideally, you would want to just replace an object's class function with your own, or turn a base object into a derived class, but you can't do those things with C++. We could have a "collisionhandler" object as a member of the Entity class, but that is even more abstract and confusing, and you would still be using the "entity" prefix inside the function to access the entity's members, so it's just like a callback and defeats the purpose.
  8. What graphics card do you have?
  9. You've created a terrain? There was a bug in some older ATI drivers that make terrain invisible. If you have an ATI graphics card, I would update your drivers: http://support.amd.com/us/gpudownload/Pages/index.aspx
  10. Josh

    Collision Decisions

    A virtual function is just a class function that can be overridden by a derived class' function. I make all my class functions virtual, always. The fact you even have to specify it probably indicates this was tacked on at some point after class functions were originally implemented in C++. So like if you have Entity::SetPosition and Model::SetPosition, the Model class' SetPosition function will override the entity's, if they are both virtual.
  11. I suggest adding the relevant entities into a table when they are created, so you can access them later. If you are trying to find a child of that model, you would just call model:FindChild(name).
  12. Josh

    Collision Decisions

    The problem is that at any given time, you may have thousands of collisions occurring, but you are only interested in a few. If we want to save all that information, we're going to have a ton of dynamically allocated collision objects each physics update, which makes things slow. Okay, we can get around that by writing the collision data to big memory buffers that only get expanded, never made smaller. Now we have to consider that while the user is accessing this memory, the physics are already processing the next step and writing to these buffers, so now we need to use two copies of the data, and alternate the read and write buffers each frame. If each collision is 20 bytes (position, normal, speed, entity0, entity1), 1000 collisions will use 19 kb of memory, times two. Okay, that isn't bad. So that gives us a system where you call CountCollisions() and GetCollision(int index) and iterate through all collisions that occurred, but it still doesn't do what you want. To find a particular collision, you would have to iterate through n*n collisions, which is always the wrong way to do things in programming. If you had 1000 collisions, you would have to iterate through 1000*1000=1,000,000 combinations to find the one you are interested in. Another way to do this would be to add a list of collisions to each entity, again with a read and write buffer that alternate each frame. That would allow faster focusing on the entities you are interested in, but again we are storing tons of data when we're really only interested in a small percentage of that data. When we use collision callbacks, all collisions are dealt with immediately, and no collision data has to be written and saved. (Not entirely true...the engine stores an array of collisions for each thread, but only entities with a collision callback get written into the array, so that cuts out 95% of your entities.) For C++, I think the ideal situation would be if you could write a class with a virtual function that overrides an Entity class function called OnCollision(). However, since C++ can't turn an object of one class into one with a derived class, that makes it very difficult. If you loaded a model, retrieved one of its limbs, and tried to recreate it with a derived class... Not pretty. This is a major shortcoming of C++, but to my knowledge, no other language deals with it either. So we have this situation where there's one approach that's simpler if you only have a few objects on the screen, but can potentially cause a lot of slowdown if you have a heavy simulation running. The best approach is probably to use a Lua script with a Collision() function declared. The support for Lua in Leadwerks3D is a lot better, with debugging and code stepping.
  13. The terrain commands do give you a lot of control. I posted some of the code the editor uses in the BlitzMax forum. Roads are just scripted entities, so you could actually just place and link them with code, although it would be much easier to use the editor.
  14. It should be clear how the directories are laid out. There's a "mod" folder in the Leadwerks Engine SDK directory "BMX" folder, as well as a "lib" folder in both. If you still have trouble I suggest reading on the BlitzMax forum about how to install a new module.
  15. Put this .bmx file in C:\Leadwerks Engine SDK and run it: SuperStrict Framework leadwerks.ENGINE Local world:TWorld Local gbuffer:TBuffer Local camera:TCamera Local mesh:TMesh Local light:TLight Local ground:TMesh Local material:TMaterial GCSetMode(2) RegisterAbstractPath( "C:/Leadwerks Engine SDK" ) Graphics(800,600) world=CreateWorld() If Not world RuntimeError "Failed to create world." gbuffer=CreateBuffer(GraphicsWidth(),GraphicsHeight(),BUFFER_DEPTH|BUFFER_COLOR0|BUFFER_COLOR1|BUFFER_COLOR2) camera=CreateCamera() PositionEntity camera,[0.0,0.0,-2.0] material=LoadMaterial("abstract::cobblestones.mat") mesh=CreateCube() PaintEntity mesh,material ground=CreateCube() ScaleEntity ground,[10.0,1.0,10.0] PositionEntity ground,[0.0,-2.0,0.0] PaintEntity ground,material light=CreateDirectionalLight() RotateEntity light,[45.0,45.0,45.0] Repeat TurnEntity mesh,[AppSpeed()*0.5,AppSpeed()*0.5,AppSpeed()*0.5] If KeyHit(KEY_ESCAPE) Exit If AppTerminate() Exit UpdateAppTime() UpdateWorld(AppSpeed()) SetBuffer(gbuffer) RenderWorld() SetBuffer(BackBuffer()) RenderLights(gbuffer) Flip(0) Forever gbuffer=Null FreeEntity light GCCollect() End
  16. Josh

    Collision Decisions

    By the way, the collision type pair is stored in an iVec2, a new class in Leadwerks3D, which is just a Vec2 with integers instead of floats. An operation overloader allows this class to be used as the key in an std::map, and the collision response is stored as a value for that key: void PhysicsDriver::SetCollisionResponse(const int& collisiontype0, const int& collisiontype1, const int& response) { if (collisiontype0>collisiontype1) { collisionresponse[iVec2(collisiontype1,collisiontype0)] = response; } else { collisionresponse[iVec2(collisiontype0,collisiontype1)] = response; } } The C++ programmers here might find that interesting.
  17. You'll need to copy the contents of the "C:\Leadwerks Engine SDK\BMX" folder to "C:\BlitzMax". There's a BlitzMax module and a static library needed to compile.
  18. Josh

    Collision Decisions

    CSG brushes will eventually have real breakage. No pre-made pieces have to be made. Scripted breakage of models can still be done the same in LE2, but typically no one bothers with something that requires more work in the art pipeline. I know there are some third-party tools coming out that will create pre-broken pieces for any triangle mesh, and that's something I'll look at down the road, but it's low-priority at the moment. Yes, I was missing one collision response I wanted.
  19. Josh

    Collision Decisions

    I don't know what the previous constants were, off the top of my head. Debris means small fragments of things you don't want the player to affect, but will still collide with the scene and most dynamic objects. If you play around with Half-Life 2: Deathmatch you'll get a good feel for this. For example, if a piece of wood breaks in half, you don't want the player kicking small fragments around, but they would still need to collide with the scene and large physical objects.
  20. As I was implementing the collision commands for Leadwerks3D, I noticed a few things that illustrate the differences between the design philosophies of Leadwerks Engine and Leadwerks3D. You'll easily recognize the new collision commands, although they have been named in a more verbose but logical manner: void ClearCollisionResponses(); void SetCollisionResponse(const int& collisiontype0, const int& collisiontype1, const int& response); int GetCollisionResponse(const int& collisiontype0, const int& collisiontype1); In Leadwerks Engine, the collisions were left to the end user to define however they wished. In Leadwerks3D, we have some built-in collision types that are declared in the engine source code: const int COLLISION_SCENE = 1; const int COLLISION_CHARACTER = 2; const int COLLISION_PROP = 3; const int COLLISION_DEBRIS = 4; By default, the following collision responses are created automatically: SetCollisionResponse(COLLISION_SCENE,COLLISION_CHARACTER,COLLISION_COLLIDE); SetCollisionResponse(COLLISION_CHARACTER,COLLISION_CHARACTER,COLLISION_COLLIDE); SetCollisionResponse(COLLISION_PROP,COLLISION_CHARACTER,COLLISION_COLLIDE); SetCollisionResponse(COLLISION_DEBRIS,COLLISION_SCENE,COLLISION_COLLIDE); SetCollisionResponse(COLLISION_PROP,COLLISION_PROP,COLLISION_COLLIDE); SetCollisionResponse(COLLISION_DEBRIS,COLLISION_PROP,COLLISION_COLLIDE); Each entity's default collision type is COLLISION_PROP, which means that without specifying any collision responses, all entities collide with one another. Of course if you want to scrap all my suggested collision responses and define your own, you can just call ClearCollisionResponses() at the start of your program. The main difference in design is that Leadwerks3D assumes the user wants some default behavior already specified, instead of being a completely blank slate. That's a design decision that is being implemented across all aspects of the engine to make it easier to get started with.
  21. What are you expecting it to do? Freeing an entity deletes it.
  22. I wouldn't worry about that, considering how many games use it.
  23. If it runs regular graphics, it should work. I don't know enough to say for sure.
  24. My only suggestion would be to install the latest drivers from NVidia.
×
×
  • Create New...