# Windows Warp3D - Game Engine, Level Editor & Model Editor

Discussion in 'Work in Progress' started by Joe Ellis, Mar 12, 2018.

Tags:
1. ### AmonMember

Joined:
Sep 13, 2016
Posts:
308
That's pretty cool.

Joe Ellis likes this.
2. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106

I've made a first person player object and laser projectiles with collision. Also cool oldskool sprites that always face the camera like on doom and things. I've done that with a special sprite shader that gets set at the end of the draw begin event after the 3d stuff is rendered, so the entire main draw event is reserved for instances with sprites and they can be drawn using the normal draw_sprite functions in their draw event like normal, the only extra thing that's needed is to set a uniform for the sprite's position eg.

shader_set_uniform_f(global.uid_sprite_pos, x, y, z)
draw_sprite(sprite_index, image_index, 0, 0)

Next week I'm gonna make some enemy ai, I've got it all planned out on paper

Yal, RujiK, sitebender and 3 others like this.
3. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
I've created a saved game system, with files called Profiles.

Each profile is a node like all the other resources, and contains all the things needed for a saved game
eg. the current world, player variables like health ammo and armour, the inventory, and any global variables you wish to save.

The variables that a profile contains are fully customisable, and profiles can be edited in the editor,
they can also be created, saved and loaded in game, which is ideally what they're for,
eg. you can load and create them in the main menu and save them during gameplay, or at the end of a level.

The only thing you can't do with them yet is save the state of a level while your playing it, so every time you load a game you would have to start at the beginning of the level or at a certain checkpoint or save spot, which alot of games work like anyway, but I will eventually try to create a system for saving the state of a world, by making variable overrides for the instances and overriding whether each one is active or not, for if an enemy has been killed or an item has been collected.

I've also made a new resource type called a Preset, which is for saving instances, this is ideal for inventory items like weapons, cus they can all use the same object_index (obj_gun) but have different variables to make them the weapon they are.
You can spawn instances of presets during gameplay, which is ideal for projectiles, effects and any instances that are created dynamically during gameplay.

I've also improved the way collision is handled, by splitting it into 3 main parts\scripts:
collision_static, collision_dynamic and collision_precise.
Upon a collision, a second script is executed, which is a more specific script for that certain object_index. All of these scripts are easily defined in an instance's create event, or you can predefine them globally.

Collision_static is to check for instances that stay in the same place throughout gameplay,
like weapon pickups, health, ammo, triggers, teleporters and any static solid objects.
They get added to a grid when they are created, and any dynamic instances that need to check collision with them only have to check the current cell
they're in, so this ends up making them only need to check collision with 1 or 2 static instances at a time (if any), so this is a huge optimization
compared to every dynamic instance having to check every static instance in the level.

Collision_dynamic is to check collision with moving objects, like the player, enemies and moving platforms. These also get added to a grid but are updated dynamically ei. removed and added to\from grid cells every time they change cell.
This script is mainly used by dynamic instances to check collision with other ones, but is also used by projectiles and things that can harm characters, even though they aren't added to the grid themselves, cus characters shouldn't check for collision with projectiles cus there are potentially alot compared to the number of characters, so its much faster for the projectiles to check collision with characters in their current cell.

Collision_precise is the script I've already covered, for the polygon level collision.
It's mainly characters, projectiles and physical moving objects that use this.
For projectiles, they use a ray projection for triangles in their mask_radius.

I will have some footage of all these new things in action pretty soon.

Here's the current list of object indices, there may be a few more added but these cover almost every type of instance the template game needs.
And don't forget, they're designed to work with the preset system to make specific things, so these are very broad, general objects that are versatile.

And here's a picture of a blank inventory display:

I haven't yet finished the part where it renders the item's models, but that's next.
The inventory itself is just a 1d array, not a grid, so this makes it very versatile with whatever way you choose to draw the inventory,
there's not a set grid resolution so it can be displayed in any sized grid you want.
The inventory is designed to be a list of instance presets, which get created whenever an item is equipped.
A good thing about this is that when a preset is loaded ei. when the inventory is loaded at the start of the level,
it automatically loads the model it uses, so this stops any lag from loading models during gameplay when you spawn an instance of a preset.

JaimitoEs and inertias like this.
4. ### lolslayerMember

Joined:
Jun 23, 2016
Posts:
695
Sounds promising

Joe Ellis likes this.
5. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
Here's some new stuff I've been working on this last month or so: (sorry no screenshots)
• Made saving game during gameplay possible, saving exact states of levels
• Improved dynamic light handling, allowing instances to emit light and made an automatic sorting system to deal with the max light limit
• Improved variable handling, reduced cpu and ram usage
• Reduced amount of node types, converted alot of them to instances instead
• Made better way of calculating smooth vertex normals, using more of a median approach instead of mean, which illiminates bias from faces with the same normal and makes shading on quads and blocks look alot better.
• Worked out how to do deferred rendering using the application surface alone (no extra surfaces)
• Created a "pre depth pass" option, which writes the world's models to the depth buffer but not the pixels' rgba, then when rendering normally it eliminates overdraw and optimizes rendering a ton when using complex shaders.
• Made a pathfinding algorithm, for using with navmeshes (points linked together)
• Worked out how to build vertex buffers gradually while rendering them, which has made it possible to load models during gameplay without having to make instances that use it invisible while it's loading
• Improved polygon-level collision method, roughly twice as fast as it was

6. ### JaimitoEsMember

Joined:
Aug 9, 2016
Posts:
221
Everything looks great and tidy! I have seen that you make use of Constrained triangulation .
Have you implemented it in GML or is it a dll? You have done a great job with the Ui and the tools. The implementation of 3d models is great! I'm thinking of implementing something like that in my editor, it could do very well for a 3D sidescroller like Donkey Kong or Trine 1.

Joe Ellis likes this.
7. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
Thanks It's all in gml. That sounds good, I'm sure you'll have no trouble implementing 3d models, the stuff that you've done so far is more complicated than that

8. ### JaimitoEsMember

Joined:
Aug 9, 2016
Posts:
221
That's cool! For performance issues I decided to use the Ear Clipping technique, but I see your script very useful, especially for texture handling. Like your project I have decided to do everything in GML, I cannot resist the temptation to run the editor on a tablet and other compatible platforms. On the 3d, I put in the list to make a function to import models in Json format, it can be very good for the easy sending of information. Thank you very much for your comments, the same I say about your excellent work.

Joe Ellis likes this.
9. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
I've finally worked out how to do the skeletal system I wanted to use, where rotations are applied in absolute space instead of being relative to the parent bone's rotation. They're applied directly to the bone's absolute rotation matrix and the relative matrix is then recalculated. (by multiplying the absolute rotation by the inverse of the parent's absolute rotation)

This means:
• You can rotate the bones to be at any angle & orientation you want quickly and easily, without being restricted to only the x, y and z rotation values.
• no more gimbal lock
• no more having to wrap your head around how the bone rotates due to it being relative to the parent bone.

However, under the hood it still uses relative matrices, so it's still fully compatible with other model formats.

Here's a screenshot showing the bone heirarchy, which displays in the same tree like structure as the world editor:

When you click on or move the mouse over a bone(in either the heirarchy or in the 3d view), you can rotate it using the keyboard:

left\right: yaw
up\down: pitch
< >: twist

holding ctrl will switch it to "tilt" rotation:
(which uses the view angle as the axis (can be snapped to a certain amount eg. 90 degrees))

left\right: tilt sideways
up\down: tilt forwards\backwards

You can also hold alt and use the arrow keys to move the bones' positions in world space, and it recalculates the rotation matrices and bone length based on the change. This makes it really easy to construct a skeleton and the bind pose
However if you use this while animating, the lengths of the bones will likely change alot, so I've added a "preserve bone length" option, cus normally changing the length of bones in an animation will make the characters skin stretch quite unnaturally. But this might be a cool thing with cartoony characters which is why I've made it as an option.

I'll post a video soon showing this stuff in action, hopefully it'll show how much better this new setup is.

JaimitoEs, Ad_Mc, Kentae and 6 others like this.
10. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
I wanted to give abit of an update, although I've hardly got anything to show for the last few months work. I've been doing alot of deep engine level stuff that hasn't made anything look any different, but it's still alot of good stuff that I wanted to tell everyone.

One screenshot I've got is that I've added "smoothing edge threshold" as a setting for each mesh.
So it's able to have smooth shading and hard edges:

I've also merged the windows of each tool into the settings panel, so it just changes with what tool you're using. I think it's alot neater and more concise.

The rest of what I've done is technical engine things, that are getting it as good as possible.
The level editor is mostly complete, minus some functions for applying settings to all selected instances, and other handy things like that.
It now has infinite undo\redo. Although it doesn't work with deleted instances yet, you can't un-delete something, but I'll try to add that by keeping them in a "deleted items" list. There's also no undo\redo in the model editor yet, I'm starting to work out how I'm gonna do it though.

I've also started making an fbx importer from scratch in gml, so it won't need the dll anymore.
This will only work with the text\asci version, but I don't think this is a problem cus blender and most other model editors allow this.

Also with paths, created by joining points together, I've made it so you're able to make "flow" for each link between points (the direction you're supposed to move along it) which is essential for a game with cars and roads, consider police cars chasing you, every police car in the map is notified of your wearabouts and each has to plan a path along the roads to get to you. Without being able to know the direction you're supposed to drive along each road they'd end up crashing into all the other cars.
So now the pathfinding algorithm is able to [optionally] check that a link from point A to B is the right direction. By checking that point A is the 1st point in the link and B is the second, and if not, it will not consider this as a possible route and treat it as a dead end if there are no links that are in the right direction.

Also the final thing, (stop reading now if your not interested in files and data)

I've done a pretty huge optimization to the file format,
it used to work with strings for saving the type of each variable, it would save the name of the type as a string then interpret it when loading.
Now instead I've made every file save a "type list", with all the names of the types that file uses. When loading it, it creates a list of real type indices by interpreting each type name. So this has cut down the file size imensely and made it so there are only 20 or so strings that need interpreting, instead of 20 per instance.
Now all variable tables are saved with the name of each variable, and a single byte for the type index.
Also before, each instance would save it's variable table, with the name, type and value of each variable.
But the variable tables have identical var names & types per object, so only the values are unique to each instance.
So now I've made it save each table used by instances only once at the beginning of the file(the var names and types) and each instance now only saves the values of it's variables. So this has also cut the file size down alot, and made loading faster.

I've also added backwards compatibility measures, when each instance's variables are loaded from the file, it afterwards checks through the current variables table(not the one saved in the file, the one configured in the project) and checks that each variable exists,
if it doesn't it creates it and sets the default value from the table.
If it does exist, it checks the value is the correct type, eg. if it's a number it will return false if the value is a string or array.
If it's not the correct type it will set the default value instead.

So this has made all level files backwards compatible if you decide to change certain variables for objects after the file was made;
it will forget about ones no longer used that were saved in the file and add new ones that weren't saved in the file.

11. ### JaimitoEsMember

Joined:
Aug 9, 2016
Posts:
221
Fantastic, I hope the world is aware of the unique value of the new tools that are yet to come for game maker. A need that many people were asking for is being met. Keep up the great work Joe !!

Joe Ellis likes this.
12. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
I've improved the skeletal system even further, I've removed the need for relative rotations and a bind pose\set of inverted absolute rotations, and made it so the bind pose doesn't use any rotations in the first place, simply positions. Then when you're editing an animation you're directly editing the rotations that are passed into the shader, which are absolute. So when you adjust a bone's rotation you're simply adding extra rotation on to it, and it automatically applies this to all sub bones aswell.
I've also started using quaternions instead of matrices after realizing that you can lerp them and blend bone influences by multiplying each quaternion by it's weight and then add them together. With matrices I was weighting and adding the transformed vertex positions together and it wasn't a very accurate way of doing it.

Here's a video showing how easy it is to build a skeleton when you can just move the bones about, and I also got some very basic vertex rigging set up for the first time ever! I need to work on this part next and make tools\functions for assigning bones to vertices and adjusting the blending\weights.

TheSnidr, Yuriy, Kentae and 1 other person like this.
13. ### IGameArtMember

Joined:
Jun 21, 2016
Posts:
171
It's really great to see people doing such cool 3d stuff in GM. Especially skeletal animation like that. This is some great progress!

Joe Ellis and Amon like this.
14. ### JaimitoEsMember

Joined:
Aug 9, 2016
Posts:
221
So cool to create enviroments!!

Joe Ellis likes this.
15. ### YuriyMember

Joined:
Dec 6, 2019
Posts:
4
That's incredibly cool!

Joe Ellis likes this.
16. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106

Testing a car object with precise collision.
It has different variables for acceleration, weight, cornering etc. which you can adjust while you're driving it, so you can find the perfect settings for certain vehicles.

RujiK, inertias, YanBG and 2 others like this.
17. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
Today I made it so you can activate individual instances and test them when the rest of the level isn't playing,
This is pretty useful for setting up variables without other stuff getting in the way.
Also made a pretty fun ball object with adjustable bounciness and weight.

18. ### JaimitoEsMember

Joined:
Aug 9, 2016
Posts:
221
Wow! have you created the collision system from scratch? it looks fantastic ! You are very close to finishing it! Keep up the great work!

Joe Ellis likes this.
19. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
Yep, just gradually learnt the maths I needed to know
and thanks

20. ### z_billMember

Joined:
Jan 21, 2020
Posts:
2
I just learned about this and skimmed the posts...but this is going to work in GMS2?! Holy crap! Wow!

The version you released (and took down?) was the 1.4 version, right?

This looks so amazing and that it's gotthe level editor built right in is sorta blowing my mind!

Any suggestions on how I could prep a game, groundwork etc, to start using this (for GMS2) once it releases? Also, not to hound you, but have you set a loose timeframe for release?

Joe Ellis likes this.
21. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
Thanks for the amazing feedback, stuff like this really motivates me and makes it feel more worthwhile

Yes, it will be for gms2. I'm going to port it once EVERYTHING is finished.
The porting probably won't take very long at all, as all the functions it uses are still in gms2 with the odd name being different.

I released it too early before, now I've decided to release it when it's completely finished, including a manual and tutorials. There's no actual date in mind, all I can say is that I'm trying to get it done as SOON as possible, while making sure everything is working as well as possible.

There are only 3 big hurdles left: the skeletal animation system, animation editor, and the lightmapper.
All of these are partly working, but need alot of finalization before they stand up along side the rest of the engine.. and I can't really just buckle down and finish them, cus I need to actually get my head around the things that are left to do.

Aside from those things, everything else just requires a few tweaks, bug fixes and extra handy functions here and there, and the progress with that is coming along really nicely and at a good pace at the moment.

I've also begun writing the manual, which I was struggling to do before, as a lot of things weren't finalized, so I couldn't really write about them in full.

And every day I'm making template\example objects (this is the fun part) All of which will be included in the release, and should provide examples of almost every type of thing in a game, whilst showing how objects need to be coded a bit differently in order to work with the engine.
All of this will be fully explained in the manual aswell, and together with the examples with commented code should provide a solid and easy to understand
starting point.

As for preparations for your game, it's hard to say, as so much of the game making process is done in gamemaker\gml along-side the Warp3D engine..
You could put together the skeleton of the project with objects with pseudo code of what they should do. Then when you have the engine it will be easier to put them into action. Also learning about vectors would make it easier to customize the collision scripts if you need to. Although it will be possible to just use the ones provided, there might be some situations where you want to slightly change what happens, and understanding what the maths is doing will help.

22. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
More progress on the skeletal system:

Now I've got auto vertex rigging\weighting set up and working properly

I've also been experimenting with setting a bone's "capture radius"
To help stop parts of the model following the wrong bone (like the side torso following the arm bone if it's too close)
This'll make it easier to rig models without having to model them in a T pose.

On the video the rig starts off not looking right, but then I adjust the bones' radiuses and the amount of pinch around the joints and it ends up looking pretty good.

23. ### CMAllenMember

Joined:
Mar 2, 2017
Posts:
863
One of the methods of 'soft selection' used in most major 3d programs is topological-based -- the distance is calculated by following edges from the source point (or calculated backwards, from the end point, along edges to the vert nearest the source point) instead of just the distance between the source and end points. I mention this because it sounds like exactly what you're trying to achieve with smart-weighing bones.

Joe Ellis likes this.
24. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
Thanks, yeah it already does that, rather than measuring the distance from vertex to bone, each vertex gets the nearest point along each bone's vector from the parent to itself, basically a "nearest point on line" function.
The radius part is just used to stop certain bones from even being measured in the first place, like the elbow shouldn't affect the torso. So it first checks whether the vertex is in the bone's radius, then if it is, it gets the nearest point along it's vector, and gets the distance from that point to the vertex's position.
The nearest bone becomes the main bone, then it checks the bones connected to it, it's parent, and sub\child bones to find out which one is nearest. The nearest ends up being "bone_2" and then it divides the distance from bone 2 by the total to get the "blend ratio" between them.

Last edited: Feb 4, 2020
25. ### YalGMC MemerGMC Elder

Joined:
Jun 20, 2016
Posts:
4,214
This looks really interesting, can't believe it's got under my nose this whole time! Gonna keep an eye on it for sure.

Joe Ellis likes this.
26. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106

I've made dynamic lights that use deferred rendering, which adds light & color over the top of the scene. I'm pretty happy with the result.
It's made it alot easier to handle dynamic lights, each one adds the light to the scene in it's draw end event.
I've done a similar thing to this for applying fog to the whole scene, and I'm planning on doing shadows like this aswell.
So now I don't have to make clones of shaders with\without fog, lights and shadows.

You might be wondering about performance. It's actually pretty good, it doesn't use any extra surfaces, it just needs to render the vertex buffers
several times, but there's plenty of room for more vertex buffers, and the batching system it uses is really efficient.
The lights can also be optimized by only rendering instances that are inside their radius, and using the collision grid it can get these instances really cheaply.

27. ### RichHopefulComposerMember

Joined:
Jun 20, 2016
Posts:
1,418
Super impressive stuff, as always. This thread makes me want to learn 3D math/coding. So cool! =D

Joe Ellis and kupo15 like this.
28. ### Joe EllisMember

Joined:
Aug 30, 2016
Posts:
1,106
I've done some stuff for the manual, the layout, page viewer, contents etc:

It's nothing special, but it's simple, straight to the point and has a nice oldskool vibe.

I spent ages trying find a good font to use, but couldn't find any that fit with the gui
so I ending up just using ms sans serif like everything else. Even though it's small it's actually really easy to read, so I think I'll just use that.

You click on a book to open it and see it's pages, and click on a page to view it.

For handling images on the pages, bullet points, titles\subtitles etc.
I've done an xml type thing where it reads special keywords in <brackets> and does a certain thing.
The actual page text files are like this:
Code:
<title>Bones
Bones are used to animate a model.
They are ordered hierarchially, starting at the root bone:
<img>Bones_Hierarchy 28 119
<goto> 28 298
Each bone has the following variables:
<bullet>X
<bullet>Y
<bullet>Z
<bullet>Yaw - Horizontal rotation
<bullet>Pitch - Vertical rotation
<bullet>Twist - Rotation around it's vector
<bullet>Length - The distance from it's parent bone
<bullet>Radius - (See <<Rigging>Rigging> for more details)
<title>Creating a Skeleton
To begin making the skeleton, you must first create the root bone in the model's hierarchy.
After that, you can right click on a bone to create other bones which stem off from it.
Use the arrow keys & pageup\dn to move it horizontally\vertically
Or double click on it to edit it's coordinates in the properties window

But are displayed like this:

Last edited: Feb 9, 2020
pomderi, inertias, Andrey and 6 others like this.