"3d" wireframe

I’ve done some experimentation, and it seems that it could be possible to draw a wireframe with a bunch of “3d” points being connected by lines. Idk really how your perspective texture code works @kwx , so I was just using colors to draw lines.

[flashing colors warning]
If it would be possible to output the positions of every sprite of one kind after they have been put into a “3d” space, and draw lines from their screen positions to their other screen positions, there could be, in theory, some convincing wireframe 3d(probably no collision because it would take a lot of math). The problem I’ve come across is that I only have the positions of the colors if they aren’t covered up. This means that there is a lot of flickering. I wonder if there was a way to fill an array every frame of the sprites’ ACTUAL positions on-screen “like array of screen pos x” and “array of screen pos y”. Also, if there was to be a wireframe in arcade, then it would probably be best to have it not render lines that are “past” other lines, so it would look more convincing (but it would require a lot of math too). You don’t have to reply, it was just an idea, because it would be REALLY cool to have something looking like full 3d even if it is impossible ro render textures to the wireframe, which, it most likely is, but idc that much, I just wanted to see if I could draw an environment. (also, as a side note, it reminds me a lot the virtual boy, which only displayed in red and could only render wireframes in 3d.)

1 Like

Ah, your current code is looking for dots of the right color in the content drawn on screen? That’s a rather roundabout way of doing wireframe graphics, and it flickers since the dots aren’t always visible due to rounding.

You can do this much more directly. Try this:

    let centerX = 28
    let centerY = 58
    // Calculate the screen position of the pyramid's top corner.
    let top = renderer.worldToScreen(centerX, centerY, 30)
    if (top[2] < -6) {
        // The pyramid is visible, it's on the front side of the screen and at least 6 units away.
        // Now calculate the screen positions for the bottom corners. 
        let p0 = renderer.worldToScreen(centerX - 5, centerY - 5, 15)
        let p1 = renderer.worldToScreen(centerX - 5, centerY + 5, 15)
        let p2 = renderer.worldToScreen(centerX + 5, centerY + 5, 15)
        let p3 = renderer.worldToScreen(centerX + 5, centerY - 5, 15)

        // Draw the bottom square
        mySprite.image.drawLine(p0[0], p0[1], p1[0], p1[1], 2)
        mySprite.image.drawLine(p1[0], p1[1], p2[0], p2[1], 2)
        mySprite.image.drawLine(p2[0], p2[1], p3[0], p3[1], 2)
        mySprite.image.drawLine(p3[0], p3[1], p0[0], p0[1], 2)

        // Draw the top edges of the pyramid, from each corner to the top
        mySprite.image.drawLine(p0[0], p0[1], top[0], top[1], 2)
        mySprite.image.drawLine(p1[0], p1[1], top[0], top[1], 2)
        mySprite.image.drawLine(p2[0], p2[1], top[0], top[1], 2)
        mySprite.image.drawLine(p3[0], p3[1], top[0], top[1], 2)
    }

Basically, the renderer.worldToScreen() function takes 3D coordinates as input. The input x and y values are in track coordinates corresponding to the x/y values in the track image. The input z value is the height above the track.

worldToScreen returns an array containing [screen_x, screen_y, z]. The first two values are directly usable as coordinates on the screen, and the third coordinate is the Z value for checking if an item is visible. (Negative Z is into the screen and visible, positive Z is behind the viewer and not visible.) So you need to add a check that the Z coordinate is in the right range before drawing it.

Does that help?

2 Likes

possible to have the points where it draws lines from in a 3d space, with a controlled height like sprites are? Currently, renderer.worldToScreen seems to only do points on the 2d plane (no height variable), or points on the top of the screen. I have a demo of how it would work in blocks, it just only draws points and not lines.

What do you mean? renderer.worldToScreen(x, y, h) takes three arguments, and the third one is the height above the ground plane. The example I posted earlier uses height 15 for the base of the pyramid, and height 30 for the top. Try tweaking those values to get different results. The current pyramid should appear to float above the ground, though that’s hard to see when the ground is a flat green area.

1 Like

Ok, I’m just dumb lol, sorry, I thought that value was color lol! I now know that one value is the color and you can now officially draw a wireframe in blocks! (no extension yet, but when it releases, it will probably be called “kiwiphoenix364/pxt-kwx-3d” or something (to credit you, also I will give credit in the description.))

I made a randomized terrain renderer with this (I know some of it doesn’t connect properly but I didn’t want to work out the math)

Also, on my pc (a couple of years old), it runs ~40-70fps. The chances of there being a point could be lessened for better performence, like this here:

(~90-120fps) on my computer