• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Universal Model Converter - Side Development Thread

left or right? (a 20x20 toggle at the top of the window)

  • Left (under the window icon)

    Votes: 23 53.5%
  • Right (under the X button)

    Votes: 20 46.5%

  • Total voters
    43
  • Poll closed .

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Figured out the idea as to decent transformation of bone tails.

Simply copy the relation to the parent bone and apply the transformed difference to the tail :)

One of the old DAE import scripts for blender 24x does this perfectly.
(I found out while replacing a modern import's rig with some old data I had)
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Ugh...
So it looks like I've hit a decent wall with SIDE...

So I'm working on a pmx script for a minecraft mod called CustomSteve.
Turns out, the script is useless, because half way through conversion, it throws a MemoryError...

This is a problem with SIDE, not the script...
it's because of SIDE's highlighting interface using unseen memory by the python interpreter.

So yea, I need to rewrite the highlighter >_<

EDIT:
hope you guys won't mind waiting a bit longer :/
I'm going to work on getting deref() working...

Why?
it actually has to do with SIDE's highlighter interface...
once I get native support for pointers working I can parse the MEM data buffer used by deref() to determine the highlight colors directly.

Currently I'm building another buffer specifically for highlights at specific offsets, which is causing more memory use than the MEM data buffer itself...

So that's why there's a MemoryError being thrown.
(Not to mention one of the reasons everything's so slow)
^ almost as slow as HexEdit Pro. :p
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Looks like my valuable information on new features and a slight tutorial wasn't all that important...
I hit the post button 3 times before my browser crashed due to a bad connection...

If my post was important, a draft would've been saved...

So I'll just post the feature and screw the information...
(I hate phones so much)

ugeImportFile( path, scope=UGE_ARCHIVE_SCRIPT, script=name, compression='zlib' )

In scripts:

def ugePollModel(): return False # True if this script can operate on this data.

I did have tutorials and verbose descriptions, but I guess none of that matters.
(Using a phone is painful enough, I'm not typing everything again)
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
One important factor I forgot to mention during my rage...

File extensions are no longer an obstacle because they're not reliable.

You can still use file extensions as associations for scripts, but the process is no longer automated.

What's now used is used by Linux to identify support based on a file's data.

Data identification isn't perfect, but it can sift out fake files, which are very common on Windows.

So that's the purpose of the poll functions above.
Basically it's a side effect of the new featurability of ugeImportFile, allowing you to execute scripts on the imported, possibly decompressed, data. :)
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Well I've got good and bad news...

The bad news is I've ported and optimized code from blender-mathutils to my API, but the results are no different from any other implementation I've tried, and I can't seem to figure out why the issue happens...
So models are still improperly transformed...

The good news is the new script loader works pretty much flawlessly, which has led me to remove about 5 duplicate code blocks in both UGE and SIDE, and rely solely on the new implementation. :)

This now makes the UGE API more like a library that can be integrated into other programs. :)

I'm sorry this is taking so long guys...
If I knew more about how to do stuff, things would move along much faster.
 

ChimeraReyat

Smash Rookie
Joined
Jul 24, 2016
Messages
3
If I recall, you were trying to get melee animations working/converted, right?

I posted in Itaru's thread about how Jigglypuff is almost the exact same in Brawl and Melee. I was thinking maybe trying to compare the animations she has that are 1:1 to each other, you could get a better grasp on Melee's animation dat files, or at the very least find an intuitive way to convert Melee .dat files to Brawl's chr0 format (effectively exporting melee animations).
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
C ChimeraReyat
Yea, but @zankyou is further ahead of me on this...
The most I've gotten is that the animation keyframes are in relation to dynamic bone IDs defined by the matanim section in player files...

As for the keyframe formatting, I'm assuming it's similar to the format of CHR0 curves, but I really have yet to look into them.

I've built a chr0 importer for blender, but it doesn't import properly yet...
It gets the data displayed by brawlbox, but the interpolation and relations appear to be incorrect...

So I've looked into the chr0 format :)

EDIT:
As for UMC, I've somehow completely borked transformation...
So I've said screw it to the transformer...
I'm removing the function ("Transforming data..." in the console) and modifying my new vector class to transform the data in real time. :)

But some new stuff was implemented as per removal of matrices, so transformation now uses less math with quaternions.

The current problem though is the idea of rotating a vec4 vertex by a quaternion...

You know me and automation :p
I'll get things sorted out, but right now, I can't say to expect anything fast (performative)... :(

As the backend has evolved, the ideas behind it have continually changed, so right now everything has to search for everything, which can take a lot of time...

I'll eventually get it to where things can quickly back-trace, or are easily linked to related data, which will make things almost instant. :)

For example, making a vert look up it's related weights and bones (if they exist).

To note it's possible to link weights to non-existent bones, for formats which may define a rig after a mesh.

You won't believe just how much fiction I've put into UMC's design. :)

EDIT2: just realized after re-reading my first portion of this post...
I sound like I'm taking credit for zankyou's findings... >_>
This is simply not the case, I'm speaking in the context of what I've figured out as a result of zankyou's findings.
He gets the credit for actually putting 2 and 2 together and working to link things up :)
At that time I was working on improving the pathfinder and reducing the amount of work needed for defining new structs. :p
Along with updates to UGE's API, such as the struct data struct definer. (If that makes any sense at all... lol)

The thing that makes UMC's/UGE's development take so long is the simplistic standards, making things easy for noobs to understand, and extremely easy for pros to use.
(Which currently, things are counter-productive, especially with automation)
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Finally got an image uploaded to Google photos without the stupid app :D

So here's what I've been doing recently:


The console shows a repeated error from the script being reloaded.
It also notifies of that script being unregistered and reregistered.

In the GUI, you'll see the filter select items being selected... (blah blah)
The scripts are now reloaded before those items are displayed.
(That includes the script select box in the model panel)

For a few more features, you can disable the filter using the toggle by the filter select.
This makes it possible to select a script, but run it on a file with a different extension.

Another thing you won't notice is that the filter select and script select widgets are now synced with each other.
(You can see the script select update when selecting a filter)

And another thing to note with the script select widget is it no longer tells you to select a script.
Instead, the process relies on data identification to "Auto Select" a script.

This is useful for files, with either no extension, or a foreign extension, in the hands of noobs who lack the knowledge to decipher the data themselves, to be deciphered by UMC, which will poll the script on the file before executing it if the poll is valid (or True).

That's all I have to offer though :p
In UMC's current state, importing will error because I'm not yet finished with data transformation...
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Interesting news for stuff I'll have by the release :)

I'm integrating MinGW into UMC.
The reason for this is to treat C code just like python code.

Basically, I have an organized section in API.C which will use python to list the sources and folders and compile them dynamically, while appending them to API.C

For example, I'm working on an extension named UGEMath.c
(Yes, this is a python C-API extension, as any source in this directory should be)

This will be compiled and referenced as API.C.UGEMath at runtime

Application of these extensions is the exact same as using raw python.
Meaning if you have an extension using multiple sources, put those sources in a directory, naming the main source "__init__.c", like python.
Except that in C, you can hide these sub-modules :)

The reason for this arrises from a flaw in python's math.sin:

>>> math.sin( math.radians( 360. ) )
-2.4492935982547064e-16

I understand that this is extremely close to 0.0, but it's not 0.0 like it should be...
And i think this is where a lot of my issues have come from.

So I'm working on my own sincos function in C, which should be more accurate, and faster than the individual functions in math.

To add, I'm providing a backend compile function for plugins to provide C sources :)
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
So as of recently I've been working on porting the iqm gpu demo to python...
I'm gonna start working on the new viewer, since I'll be able to animate using the GPU.
I figured I may as well work on the new viewer since I've been rebuilding the backend...
So you can expect animation to work in this next release :)
I should be finished with the viewer before finishing the backend ;)

I've also had ideas for those OOP spud-heads out there who continually yell at me for the functional design...

So on top of what you can already do with the functional interface, you'll also be able to do stuff like:

Obj = ugeSetObject( name )
Obj.Location = [ X, Y, Z ]

Note that Location is a property to a backend vector object, so you're basically calling a function...

This will also be an option:

Obj.Location.X = X

You'll find much more treats and stuff documented in the release.
(Yes documentation is a thing I'm working hardcore on)

EDIT: added an attachment with a better explanation ;)
 

Attachments

Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
well, I've got some bad news for windows users...

you all know how I don't support Microsoft's recent practices in not caring about their user's privacy or security.
while newer version of windows have fixed a few security bugs found in WinXP (the last most secure version of windows), they have added far more worse holes which have allowed automated installation of viruses right out of the box.
now I'm still running strong with XP and havn't had any issues since last being connected to net about a year ago (which is still fairly recent)

so with all that being said, you all know how python has stopped supporting WinXP since the release of 3.5
well, now as of 3.6, they've introduced quite a useful feature being async generators.

I've requested they backport support to XP so that I may continue supporting windows, but if my request gets denied, well, I'm sorry to say, windows users might find themselves without the use of my program, since wine is not a legit testing suite for windows development...

in all seriousness, I hope they accept my request and I hope to see a 3.6 release that supports XP...
otherwize UMC/UGE will end up being for linux and mac only... :(


don't yell at me guys... I'm not the one cutting you off...
don't blame me because I don't support corruption.

EDIT: looks like my request is useless...
it's already official as of PEP11, meaning that my request will just get shoved off...

so, as of the port to a py3 interpreter, likely 36, windows support for UMC will be removed UNLESS someone is willing to compile a portable interpreter for WinXP.
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
welp, Microsoft done did it... just tested the old release of UMC 3.0a on Windows 10 (2 people tested) and neither user could run it.

the issue is with GLFW where by an improper instance is passed to the glfwMakeContextCurrent() function in the backend api.
this is likely caused by a non-existent pointer to the current context handle passed to the function.

so, Microsoft broke support for UMC...
I'll try my best to make it work, but I'm forced to use people as guinniepigs (spell check), so I'm not making any promises...
it works on wine and Windows XP as well as apparently 7, so if you want to yell at anyone, yell at Microsoft to fix their bug.

EDIT: btw, in effort to make a long term runtime performance boost, I'll be dropping the basic Python interpreter and switching to pypy, which is a more JIT-like version of Python meant to increase long-term performance...
basically, ill still need to do my code style for micro-optimization, but when importing something like a Minecraft world, the performance will gradually increase as the interpreter runs.

the good news about the switch is that this interpreter likely won't drop support for XP once a 3.5 version is released :)
until then I'll be sticking to the current 2x Windows x86 interpreter.
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
good news
I'll likely be getting some 3rd-party support for Internet from a close friend, so UGE development should be taking off whenever that's finalized...
this means an actual official release, since Copy fueled development release for UMC.

also, I'm going to refer UMC as the name for the old slow and clunky API...
the one that actually worked...

UGE will be referred to this new API, even though the name will still temporarily stand as UMC.

I know it's taking a long time, the problem is that I'm building something truely universal, and that I lack the knowledge to do so...
and then also the fact that I have no internet, which slows down my ability to gain said knowledge, let alone haults my ability to collaborate on my project as needed...

so there's not much within my ability that I can do to make a release...

I would have loved to have setup a donations account, but I need internet to do that safely as well... (technicalities with SSI, since they'll deduct my pay to the equivalent, thus getting me nowhere)

so yea, trivial issues with no help = no release.

i haven't quit, I just need to jump 4 blocks, but can only jump 3.
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
welp... just so everyone knows, my logic has been defeated, and I have been officially mocked...
this is due to performance issues and design flaws with Python 27 and that there's absolutely no reason to continue using it.

so since I can't use pypy at this current moment, I'm looking into other portable interpreters that might work with Windows XP, since I need an x86 Windows environment to upgrade the basic interpreter.

I'm currently looking into Anaconda, which claims to be portable and perform better than Python, so I'm working on installing that to test with. ;)

EDIT: welp, so much for Anaconda...
it installs, but doesn't run...
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
good news

apparently async in py36 and await in py35 is only syntactical sugar for features which already exist in py34:
https://www.google.com/amp/s/snarky...on-3-5/amp/?client=ms-android-americamovil-us

so I've found a version of Anaconda that works on XP and have already ported it over to Linux
goodbye py27, you will not be missed.

at least now a few broken support cases should work...

in truth, I've grown very frustrated with the types, features, and performance of py27, and have been looking forward to py3 for a long time.

I can now remove most of the annoying type checking code from the UGE backend and work on improving the reliability of it.

yes this is going to delay a bit, but I blame myself for that as it should've been done a long time ago.
sorry guys.

I'm gonna head to the shadows for a bit...
the next notification will be a release.

I will never die, so if you wish to know what's going on, get in contact with me wherever :)
(if I don't get back with you within 24h, I wasn't notified)

just a tip, you might want to request my discord server if you haven't already ;)

EDIT:
There's no longer a need to request. :)
some time ago I started extending my server with my other major projects, but wanted to go even further and allow others to have channels for their projects.

so my server is now The Tcll5850 Community Dev Chat, and you can follow me here: :)
https://discord.gg/0Y8h5pLQK5uS7xMH
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Just to get everyone caught up, I know I promised this post would be a release, but ultimately it's not, sorry guys, but I have done some big things.
like for one, I actually have internet now
for two, I've been working on FORMAT like a bull and have something that literally almost fully works (I'm actually doing testing)
for three, I've been working on the GH for UGE, and have posted some docs about using UGE's API (quality could be better though)
for four, I'm building a semi-standard super-computer to use as a web server for my site

that's about all the big stuff, but I have been in contact as well with hackers of other games, I know the KAR scene has gotten pretty big, and I've gotten fresh new ideas for scripts, even down to possibly supporting exporting HAL's HSD archive format (the format used in Melee, KAR, and other games)

so I mentioned I've worked on the new GH, here's the link to that:
https://github.com/Tcll5850/Universal-Game-Editor
you'll find docs on the 3 frontend standards for the API, which can be cross-used however needed.

I still stand by simpler than blender usage ;)

so while I currently don't yet have a release, I'm actually validating the code to be able to forward to GH for real-time collaborative development.
(note GH is not real-time, but I plan on installing Saros for IDEA to host my own real-time session that'll sync with GH)

once I upload to GH, there's alot of big stuff I plan on adding before I release.

as you guys know me, I can't give a solid release date, but I can say the plan is in action and, now that I have internet, should execute much faster. ;)

so I hope this news isn't completely disappointing :p

EDIT:
for some extra info on UGE, the proxies I previously mentioned worked for everything but facepoints, so I ultimately ended up scrapping them for what I have now that functions similarly (actually looser), but more performative than ever, despite memory use still being a bit above preferred...

I do plan on porting the API to C-Python to hopefully get things running faster with more memory management...
I've already had to do some incredibly hacky and complex stuff to get python to run my API properly.
see here: https://stackoverflow.com/questions...-to-a-class-without-a-reference-in-class-dict

but that aside, one of the things I'm working on is treating C like python and have actually included a portable mingw compiler to compile on the fly when (re)loading.
I strictly recommend C because C++ is super slow to compile.

so yeah, I've been very busy :p

EDIT2:
if you aren't hyped yet, this should help :)

currently crashes on the primitive creation, line, but I'm completely caught up to where I was with proxies, without them.

EDIT3:
I am now beyond that point and am farther ahead than I've ever been with this new API :D

here's the attributes of Primitive for those wanting to see REAL results ;)

I need to add a __repr__ function to UGE_CONSTANT to make it display it's name instead of the object :p
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
sorry it's not more though...
it was a B to work on without internet, and I had to go through crap the hard way...

at least I learned about metaclass programming along the way :p
but still, I would've liked to have had more done...

but at the same time, UGE is basically at the level of an AI that does it's best to keep it's data in tact and operable, which isn't exactly as simple as your typical "Hello World!" application... lol

at least now I won't have to rewrite the API if I plan on adding a new feature...
I had to kill off 3.0a because of that... it was just becoming way too unmanageable.
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
got this B to finally bend to my will!
successfully created a Facepoint instance!

also fixed up some minor repr issues :p

still need to port UGEVector to my private standard... heh

EDIT: an unexpected outcome...
all I did was write the code in the test and run, expecting a crash...
but instead, it worked... somewhat:


now you can at least see it truly is possible to format literally however you need :D

heck, you can even do stuff as ambiguous as:
Code:
Facepoint.Vertice = dict( WXY = (1.,1.,0.) )
just one thing to note though
since Z wasn't given a value, it's marked as None: <vector X: 1.0, Y: 0.0, Z: None, W: 1.0 >
because of that though, iterating though the vector stops at Z, returning only X and Y.

EDIT2:
just an update to notify vectors are finally created properly :p

here's the debug info as well to show Forwarder works with them properly as well ;)

^ this is the reason for so much pain right here
I went through 3 API rewrites to figure out a decent method to get this portion working
(Facepoint.Vertice updates and references from meshObject.Vertices)

EDIT3:
fixed setting Forwarder instances directly
this also shows some of the many various ways you can assign data to them:
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
well... of all that good... there had to be a bad -.-*


I was so close to prepairing GH for my code... why now -_-

what does this mean exactly?
/dev/sdc is my 1TB data drive which stored all of my projects I've been working on.
the problem it had for years (after XP64 corrupted itself) was a power loss/short issue where it kept spinning up every now and then...
looks like it finally took it's toll and blew up the controller.
(it wasn't entirely the connectors, I've used about 7 PSUs on the drive with the same results)

the data (everything including my home directory) is fine... but now I'm stuck not being able to do anything until it gets fixed (a new board and possibly some professional recovery).

yeah I even had my home directory saved for the moment I intended to install Solus on my OS HDD (or a newer HDD), so I couldn't even boot onto my desktop for a good moment...
finally created a temporary home directory to at least get somewhere, but I still can't really do much without everything I was working on...

btw, this was a Western Digital HDD that now makes 3 dead HDDs under it's name
Seagate, Toshiba, and Hitachi are doing better.
Maxtor is still the worst.

my 500GB Hitachi media drive (ISOs, Rips, music, and video) doesn't seem to be suffering from it's power loss issue anymore... not sure what's up with that, but that's been since I recieved the drive...
at least I'm not being notified of any imminent failure with it like I was with the WD.

EDIT:
after a few attempts to identify /dev/sdc, I was able to get somewhere:

I'm attempting a data recovery currently, if I can recover the ext4 FS, I should have all my data.

EDIT2: ok, so after some rigorous poking and prodding, I need to format the drive before I can use it again...
but before I do that, I need to image it to recover the data with some seriously low level tools... sleuthkit seems to be the best from what I'm hearing, but I need to get my hands on another HDD...
the largest I have is 500GB, and that's already in use...

at least I can recover it and don't have to get professional service with some advanced hardware to do it...
so it looks like I'm taking a forced vacation for a bit...
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
so thanks to Western Digital not being a very noteworthy brand towards me (3rd dead HDD, only have an 80GB IDE drive left), and delaying my work by destroying all of my projects, pictures, portable programs, installers, corrupt drive images, and even my linux settings and whatever else was in my /home directory that wasn't media...

I've restored a dated backup of my most recent sources and uploaded them here since I can't trust my PCs to securely hold my data like I need them to.
https://github.com/Tcll5850/Universal-Game-Editor
I blame NTFS for cooking the drive and giving it the power issues it's had for years...

so yeah, I'm no longer close to a release, but you guys can watch me update my code...
I have SparkleShare managing GitHub between my PCs.
I couldn't do this before because there was quite a bit of junk clouding up my workspace that would've been transferred otherwize, so I was pretty much set for failure with my fingers crossed this whole time...

I have enough confidence to say that in about 2 more days I would've had an upload of FORMAT to GH from my last post showing the API working...
now I have to try to scavenge to figure out what I did blindfolded yet again...
(I'm sure you guys remember me finishing my 3.0a API docs just to have lost them to corruption because I had no way of uploading)

at least now I have a solid idea of my API and what I did, but as for redoing it, I have to try and recall exactly what I had in every module, which won't be easy...

watch, the next time this happens, GitHub will be Gov't sanctioned and taken down and all of my PCs will fail.
either that or something will try to kill me, cuz I ain't quittin until it's done.

now that I actually have standards, hopefully I can make it to where others can work on my code more easily and get this thing to finally take off.
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
so I've made some progress on UGE, and have gotten automation working (see line 21) :)

note that automation doesn't require a dict, but anything that acts like a dict
eg: using a uge_struct to represent attributes of a UGEObject
mis-matched attributes are simply overlooked, so it's safe do do whatever you like or need to.
also due to the dict-like behavior, you don't need to worry about attribute order in the uge_struct, the API will internally update what's recieved accordingly ;)

so automation is the representation of UGEObjects with data ;)
btw, the automation format is exactly the format to be used in my SES format. ;D

EDIT:
work has also finally begun on FILE
there is now a File class as a UGEObject in the API with access to typical Name, ID, Parent, Child, Next, and Prev attributes as well as Size, Offset, and Path

you can access the file with CurretFile or ugeGetFile()
yes, ugeImportFile has been renamed to ugeGetFile

to add, dataspaces are also in the works
think of a dataspace as a temp-file inside a file
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
welp, this is some concerning information...
to think I just started my GH orgamization, and now this BS starts happening:

looks like I'll be slowly taking my leave from GH then...
I already support Microsoft by playing Minecraft, which is more support than I'm comfortable with...
I will not support them with GH as well. >_<

as for where I'll be moving my repo to, I'll probably host my own git and link everything to there, but it's going to take a while to set up. -.-*
(it's something I wanted to do for UGE anyways, so whatever)
 
Last edited:

legoj15

Smash Rookie
Joined
Sep 10, 2015
Messages
3
NNID
legoj15
3DS FC
4441-8940-6379
Damn, I was really hoping that the acquisition wouldn't affect any of the repos I follow in GH.....

Welp, just don't forget about linking your new git here :p
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
Damn, I was really hoping that the acquisition wouldn't affect any of the repos I follow in GH.....

Welp, just don't forget about linking your new git here :p
don't worry, I will, as well as most of my other threads. ;)

EDIT: so I've been talked into joining GitLab temporarily until I have my own git server running well. ;)
I'll post the link once that's all set up.
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
so, just to update, things are still being set up, but overall the repo is pretty much ready...
here's the link for that: https://gitlab.com/Tcll5850/Universal-Game-Editor
Note that it IS restricted and you must request access. (contact me before doing so if you want your request to be accepted)

aside from that, I've also updated the links in the 3rd post to a redirect to my official thread:
http://tcll5850.proboards.com/thread/144/public-uge-discussion-thread
I'm dealing with life, and can't manage as much as I used to, so I'm afraid I have to redirect to keep everyone updated.

in other recent news, my secondary monitor decided to S itself, and the board that manages the electron guns of the CRT almost caught fire due to a few bad caps.
you can see just how blackened it is in this image: (pretty sure dust and age are to blame)

luckilly it's repairable, and all I need to do is replace a bunch of caps...
hopefully I should be back up soon, working off 1 monitor is a nightmare :p
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
yo, whoever's github this is, I know you're on here, I need to invite you to my gitlab group and I can't remember who I know you as:


I can't send an email from GH anymore...
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
just so everone knows the project isn't dead ;)
I've recently been urged to improve the DATA backend
or rather how it works in the frontend...

granularity between endian selection has been a hassle, actually more than that really...
so I've worked on an idea that would improve that through automation.

note that the old system is still provided as a final override,
rather than backwards compatibility, since that's been out the window since the death of UMC 3.0a
(at least I tried guys, but for those who don't know, that blew up in my face)

anyways, here's how it works...
you define a base struct type with a `big` member/attribute:
Code:
big = '\xfe\xff'
little = '\xff\xfe'

big_string = string(2)

HEADER = struct(
    magic = string(4),
    big = lambda value=None, **kw: big_string( None if value is None else ( big if value else little ) ) == big, # value should be either None, True, or False
)
I know this example is a bit unintuitive, but I'm using a practical use case with a Byte Order Mark (0xFEFF for big and 0xFFFE for little)
the `big` attribute uses an augment that returns True or False if the BOM is big,
with included logic for write operations where `value` will be None, True, or False.

after that, you define your base data type which dereferences the struct (yes I'm actually using my pointer system,
and defining this stuff outside of the R/W operation functions):
Code:
# note that deref() will return a deref object if an R/W operation is not being performed when called
u32 = U( 4, big = deref( 0, HEADER ) )
basically
when you call the u32() definition
it will see that it's `big` argument holds a callable object/augment
when reading, that augment will return the HEADER struct instance at addr 0
and since it's a struct on the `big` argument, the u32 definition's read function will retrueve the struct's ['big'] member, which will be either True or False

note that if there is no HEADER instance at addr 0, the deref object will create it when called
but you should almost always call a header-struct first, as shown here:
Code:
def ugeImportModel(*args,**kw):
    header = HEADER()

    value = u32() # endian determined by header.big
something else I've been reworking is field() which has been turned into a struct-type:
Code:
myField = field(
    __size__: [int, struct, augment] = 1, # (in bytes) determined by ceil( member sum / 8 ) if unspecified
    __addr__: [int, struct, augment],
    member1 = 3, # 00000111
    member2 = 1, # 00001000
    member3 = 1, # 00010000
    member4 = 1, # 00100000
    member5 = 2  # 11000000
)
here's an example reworked from my BRMDL script:
Code:
        Influence = field( # Tcll: thanks BJ :)
            Len = 4,          # 0x0000000F
            Adr = 12,         # 0x0000FFF0
            link_index = 16 ) # 0xFFFF0000
)
as you can probably tell, the byte-size of the field will be auto-determined but you can specify if you need to oversize it
(I'm also working on __align__ for struct/array types which should align the value within an allocated space)

also, use if the Influence field can be any of:
inf = Len,Adr,link_index = Influence()
inf.Adr
inf['Len']


and you may have also noticed above that the definition of u32 uses a new data type call
while data types like bu16 and bf32 are still provided for ease of use, you may override these with your own definitions that are more flexible with retrieving needed information from data structs.
the base types look like this:
Code:
u8 = u( size: [int, struct, augment] = 1, offset: [int, struct, augment], big: [bool, struct, augment] )
s8 = s( size: [int, struct, augment] = 1, offset: [int, struct, augment], big: [bool, struct, augment] )
f8 = f( format: UGE_FLOAT_FORMAT = UGE_IEEE754, size: [int, struct, augment] = 1, offset: [int, struct, augment], big: [bool, struct, augment] ) # no longer compatible with any byte size under IEEE754
h8 = h( size: [int, struct, augment] = 1, offset: [int, struct, augment], big: [bool, struct, augment] )
yes you're reading correctly, I'm restricting IEEE754 to the existing size specs.
bf(5) was cool, but it wasn't standard, and as such, anything written with it would likely be incompatible when an official standard is actually released.

funny enough though, I actually plan on releasing custom standards for float definitions (not by this release though)

and finally, union() is being added as another struct-type object
basically, it works almost exactly like a struct(), but all members occupy the same address space

also, changes are being made to how virtual files are managed
rather than JUST holding the data as an array('B'), the UGEFile class will actually emulate a file stream, where 3rd-party modules like pillow can manage them appropriately without needing stream wrappers like StringIO()

the UGEFile object will also have it's own global `big` attribute, which will be the final fallback for all data objects relying on endian.

so yeah, quite a bit of change going on for UGE ;)
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
some extra new functionality coming by the release
inline equation augments:

^ of course it'll be much more refined than this (you should be able to see the equation in the object repr), and the opProxy class should be much more hidden.

so basically, op is the resulting object from bu32+10+5
what it does is, since the object is an augment, when called, it reads a bu32() value from the current file, then adds 10 and 5 to it.
for the above test, there was no file to read from, so the value it held was 0 + 10 + 5 being 15, which was returned from the call.

usage for these is anywhere you can put a UGE data struct.
here's an example from my BRMDL script I'm currently porting (really I'm just taking notes by porting this):
Code:
        Registers = array( switch( bh8, {
            '08': struct( __name__='CP', Command=bh8, Value=bu32 ),
            '10': struct( __name__='XF', Length=bu16+1, Command=bu16, Structures=array(bu32, count=deref(CurrentFile.getOffset-4,'XF').Length), padding=bu8 )
        }) )
you'll notice 2 of these inline augments for 'XF'.Length and for the deref() addr input.
note getOffset is pending a name change since you should be able to set the offset as well (it is an augment after all).

and you've probably noticed another feature as well, deref() being supplied a string for a struct.
remember the deref object mentioned above?
well here's another case where that's needed...
since the struct we need is the parent of the array and is not defined until template-automation begins,
we refer to the struct object by __name__ when the deref object returned is called
(which is when the struct will actually be defined and registered before it's called to call the array which calls the deref object down the hierarchy)

this should greatly reduce alot of the complexities when working with binary data :)

but this is only just the surface, wait until you guys see what I've got planned for string()() ;D

EDIT: update.
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
made an official update to switch()

initially it's just a function that stores a value for testing against cases
but there's now another way to use it that returns a switch object for automation:

sw = switch( struct, { comparator: struct } )

example:
Code:
sw = switch( bu8, {
    0: bu8,
    1: bu16,
    2: bu32,
    3: bu64
})

# read
result = sw() # will be an instance of the struct returned from the comparison, or None if defaulted

# write
ref = sw( value = (0, 255), label=('','') )
to explain it simply
when called, the switch takes the value returned from it's supplied struct and compares it with a key in it's supplied dict...
if a struct is resolved, that's called, and the value of that is returned.

something this could very easily be used for is the TEV registers shown here (sorry for no highlight)
* can't restore image *
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
well, I've just found what I think is a plausable bug with py34 file streams
here's a test file I've created opened as: (not doing code blocks because it's harder to make out when it's not syntax highlighted)

>>> f = open('test.bin', 'ab+')
>>> f.seek(0,0)
0
>>> f.read(4)
b'test'
>>> f.read()
b'ing'
>>> f.seek(0,0)
0
>>> f.read(4)
b'test'
>>> f.tell()
4
>>> f.write(b' insert')
7
>>> f.tell()
11
>>> f.read()
b''
>>> # uhh, wait a minute
>>> f.seek(0,0)
0
>>> f.read()
b'testing insert'
>>> f.tell()
14
>>> # so the file content is 14 bytes long
>>> f.read()
b''
>>> f.seek(-3,2) # 11 - 14
11
>>> f.read()
b'ert'
>>> # ^ this is what the above was supposed to return

I think I'm going to fix this with UGE's File objects, since I'm making them emulate file streams
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
good news, I've finally started working on CLI options for usage, and think I've figured out something decent:
Code:
uge.sh
    import
        script name
        scope UGE_####_SCRIPT
        option key value
        root name
        filename

    export
        filename
        option key value
        scope UGE_####_SCRIPT
        script name
        
        root name
        world name
        scene name
        object name
        material name
        image name

        as newname
compression has been removed from the import mechanism and is left as a frontend operation within scripts
since scripts should be able to detect if a file is compressed, and which compression standard to use (*.pcs anyone)
having the compression specified on the import mechanic would likely lead to double operation
so instead, compression support is being provided as methods on File objects (also with functional wrappers of course).

but as for CLI use...
the script and scope commands are entirely optional as both can be detected by polling the file's data, or for export detecting the handler from the extension.
the options below the split on the export section are selectors which access data from the CurrentRoot.
for example, if you wanted to export selected objects from a blender scene to an obj (which you'll also be able to do through the UI as well),
the CLI input would look something like this:
Code:
uge.exe import blender_scene.blend export model.obj object 'rig 1' object 'rig 2'
hope you guys enjoy :)

EDIT:
just wrote a quick test code:

and while it's a bit more complex than I'd like (which I'll work on), it works :)

here's the output broken down:
Code:
{
    'import': {
        'path': 'blender_scene.blend'
    }, 
    'export': {
        'data': [('object', 'rig 1'), ('object', 'rig 2')], 
        'path': 'model.obj'
    }
}
note that the 'data' section should consist of the actual objects in the API rather than the tuples you see there
but it will keep it's order as shown ;)

EDIT2:
made some updates to the logic
if you want to import resources from multiple files to multiple roots, and select individual resources from those roots to export to a single file, renaming them in the process:
Code:
uge.exe\
    import 'model0.fbx' root 'root0'\
    import 'model1.fbx' root 'root1'\
    export 'merged.fbx'\
        root 'root0' object 'rig' as 'rig0'\
        root 'root1' object 'rig' as 'rig1'
note that this also allows you to name the roots you want to import to ;)

EDIT3:
would probably be good if I showed a shot of the update working... lol


breakdown:
Code:
{
    'import': [
        {'root': 'root0', 'path': 'model0.fbx'}, 
        {'root': 'root1', 'path': 'model1.fbx'}
    ], 
    'export': [
        {'data': [
            ('root', 'root0'), ('object', 'rig'), ('as', 'rig0'), 
            ('root', 'root1'), ('object', 'rig'), ('as', 'rig1')
        ], 'path': 'merged.fbx'}, 
        {'data': [('root', 'root0'), ('scene', 's1')], 'path': 'other.fbx'}, 
        {'data': [('root', 'root1'), ('image', 'backdrop_high')], 'path': 'image.png'}
    ]
}
yes, I know I have nothing to actually show the rename
when the objects are stored, they should have a renamed copy

and yes you can also have multiple export jobs ;)
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
post info deleted per request of the one in focus.
nobody cares about the criminals who were mentioned here, everyone seems to think they should be rewarded for their actions
and the dude I was backing up has had too much stress happen to him recently

I don't feel as welcome in this community as I used to, especially after what happened to the Melee Workshop Discord server
and I can't help but feel I was set up by Doq and all them

so whatever, if they want criminals to run things, then I don't care anymore.

I'm not quitting my work
but if I'm ever inactive from the smash communities for an extended period
it's because of false information spread about me and my friends
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
getting back to topic with UGE, I AM working on designing the animation system, and so far, I think it's been almost perfected.


it supports just about as much as blender (lacking dynamic support for reasons of extended definition, planned for later), which already has more support than Maya

the functional frontend will be slightly different as well ;)

I'll update the wiki with some docs that should hopefully be easier to follow than the src-docs I had up earlier :p
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
if anyone's wondering what's haulting UGE's development currently

it's because I need to figure out how to do sub-process IPC with pipes (not sockets) using native windows functions provided by python's native C modules.
(PyWin32 does the same thing, but it's just as buggy as it is bloaty, and the binaries don't import after the first run)

the subprocess module only does communication to child and then provides console pipes
it doesn't provide a read pipe from the child process.

more info here:
https://www.daniweb.com/programming...ipc-between-a-subprocess-under-native-modules
as usual, I'm not getting the help I need...

but that's not the only thing slowing me down
I also need to make a custom module loader for UGE libs, which is proving to be a butt :p
 

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
now that I'm free from the cruddy platform Discord, you guys should hopefully see a lot more activity from me here regarding UGE. :)

I'm actually rather glad Punch freed me from that cancer, but I want to note that due to some recent issues with Discord, I've been RATted with a RAT called Pupy (yes, on linux, I never said it couldn't be infected)...
after manually removing it, I now have a lot of cleanup to do to ensure my data is safe if it should happen again and damage is actually done.

no, I was only RATted just to get the Discord token of one of my alts I used for protecting my server, and the process was entirely automated and unnoticeable until the moment my alt transferred ownership.
(everything's in order now though, and I did get ownership back before the grief above when I transferred to Bubs)

anyways, so it'll be a little bit before you'll see more activity. ;)
 

TDRR

Smash Journeyman
Joined
Sep 18, 2017
Messages
286
Location
Venezuela
I wonder, what are the formats UGE currently supports?

Also, how are you going to stop those bad guys from using UGE?
 
Last edited:

Tcll

Smash Lord
Joined
Jul 10, 2010
Messages
1,780
Location
The Gates of Darkness
NNID
Tcll5850
I won't stop them from using the open portions of it that can be freely downloaded or distributed.
but as far as connections go to my server and shared resources, I can at least make a huge dent there using both IP and device tracking among other things.
(I'm still learning stuff while I can't afford things atm)

and yes, I'll be sure to protect everything as much as I can, so that they can't break in and take control.
whatever you share on my server will be secured behind my own DNS.


it'll be more secure than this place, that's for sure. :D

anyways, as for formats
I've been working on adding a few more behind the scenes ;)
paricularly HSF and NDM :D
and that's aside from all the others supported in UMC I'm working on porting :)

currently I'm working on tests to get deref() augments working better with multi-attribute access:
Code:
test = struct(
    data0 = bu32,
    data1 = bu32
)

main = deref( 0, test ) # creates an augment if not within a R/W operation.
sub0 = main.data0 # creates a new augment to access test.data0 when called.
sub1 = main.data1 # creates a new augment to access test.data1 when called.
but while the backend is in the works, I won't have anything until I'm able to run it inside a secure subprocess...

I'm not taking any shortcuts nor risking anything. ;)

EDIT:
design improvement to deref() and datatypes to make things actually make sense:
- deref() now supports value and label arguments to do deref-set more appropriately, including through automation
- datatype().set() has been removed since it was a confusing feature of deref() and was too open
Code:
main = deref( 0, bu32 ) # augment

test = struct(
    data0 = main,
    data1 = bu32
)

def ugeExportModel( options ): # well this is a first
    
    result = test(      # the struct is returned for debug purposes
        dict(           # this is supplied as the value of the struct (automation writes the values to the file in separate locations)
            data0 = 25, # written to address 0 as specified by the dereference
            data1 = 32  # written to the relative address of this struct (as the first item in the datablock)
        )               # note that this is a dict, so the order of the values doesn't matter here (the struct-def determines that)
    )
    
    result2 = deref( 0, bu32, value = 56 ) # overwrites the previous value of 25 with 56

    # result.data0 should now be 56, or rather the exact same object as result2:
    print( result2 is result.data0 ) # should be True due to how the mechanics of deref() work (a bu32 object already exists at address 0)
EDIT2: the longer I think about this, the more I'm favoring to just make deref() an augment like I recently did to field()()
the pros outweigh the cons of doing as such:

pros:
- processing is faster (when done appropriately) without needing to check if a deref() call should return an augment, and instead always augments.
- no longer need to use strings within inline struct automation to dereference a value within an automated struct: (easier to maintain)
before:
Code:
        Object = struct(
            size              = bu32,
            MDL0_header       = bs32,
            Link              = bu32,
            CPL               = bu32,
            CPH               = bu32,
            INVTXSPEC         = bu32,
            Attr_size         = bu32,
            Attr_flags        = bu32,
            Attributes        = struct(
                __size__          = deref( BRMDL.addr-32, 'Object' ).Attr_size,
                __addr__          = bu32+24, # jump to this address before reading the values.
                padding           = skip(10),
                Registers         = array( switch( h8, { '08':CP, '10':XF, '61':BP } ), count=6 ) ),
            Buffer_Size       = bu32,
            Data_Size         = bu32,
            Primitives        = Primitives,
            ...
after:
Code:
        Object = struct(
            size              = bu32,
            MDL0_header       = bs32,
            Link              = bu32,
            CPL               = bu32,
            CPH               = bu32,
            INVTXSPEC         = bu32,
            Attr_size         = bu32,
            Attr_flags        = bu32,
            Attributes        = struct(
                __size__          = deref( BRMDL.addr-8, bu32 ),
                __addr__          = bu32+24, # jump to this address before reading the values.
                padding           = skip(10),
                Registers         = array( switch( h8, { '08':CP, '10':XF, '61':BP } ), count=6 ) ),
            Buffer_Size       = bu32,
            Data_Size         = bu32,
            Primitives        = Primitives,
            ...
this example used to have more to it, but I found a better way using less dereferencing

cons:
- open dereferencing uses a tiny bit extra code:
before:
Code:
def ugeIOFuncdef( Options ):
    ...
    data = deref( pointer, bu32 ) # read (copy object)
    data = deref( pointer, bu32, 10 ) # write (update object)
after:
Code:
def ugeIOFuncdef( Options ):
    ...
    data = deref( pointer, bu32 )() # read (copy object)
    data = deref( pointer, bu32 )( 10 ) # write (update object)
this is really nothing to complain over, considering how much the backend actually does, as well as where UGE is heading...

- vectors are augments
- switches (as you can see above) are augments
just about every type of object or operation is heading down the path of inline automation.

no it's not replacing functional or object oriented methods of use, only unifying everything for cross-compatibility.
(you can use whatever pythonic preference you prefer, automation is just another option)

EDIT3:
currently I'm trying to work on what happenes to deref attributes to verify they can be updated through write operations.
as well as a brand new backend update mechanism that works similar to *.set() with less usage restriction (since deref()() calls this).

this was a test to see if a child sub-class could use a parent slots attribute descriptor after it's been removed from the parent...
turns out I can: :)
(if this image isn't appearing for you, the fault is with smashboards)
image
so this is the new private and protected (not to say it can't still be accessed) mechanism for retrieving the update method relative to the datatype object instance within deref()()

it can't be accessed unless you really understand the inner workings of Python, and even then, static access is not guaranteed.
(python is inherently insecure, as the access it gives you is the same access it uses, so I can only do so much without cutting performance)

anyways, for deref() attribute access:
Code:
aug = deref( pointer, bu32 ).__addr__ # this is read only and will result in an error if given a value

dummy = struct(
    data = bu32
)
aug = deref( pointer, dummy ).data # this is writable and can be supplied with any value allowed by bu32
I'm trying to work on a mechanic that will catch the error case appropriately.
 
Last edited:
Top Bottom