I have created a model in 3dsmax with real world measures (in cm). What I am doing is a button box for Pc SimRacing, and what I want to do now is render the image (my model) from 3dsmax with the correct measures so that I can print a template for cutting the wood.
there is no button for a sim race-track you would need to model it from a tutorial if you can find that kind of tutorial out there, you could find a lot of tutorials on how to make a car race-track. or do you want to create a button that you can insert into max and just click it? i think shawn @lightcube will need to help you at this in 3ds max maxscript but you would need to know the maxscript language
that is what i first thought as a 3d program you just press a button and 3ds max just automatically modeled the thing for you, without putting any effort into my searches or reading book or reading tutorials.
I don't know if you are familiar with SimRacing, but in SimRacing there are boxes called "Button Boxes" (like the name say's) have buttons that are used to assign some functions of the car so that in the race you can change them, like the real race cars have. For example, turn on or turn off the lights.
I thought you were talking about the game itself there was a game called sim racing i gave you the video to how to use real world measurements from turbosquid, he explanings how to use the real world measurements if you watched it
If I am understanding you correctly, I think you want a free little script called DiMaster 2 by the infamous Bobo. Can you check that out for me and let me know if that does what you need? Thanks!
Best Regards,
As I read this thread, even your idea of the script AJ seems to not address the need of the OP. The script will allow the OP to see what he's created, but he's not doubting that his model is correct to scale.
He is concerned that no matter what he modeled, once he renders and then plots a template, the end result may no longer be identical to the units he entered into max. I think he's looking for direction to zero out any errors introduced to the scaling.
My advice is to make sure you know the dots per inch that you'll be printing at. If you want to print to scale, you'll need to render with that in mind as well which can be tricky. To verify the lengths, you can still use the Bobo script and print the dimensions to check with a ruler after printing.
If your printer prints at say 200 DPI, then you'll need 200 pixels of render space per inch. Let's say the whole housing is 10 inches across, then you need 2000 pixels of printed area which will be impacted by the camera zoom/level. If you plan on printing to a 8.5 x 11 piece of paper, in pixels @ 200 dpi that would be 1700 x 2200 pixels. (You can use the print size wizard as well to work out the DPI.) If you have .5 inch margins around the edges of your paper, then you'd render at 1500 x 2000. Some printers can print to the edge of the page, so you can set 1700 x 2200 in that case. (Or use Print Actual Size or Scaling 100% in the print properties out of the printing application.)
4) Go to your top viewport and zoom in until the edges of your plane fill the frame perfectly. Or, if you prefer a camera, use a camera rotated exactly 90 degrees downward and a very low FOV. (like, .1)
5) Render and print. Check the DIMaster measurement against a ruler to ensure they are the right size. If not, zoom as needed, renderer and re-print. If you know you are going to do this a lot, save that scene for use with future objects.
I set a breakpoint here and went back in the stack trace to OpenGLContext.cpp -> renderFrame() and I saw that the MessageManager::Lock, mmLock local variable had its member lockWasSuccessful set to false, meaning that the OpenGL thread is not holding a Message Thread lock when accessing Component data. The Component data could simultaneously be modified by the MessageThread, causing a race condition.
In the past, it was my understanding that the OpenGL thread always holds a MessageManager::Lock in the renderOpenGL() callback. But, this is not always true. The OpenGL thread only holds a MessageManager::Lock when the associated OpenGLContext is attached to render juce::Components, not purely GL code, and any of those Components are marked to be redrawn by the GL thread. If no Components need to be redrawn, and there is other rendering being done by the GL thread in a renderOpenGL() callback, then the GL thread will not be holding a MessageManager::Lock.
I am not sure why this particular code is guarded by the lock while many Graphics calls above, for an Image, are not guarded. (I am not entirely sure which JUCE methods/objects are unsafe to access on a thread other than the Message Thread.)
besides of this, I would suggest that the gl-context should create cached versions of getWidth()/Height() which can be safefly accesd from the gl-callback because they are fundamentally useful.
Its really important that the GL-Thread can run as independent as possible.
In the program I am writing, one of my OpenGLRenderers uses CachedValues to set various OpenGL Uniforms in the renderOpenGL() callback. I understand that CachedValues are Message Thread specific objects since they receive synchronous value updates from the Message Thread.
So, I gather from the first commit that anyone who is writing custom OpenGL code using OpenGLRenderer cannot assume automatic thread safety between the Message Thread and the GL Thread (or pool). Thread safety between these threads is not managed for the user by JUCE.
If my understanding is correct, maybe the documentation for OpenGLRenderer should be updated to more strongly reflect this. At the moment, the docs make it sound like if you attach your OpenGLContext to a Component and register your OpenGLRenderer, then your renderer callbacks are thread-safe because the MessageManager will be locked. But from what I understand, any use of OpenGLRenderer will need to handle its own thread-safety with the Message Thread, even if it is attached to a component (as demonstrated in my original post with the OpenGLDemo).
When checking the docs on develop, I came across that new warning you refer to: not to use MessageManagerLock in the renderOpenGL() callback. I assume this is why you removed the MessageManagerLock from the OpenGLDemo in your commit. That is very handy to know.
So, if a developer were using a custom OpenGLRenderer with setContinuousRepainting as true, they would need to handle thread safety themselves. When handling safety with the Message Thread, they would not be able to use MessageManagerLock, but could use a other safety solutions.
In the JUCE GL app I am working on at the moment, I am accessing CachedValues in renderOpenGL(). I believe these CachedValues get updated synchronously on the Message Thread via a ValueTree. So my access of these CachedValues in renderOpenGL() is a race condition because the Message Thread may update the value while the GL thread reads the value.
To remedy this, I could use a bunch of std::atomics instead of CachedValues, and then manually set the atomics in a ValueTree::Listener callback. Alternatively, I could use a mutex to lock access to these pieces of data when they are accessed or written to in the ValueTree::Listener callback. Further, I could create some kind of wrapper class that obfuscates these approaches but essentially does the same stuff.
You could also use lock-free strucutres such as queues (i.e. produce updates on the main thread, add them to the queue, and then read the updates inside the render callback). Using a mutex or an atomic will probably be simplest, though.
This function is useful when you need to execute house-keeping tasks such as allocating, deallocating textures or framebuffers. As such, the functor will execute without locking the message thread. Therefore, it is not intended for any drawing commands or GUI code. Any GUI code should be executed in the OpenGLRenderer::renderOpenGL callback instead.
From what I have learned in this thread, GUI code should NOT be executed in OpenGLRenderer::renderOpenGL() as this could cause data races between the GL thread and the JUCE Message Thread, unless setContinuousRepainting is false.
On latest JUCE develop (past 6.1.2), I am still getting MacOS thread sanitizer warnings when using OpenGL in the JUCE DemoRunner. I have never actually been able to use OpenGL with JUCE without getting some thread sanitizer warnings, so this is not unexpected, and it may not actually be anything to worry about. But, after your previous post, @reuk, I thought maybe all thread sanitizer warnings with OpenGL in JUCE might have been resolved.
I get 5 thread sanitizer warnings in the JUCE DemoRunner the first time I access any GL related demo or if I go to Settings and set the Renderer to OpenGL Renderer. This spurt of warnings seems to only occur the first time GL is used during the lifetime of the app.
Reading this thread with great interest. I also have a Component implementing OpenGLRenderer, and it is updating some uniform variables used by the openGl renderer method in a custom-made parameterCallback class
I do sometimes get small audio dropouts when I am wildly changing GUI sliders which are attached to the AudioParameterFloats which in turn set the openGl uniform variables and I wonder if it has to do with this race-condition (if there is one - I think the atomic fixes it) ?
I am trying to understand this (I am still not super familliar with multithreading concepts). So you think that the audio dropouts are due to the fact that the audio-thread is pushing the changes and basically setting the atomic values used in the audioParameters and then since they are atomic they internally use a lock, and so when the openGL context uses it it locks it and when this happens the audio-thread is being blocked?
So basically I should have a mechanism in the openGLrenderer method that makes sure that the parameter value is currently not being set by the audio-thread. But when this is the case, it can ignore and simply not set the uniform variable (it is ok if the opengl renderer skips one or a few frames and uses the previous value). I think I did this kind of thing before with a TryLock. Should I use this? Or with a flag? Is there an example somehwere with a flag? Does the flag need to be atomic aswell?
c80f0f1006