The not-so-manic track editor.
#1
Another lua exercise (so 0.8.0 or later).

An editor integrated into a track (a track object which responds to some special messages from an editor interface running on the interface thread):

* primary focus is on placing geoms (joints and bodies might come later... object spawning could be supported, but it's hard to move them without having to unspawn/respawn them every step)
* will not compete with pure lua scripting (which is more powerful), but will instead make it easy to place many geoms visually without having to worry about coordinates (then generate a list/lua script which can be included in a normal track script)
* good when building a city or complex road. Also if someone were to make some road blocks, it could copy the trackmania editor+add some improvements.
* supports realtime simulation (so can drive a car through a jump, and in the air pause the simulation, switch to editor and place a road to land on, return to car and continue the flight and land on the road)

It will feature two modes: edit and navigation (wont cover the complete key layout yet):
* navigation: like the classic noclip fps mode (with Q and E for up/down. 'nuff said). Look at some existing geom and click will change to edit mode:
* edit: scroll wheel to move closer/away, mouse will rotate the camera around. Hold left button and use movement keys to move the geom, right button and mouse to rotate. can also delete (Delete key) and return to edit through Esc.
Pressing space in both modes opens the Spawn&Settings menu, with a spawn utility (either basic geom, load geom from trimesh like obj or road file, through file browser)., and some usual settings (enable snap-to-grid, set grid size and visibility, 3D transparency, debug geom rendering mode, etc).
Try systemd. They said.
It'll be just as reliable as init. They said.
It'll be completely bug-free. They said.
Our monolithic windows-approach is far superior to the Unix-approach. They said.
Okay, so the codebase has grown gigantic and no one but our paid group of full-time developers who created it can maintain it and fix bugs... but it'll be fine. They said.
Okay, we'll shove it down your throat whether you like it or not. They said.

I guess it's finally time to look into GuixSD and/or devuan.

Code:
systemd-journald(195): Received SIGTERM.
systemd[1]: systemd-udevd.service has no holdoff time, scheduling restart.
systemd[1]: systemd-udevd.service failed to schedule restart job: final.target is queued, ignoring restart request for unit systemd-udevd.service
systemd[1]: Unit systemd-udevd.service entered failed state.
systemd[1]: systemd-journald.service has no holdoff time, scheduling restart.
systemd[1]: systemd-journald.service failed to schedule restart job: final.target is queued, ignoring restart request for unit systemd-journald.service
systemd[1]: Unit systemd-journald.service entered failed state.
Reply
#2
I'm not sure I understand what you're describing - how would it be different from having a Generic Editor running in the Interface thread, which could access a library of 3d models, and put them together to make a single track object?

Or does each track have it's own "scripted events" (e.g. "ball" object needs to be in "goal" zone to score a point), which the Generic Editor could hook into and trigger directly?

I guess I'm confused because "An editor integrated into a track" sounds like the track has a stand-alone lua-based editor embedded within it... which would be.. interesting, but I think I'm either mis-reading, derping, or both ;-)
Reply
#3
Very good question!

And it shows a big problem on my side: I got a lot of ideas and features planed, but haven't mentioned them!

Quote:sounds like the track has a stand-alone lua-based editor embedded within it... which would be.. interesting
That's actually quite close to it!Big Grin

So, I'll try to explain my idea of "objects", the interface and simulation threads and how lua ties into it all. And of course why I said that the track would have the editor inside itself. Smile

First of all: the interface and simulation threads doesn't require much explanation. Basically the interface thread launches at start, and run "rc.lua" which can create a window, and launch one or more simulation threads, set up rendering scenes, "remotes" (other scripts designed to take inputs and control cars and similar in simulation) and all that.

Objects: a concept only on the simulation thread(s). But also the most important thing. My idea (which I've based even the earliest versions of rcx on!) is that each simulation is just a large set of "components" (different ode things: bodies, geoms, joints, spaces). In order to manage all of them they are grouped into "objects". Now an object got several purposes: it got a "loader" which loads everything needed (mainly 3D models+texture+sounds) when the "template"/"blueprint" is loaded (normally just before a race), a "constructor"/"spawner" which gets run every time an object is spawned from a "template" (create geoms, bodies and whatnot. assign 3d models, set up hooks, timers and other event-driven things).

It was only recently I decided to use lua scripting for rc (rcx back then), and what I can say is this: most programs use lua as configuration-on-steroids. I'm going to use it as a complete programming language. There's nothing with the objects that will be hardcoded (except for an abstraced idea of coordinates: each object will have it's own basis in the 3D space, which is set when it's spawned, so when the lua script works with stuff in 3D, all matrices and vectors will be multiplied by its unique transformation matrix. And of course the C/C++ code that tracks the objects and their components, and frees up the memory when no longer used - either the simulation ended or something was loaded but the reference isn't used anymore, like as if it was a GC).

Objects will form the basis for everything: a car is an object, a track is an object, a building on the track is an object (which gets recursively loaded as a dependency when the track is loaded, and spawned by the contructor of the track). Heck even an AI _could_ be an object (but probably wont, because there's ). In pseudocode, the following would be a lua script for "data/objects/misc/box/object.lua":
Code:
--load the 3d and create the spawn function
my3d = Trimesh:Load_3d("box.obj") --this file is inside data/objects/misc/box/

function spaw()
    mygeom = Geom:Create_Box(1, 1, 1)
    mygeom::Add_3D(my3d) --syntax here will change
end

--done, just return the spawning function!
return spawn

And a track would look like this:

Code:
box = Object:Load_Object("misc/box")
my3d = Trimesh:Load_3d("ground.obj")

function spaw()
    --
    --placeholder for setting up a global space, rendering scene and so forth...
    --

    mygeom = Geom:Create_Plane(0, 0, 1)
    mygeom::Add_3D(my3d) --probably will look different...

    box:Spawn(0, 0, 10) --could also add rotation
end

return spawn

And so on. A car would also listen for messages ("Simulation:Set_Message_Hook(function())") and change the joint settings for the wheels and add torque to the wheels as requested.

My design is based around... lack of trust. Among the different parts of the simulator. One object can't modify the contents of another object (unless the object reveals the reference to it, in which case it's assumed that anything can happen). They can only load and spawn each other (but probably not delete), and they can communicate through messages (which are just lua tables). These messages are capable of going to different threads and different objects in different threads (the interface thread will only have the single rc.lua script sending/receiving messages, but all simulation threads got objects each one having its unique "mailbox"). If you want to control a car, then you send it a message. If the car understands it (and accepts the sender) it will look at the value "steering" and configure the steering accordingly and so forth. The car can also return a message containing its current velocity and where its attached camera should look at (in the same way a FPS character would receive walk and shoot commands through messages and return ammo info and camera position/rotation). Keep in mind that the "control massages" doesn't need to come from the interface thread - they could just as well be sent from another object or some AI (WIP on how this will look... lua script running on the simulation thread at least. maybe just objects, that would work...).

This is where the "remotes" come in: instead of having the "rc.lua" running by the interface thread having different chunks of code for different vehicles/characters, there will be a directory ("remotes") containing short lua scripts doing this translation from the keyboard (or whatever the specific remote has been configured to use by the user/profile). The remotes can be used for different vehicles (all rollcage cars will use the same one, for instance) and most of them will also manage the camera pos+rot and display info on screen. They will just run once and set up hooks with rc.lua (which can then be discarded when not used any more, leaving the gc to remove it).

This is also one of very few ways the interface thread can "interfere" with the simulation. It DOES however have access to a range of more powerful functions which are used for more direct control of the whole simulation and ("load object", "spawn object", "remove object", "runlevel=?", "terminate", "simulation_speed=?", "dump_state", "kill"), but this doesn't allow it to actually create things in the simulation (everything in the simulation needs to be assigned to an objects, and the interface thread is _not_ an object).


Ok, with that lengthy part over, what did I mean with a track editor inside a track?
My idea for a track editor is not something very complex. I'm not intending this to be used for "real" tracks, but rather if someone wants to quickly try out some 3D model, make a trackmania-like track, or just not wanting to get dirty with lua (and a huge custom set of lua functions containing everything fro vector+matrix math to trimesh manipulations) and just wanting an easy option for a first time creation. Basically: this will in no way be capable of creating those more fun stuff (IMO) like different event-driven stuff and more complex constructions with joints and spaces. And it will definitely not be able to create multiple rendering scenes and launch multiple simulation threads and start doing real funky stuff (like simulating a planet system while at the same time simulate the local race, and finally put it all in a box on a table inside a third simulation. Big Grin

With this premise, how would I implement it? First of all, a lot of data need to be displayed on screen and inputse needs to be parsed. And the interface thread isn't really allowed to interfere with the simulation at a low enough level to add/remove geoms... So my idea is this:

* "editor" remote: like a rollcage/wipeout/fps remote control, but previewing 3D models (also able to load another remote to switch input to with a press on the Tab button, bound to some in-game vehicle. but not important right now)
* "editor" object: the object the remote will be communicating with. It will handle the creation+tracking of geoms and bodies. It will also be responsible for doing a raycasting to find what geom/body the player is currently looking at. It will have two special commands (again, like any other message): "save" and "load" which should be self-explanatory (just specify a filename).

With an analogy to the Sauce engine: this will be much less like a real "map editor", and more like "GMod". You'll be controlling a object "holding" different tools and just do simple manipulations (with with the extra features of also being like the track editor in trackmania and being able to create bodies so stuff will move).

What's important here is to note that the editor object wont _have_ to be a track! So if wanted, the editor object could be just one of the normal objects, and the interface thread could just load some random track and the load+spawn the editor object in the middle and start editing (but then not being able to change or remove the existing parts of the real track, as mentioned before). Then just save the work, and if happy with it, copy+paste the track it's based on and add a line to the lua script to autoload the editor object and load the custom track inside it!

Sooooo.... I just managed to make it all even more confusing, didn't I? Heart
Try systemd. They said.
It'll be just as reliable as init. They said.
It'll be completely bug-free. They said.
Our monolithic windows-approach is far superior to the Unix-approach. They said.
Okay, so the codebase has grown gigantic and no one but our paid group of full-time developers who created it can maintain it and fix bugs... but it'll be fine. They said.
Okay, we'll shove it down your throat whether you like it or not. They said.

I guess it's finally time to look into GuixSD and/or devuan.

Code:
systemd-journald(195): Received SIGTERM.
systemd[1]: systemd-udevd.service has no holdoff time, scheduling restart.
systemd[1]: systemd-udevd.service failed to schedule restart job: final.target is queued, ignoring restart request for unit systemd-udevd.service
systemd[1]: Unit systemd-udevd.service entered failed state.
systemd[1]: systemd-journald.service has no holdoff time, scheduling restart.
systemd[1]: systemd-journald.service failed to schedule restart job: final.target is queued, ignoring restart request for unit systemd-journald.service
systemd[1]: Unit systemd-journald.service entered failed state.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)