05-26-2024 08:19 AM
This weekend I was so excited when I saw this js code:
for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a
(It is originally from City In A Bottle – A 256 Byte Raycasting System)
So, I spent some time today to recreate it in LabVIEW:
Because such ray tracing with relatively few operations looks like magic to me:
There may be some kinds of Rube Goldberg Code here, but it works at least. By the way, JavaScript is slightly different from the C Programming Language in terms of Operator Precedence and also logical operators' behaviors. Most of the time was spent converting this piece of code from JS to C (I learned some new old things, and I can recommend this exercise for everyone). Once it was successfully executed in C, it was more or less trivial to port it to LabVIEW. Sorry for the slightly messy diagram; I would like to see the whole thing on the same BD snipet without SubVIs. Feel free to modify or improve it, of course. Enjoy!
05-26-2024 01:23 PM
@Andrey_Dmitriev wrote:
Feel free to modify or improve it, of course. Enjoy!
Very nice!
What immediately comes to mind of course is that all controls belong outside the FOR loop stack. It is more effort if the compiler must assume that they can change midstream instead of allowing constant folding for the duration of the loop stack. It also makes the code cleaner to read if all control terminal are in one location instead of scattered all over the diagram.
I wasn't aware that bitwise operations on DBL coerce to I32. Seems somewhat random.... 😄
05-28-2024 10:31 AM
That ... is awesome!
05-28-2024 11:46 AM
Yeah that is pretty cool. Sometimes intense math stuff like this blows my mind. Early video game developers, and demo scene people are wizards with this type of stuff.
Unofficial Forum Rules and Guidelines
Get going with G! - LabVIEW Wiki.
17 Part Blog on Automotive CAN bus. - Hooovahh - LabVIEW Overlord
05-28-2024 12:32 PM
@Hooovahh wrote:
Early video game developers, and demo scene people are wizards with this type of stuff.
Imagine having to program a (pseudo) 3D racing game on an 8bit 3.58Mhz processor with 8kB RAM, but they did it (example).
Then there is a full chess game that was running on a 4bit processor with 80bytes (No, not kbytes!) of RAM. (see my old post here)
We are totally spoiled! Of course my first LabVIEW program to control a spectrometer was running on a 100Mhz Pentium 1 and I never had performance problems. 😄
05-29-2024 09:07 AM
@Hooovahh wrote:
and demo scene people are wizards with this type of stuff.
Thanks! I did a few of those (at age 12 😎)...
05-31-2024 07:21 PM
Went full circle and ported the LabVIEW implementation to G Web Development Software to run in a browser 😋. See the demo page!
Used LabVIEW NXG's import from LabVIEW feature to create an NXG project, converted it to an NXG Web Module target, and then imported the NXG project to G Web so diagram was ruffled up quite a bit. It really is only useful for simple projects like this. Probably would have been quicker to rewrite by hand 😅.
Doesn't run particularly fast but G Web isn't really targeted for fast numerical processing. G Web is better suited to UI interactions and talking to backends doing any serious number crunching (or using the JSLI to call into JS for doing lots of data processing). Anyway, cool project! Was fun to play with 🙂.
06-05-2024 10:10 AM
kudos to you!
reminds me of "Creating music in one line of C code" - or caustics's 8 bit synthesizer
06-05-2024 11:45 AM
I have the nagging feeling that the entire thing could be done entirely in blue (no orange wires!), but I have not tried.
06-05-2024 11:51 AM - edited 06-05-2024 11:52 AM
@altenbach wrote:
I have the nagging feeling that the entire thing could be done entirely in blue (no orange wires!), but I have not tried.
I don't think so (at least not 1:1), because a and b (X and Y increments) are fractional. But you can try.
At the beginning everything was looks pretty simple, but I spend much more time that was initially expected.
Anyway, functionally equivalent C code is below, may be will be helpful for you if you will give a try:
bool isThereAnythingAt(double X, double Y, int Z)
{ // The random building height comes from (X^Z)*8.
int temp1 = (int)(X / BUILDING_WIDTH) ^ (Z / BUILDING_DEPTH);
int temp2 = (CITY_DISTANCE < Z) & (AVENUE_WIDTH < fmod(X, (double)AVENUE_PERIOD));
int temp3 = temp2 ? temp1 : 0;
int Hit = GROUND_PLANE - (temp3 * % (BUILDING_HEIGHT + 1);
return (Y >= Hit);
}
void verboseDraw(int t, float* data) {
const int w = 99;
for (int i = 6000; i--;) { // World space coordinates.
double X = t;
double Y = 1;
int Z; // Ray direction in world space.
double a = i % w / 50.0 - 1.0;
double b = 1.0 - (double)i / 4000;
double d = 1; // Light.
double s = b; // Background
for (Z = 2; Z < w; ++Z) { // Ray tracing!
if (isThereAnythingAt(X, Y, Z)) { // We hit the model, ray tracing toward the light.
double last_d = d;
s = ((int)X & (int)Y & Z) % 3; // The texture.
s /= (double)Z; // Fog.
a = b = 1; // New direction, toward the light.
d = (double)Z / w;
if (last_d < 1) break; // Effectively the same as the ||d|(...) part.
}
X += a;
Y -= b;
}
double darkness = d * Z / w - s; // Texture + lighting.
data[i] = (float)darkness;
}
}