I thought I would do something unusual, I will speak of my work so that beginners or hobbyists and passionate people who wonder how it is out there in the wild, can get an image of what it is to work in this industry.
Also, as a bonus, it will give hobby programmers a sense of scale into why it takes so much more time to professionals to get things done, compared to when its done home. This is linked to the difference between what we call, a prototype, and a production code.
Disclaimer: the post is detailed, on purpose. It can be boring. So bear with me
So, last week, I had to start development of a task that is related to making a tool I develop, cooperate with Maya, in the sense of being able to control Maya remotely, and export/import stuff from it.
The first part of this is to document yourself, if like me you are not familiar with Maya. So I use google, and I stumble across the commandPort mel command. (Mel is the script language inherent to Maya)
This command allows to command Maya remotely. Just what I need.
It happens to have a port open by default, but this port when accessed pops a security dialog (for good reasons), but it is just too bad in our workflow because it disrupts the "automation" and make our tool integration bad.
So rather, I found that starting my own commandPort didn't raise this problem.
But, the user would have to click a button to start the service, which is the same problem as the security dialog from before. Back to square one.
Only, there is something called userSetup.mel/.py that can be used to put startup scripts.
Perfect this is the good place to put our command.
Except its not that simple, will artist need to paste this line by themselves ? No, it needs to get automatically installed when installing the company's internal toolsuite. That is all ok, I just need to put the file containing the one-liner into the installer and specify the destination.
If only it was that simple.
userSetup.mel/py is a script that is shared by other applications that wants to make exactly this kinds of things. Therefore you cannot overwrite it stupidly.
Most companies don't care. Like 3d connexion or Substance, they just overwrite it, and they are doing-it-wrong™.
The good way to do it, is to APPEND your modification to it.
Fine, I'll write a python program that does that.
Except, how do you locate the folder for the script ?
Most of the time it is in the user's document/maya folder. But sometimes it may be located by the environment variable called MAYA_APP_DIR, therefore you need to check if it is defined and follow it if so.
Then, it is not over, because in case the installer fails at some other point (remember its a tool suite), it must be capable to rollback, so uninstall as well. Which means detecting your addition (I used recognizable patterns that I put in comments) and removing it, using some string operations. Fortunately python is awesome for that.
But in the end, the script is 200 lines, to install a 1 line script. Yep... Actually the one line script ended up being around 20 because of exceptions safety, and modularization for the future I chose to load code located in another sibling script file on the side of userSetup.py, using python's awesome self interpretation "execfile".
However, one-does-not-simply™ load a script on the same folder as the current script, because it uses the current APPLICATION working directory.
For that, I fixed it using a debug stack inspection system internal to python, that is able to tell the current script's full file path. Yeah !
Then, I need to integrate invocation of this installer by the parent installer, which is written in C++, so I used PyInstaller to make an .exe out of my python script, and then used CreateProcess and WaitForSingle stuff from Win32 API to invoke my sub-installer. Then add the files into the all-mighty installer solution.
I had to write a C# GUI to test rapidly if the Socket connection was working with Maya, it didn't take long at all thanks to google again, the code was already posted somewhere, so copy paste + do a quick GUI over it and rollin' !
Then I needed to modify my main application tool, the one I want able to speak to Maya, its in C# as well, I factorized the code from my GUI tester, and integrated it, then used it to start by opening the maya scene.
Which... could only have happened after I made a Maya launcher, by detecting the install path (or requesting manual input if not found), and execute maya with some Process.Start stuff.
Only it is not that simple, because you do not want to start a flock of Mayas, so you need to check the running processes on the machine. I used "maya" as a string identifier, it works for me now, I hope Maya is always called Maya... Dangers of hardcoding...
The scene path itself was difficult to retrieve because my tool works with derivatives assets that are exported, but thankfully enough they bare the original Maya path in their headers. Which are readable by a library a colleague did.
So a little toying with my C++ utility helper, and bit of PInvoke and up and rollin' again.
And then I realized that I had to send multiple commands one after the other, like "load scene" and "select some stuff". But my system was spawning a new thread for every command, therefore creating a potential race condition which would have made the selection command appear first to Maya.
I fixed it by using only one thread, and a .NET4 concurrent collection called BlockingCollection using an underlying ConcurrentQueue. Ok, go to next !
I had something working at this point, but then I realized the auto-sync, which is a feature of a Maya plugin we have, didn't work, and I learned it was due to the name of the scene being different in the (third) external tool I have and the Maya scene's name.
This is actually a huge issue because all of my internal identification system works on string made of the exported name, which can be anything. This will take a long time to fix, and is not done today, it will be for this week.
And this is how, from something as simple as that, and that should take 4 hours tops, according to common sense (non programmer sense), you end up using a week and to finally realize that it will actually take 2 or more.
This is typical your-everyday-story as a professional. It is typical that a solution to a problem cascades into a deep tree of implications like this very small original problem.
Share your own if you think you have a story ^^ !
We're offering banner ads on our site from just $5!
Lightness1024Member Since 06 Aug 2009
Offline Last Active Dec 03 2014 08:44 AM
- Group Members
- Active Posts 204
- Profile Views 5,601
- Submitted Links 0
- Member Title Member
- Age Age Unknown
- Birthday Birthday Unknown
Topics I've Started
16 September 2014 - 08:01 AM
06 September 2014 - 05:27 AM
first of all, I encourage the readers of this topic to go to google image search, and type:
Ok, so there are multiple conventions clearly, some put the horizon on the small part of the cross, some turn the cross on the side and put the horizon along the long edge.
I have even seen the top part of the sky being split accross the 4 segments around the center.
Now, there is a somekind official definition that works for me:
direction target sc tc ma
---------- --------------------------------- --- --- ---
+rx GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
-rx GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
+ry GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
-ry GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
+rz GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
-rz GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
I'm not sure if it works for right handed AND left handed coordinates convention ?
But it works in my left handed case.
In my case the convention is like that:
+Y is the top, and +X the right, while +Z is the front.
I think only the "+Z is the front" is somehow one of the most standard things when it comes to convention because this is where a camera is looking with a unity matrix.
What do you think about cubemap conventions ? how does it relate to coordinate conventions ?
03 September 2014 - 05:54 AM
I'm running Cubemapgen (modified by Sebastien Lagarde), and I notice if I change the "input degamma" slider it runs some seriously heavy algorithm that runs for like 20 minutes (what the heck ??).
Anyway, during this time it brings my little core i5 at 98C for core0 and 101C for core1.
its a 3230M supposed to run at 2.6 Ghz stock, but coretemp reports its actually at 3Ghz. It has a T-Junction of 105 degrees so the core circuitry itself is safe, but you know, at 100 it may melt stuff around !
Its a Dell 17 inches laptop.
What do you think ?
14 October 2012 - 06:18 AM
I need a code representation of level data. say I'm using C++ I have a "Level" struct storing layers, a layer is a grid of objects.
each object represents some kind of displayable sprite with a position, orientation, sprite id (e.g. lookup-able by filename using an external global sprite/images central manager...).
The issue is, storing the sprite ID is enough to store all properties (position/orientation etc) because the display engine (say SFML) has a copy of all this information.
So the question is, should the "LevelObject" structure store position, orientation, size... in its own structure and transfer to SFML when necessary using an "UpdateViewFromModel" function ?
Or should it suppose that this is dual property storing, and that it will cause confusion and incoherence at some point, because the View stores a copy of the Model. So we could consider the view as being the view and the model at the same time ?
27 September 2012 - 07:41 AM
in their LPV implementations, both Andreas Kirsch (c.f http://blog.blackhc....annotations.pdf)
and Benjamin Thaut (http://3d.benjamin-thaut.de/?p=16) are using similar definitions, either premultiplied with c0 and c1 coefficients or not, but basically the same. (0.25, 0.5) along z (for ZonalH), after multiply with c0 and c1.
you can find the rotation formula along axis n in Andreas Kirsch annotation, and concludes that it results to the same thing, but spread on all SH coefficients (in the band 2), just multiplied by normal vector: (0.25,-0.5*ny,0.5*nz,-0.5*nx).
However, if you read Ramamoorthi, they use another way of calculating the coefficients, instead of doing the actual integrand to project the cos(theta) function on the carthesian basis functions, they use the base definitions of the Ylm to extract some horrible formula full of square roots and factorials, and they decide the coefficients are:
(Pi, 2 Pi / 3, Pi / 4) for 3 bands of Zonal Harmonics. (so simply 0 on the non zonal terms)
this is relayed by Sebastien Lagarde on his blog:
though I don't get the feeling that he is truly understanding those coefficients since he mention the sources (peter pike sloan, robert green and ShaderX2) to get them.
and talking about Sloan and Green, we also find disturbing lack of consistencies between papers, notably in the cartesian definitions of the SH basis, when one claims the Zonal of order 2 is k*(3z²-1) the other (Green) claims k*(2z²-x²-y²) !! wtf ?
and there is another inconsistency in the constant of the l=1,m=2 coefficient, where Green claims it is 1/2*sqrt(15/Pi), the others claim it is 1/4*sqrt(15/Pi) which is quite different.
When I calculate the projeciton of the cos lobe on that l=1,m=0 coefficient I get sqrt(5*Pi)/8 which is a coefficient I found nowhere on the literature though I quaduple checked my math.
Also, nobody talks clearly of how to rotate the order 2 coslobe, in ramamoorthi it is completely forgotten, like if it was trivial, in Green he suggests it is extremely complicated and "reaches the limit of current research".
In Sloan, you find the idea that Zonal rotations are simpler, "only O(N) compared to O(N²)" he says.
And if you read Halo 3 engine siggraph 2008 slide presentation, the SH rotation shader they have seems to be quite complicated.
Though this one surely is for any SH ... :/
I simply want to project a goddamn environment map into SH, convolve it with a coslobe.
there is a sample code from Nvidia for that but for paraboloid cube maps.
but I don't understand really how to do it properly, and trying something blindly is the best way to get something, thinks that it works but actually it is wrong but in a way that is difficult to see.
(go prove that an irradiance map is biaised, or incorrectly scaled etc...)
thanks for any help on that.
edit: actually I found a paper that corroborates my result :
but it clearly is different from the result of Lagarde and Ramamoorthi for coefficients of the same function. (ramamoorthi calls it Âl)
the only missing thing now is the rotated clamped cosine lobe in 3 band SH.
edit2: i found some promising stuff for that last part : http://www.iro.umont.../SHRot_mine.pdf
however it will take me ages to understand that paper :'( if I can at all.
for the moment, i'm just going to calculate projections of cos lobes along 6 directions and interpolate between them linearly. at least i can grasp that.
edit3: I have calculated coefficients for the cosine lobe along x : [S0=sqrt(pi)/2, S3=-sqrt(pi/3), S7=sqrt(15*Pi)/8] 0 elsewhere.
the plot is attached file to this post. we can clearly see that it is tilted and not resembling the coslobe along Z. Which would invalidate the famous "rotation invariant" property of SH that everybody seems to praise. Or rather, if I understand it, they seem to praise an erronous assumption that rotations will not make the projection vary, which is false, the property merely says that rotating the coefficients will get the same projection than reprojecting the rotated function. It never mention anything about keeping the same shape. Sload and Green both mention that function will not 'wobble' when rotated. I think this is false and my plot tends to prove it.