Craft 3D

Something I realized not too long ago. Craft 3D isn’t real 3D. When you look at a Craft 3D object, what you see looks like a 3D object, rotates like a 3D object, and acts like a 3D object for physics. When you look at a 3D object, what you see is actually just the skin part of the 3D object that’s facing you. Here’s an example of what I’m pointing out. When you run the code, you see a cube. As you use your finger to rotate the cube, you’ll see a green sphere on the other side. Everything looks fine and in 3D. Restart the code and slowly zoom in on the cube using the two finger spread. Once you pierce the skin of the cube, you’ll see a red sphere inside and the green sphere. The cube is gone. You don’t see what should be the far side of the cube. If you slowly keep zooming in on the red sphere, eventually you will poke a small hole in the skin of the red sphere and you will see the green sphere through it. So once you pass through the skin of the 3D object, you don’t see what should be the other side. Under normal conditions none of this really matters. You won’t realize that you don’t see the 3D object anymore. But there might be some conditions where it might be a problem and I just want to point this out.

displayMode(FULLSCREEN)

function setup()
    assert(craft, "Please include Craft as a dependency")
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()
    skyMaterial=scene.sky.material
    skyMaterial.sky=color(0)
    skyMaterial.horizon=color(0)
    scene.sun.rotation=quat.eulerAngles(20,45,-30)
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 30, -30, 300)
    createSphere(0,0,0,.2,255,0,0)
    createSphere(0,0,14,2,0,255,0)
    createCube()
end

function createSphere(x,y,z,s,r,g,b)
    sphere1=scene:entity()
    s1=sphere1:add(craft.rigidbody,STATIC)
    sphere1.position=vec3(x,y,z)
    sphere1:add(craft.shape.sphere,s)
    sphere1.model = craft.model.icosphere(s,3)
    sphere1.material = craft.material("Materials:Specular")
    sphere1.material.diffuse=color(r,g,b)
end

function createCube()
    ww=scene:entity()
    w=ww:add(craft.rigidbody,STATIC)
    w.restitution=1
    ww.position=vec3(0,0,0)
    ww:add(craft.shape.box,vec3(7,7,7))
    ww.model = craft.model.cube(vec3(7,7,7))
    ww.material = craft.material("Materials:Standard")
    ww.material.map = readImage("Blocks:Brick Red")
    ww.material.blendMode = NORMAL
end

function draw()
    update(DeltaTime)
    scene:draw()	
    text("Slide your finger to rotate image",WIDTH/2,HEIGHT-25)
end

function update(dt)
    scene:update(dt)
end

When the normal of a triangle is pointing away from the camera then the assumption is that the face is on the back face and so it isn’t displayed. Under normal circumstances then any back-facing parts of the mesh will be occluded by a front-facing part so this is a reasonable assumption.

If you want to be “inside” a shape then you need to invert the normals. My PseudoMesh class can do that for you if creating a model from a mesh.

@LoopSpace I was just surprised when I ran across this the first time. I was thinking that if Craft created a 3D object and I went inside, it would look like I was inside. I wasn’t expecting the object to disappear. Like I said above, under normal conditions it doesn’t matter.

@dave1707 , @LoopSpace - seen this as well, good demonstration of effect. Doesn’t occur with a mesh sphere. 3D on a 2D screen is always extrapolation of the camera view.

It could be down to maximising drawing speed by eliminating the hidden features and not drawing all features from the back to the front. Depending on the algorithm used, a compromise of speed versus detail.

On the Pseudomesh front, @John must have used a similar technique for the skybox effect. The system needs to recognise that it moves from outside an object to the inside of one an make adjustments to the normals. Also if external light sources are used you should just end up in the dark anyway.

Hey guys. What you are seeing is an example of Backface Culling which is used to prevent normally unseen triangles from being rendered. It isn’t based on triangle normals but rather winding order (which can be clockwise or anti-clockwise).

There are cases where you want double-sided materials. At the moment craft doesn’t support this but I could easily add some options to materials for this (i.e. material.doubleSided). For now you can use @LoopSpace’s PseudoMesh class. An easy way for it to work without checking if you are inside is just create two meshes with one inverted so it’s always visible. Another trick is to simply scale the object by -1,-1,-1 but the normals might be incorrect.

@John Thanks for the info and the link Backface Culling to a lot more info to read about. I probably won’t be doing anything where I need to see the inside of an object, I just wanted to point out what I ran into as info for others.