Codea Craft - 4
I believe I mentioned last time that I have been wondering how to build and import objects like the robot that I’ve been playing with. I had supposed that one way would be to build them in a program like Blender or 3DSMax (however you capitalize that), and then save them in a format Codea understands, do some magic, and there the object would be.
As always, though, I keep thinking that my art would be better if only I had a better pencil, so I looked for a new pencil for 3D objects. I found an article using Google, something about 3D, iPad, 2019, that said that an app named uMake was marvelous. So I downloaded it yesterday and tried it out. The bad news is that it has a subscription model, ranging from about $16 a month down to about $10, depending on how long you sign up for. The good news[1] is that in the scheme of things, $16 isn’t much, and the good news[2] is that it’s really a nice program, quite powerful for the iPad. Good news[3] is that their tutorials and support are very good, for any platform.1
Basically, in uMake, you have a nice 3D world, with quick alignment to the x, y, or z planes. There’s also the ability to align to special planes relating to your object, but I’m not there yet. Anyway, you draw curves with your pen, and, depending on the tool you use, they are NURBS curves with editable handles, or they are smart enough to automatically be straight or round, or they’re just sketch lines. You can draw two curves, and if they intersect at the end points, they form a closed curve and uMake will fill that with a surface. You can draw two curves side by side, and loft a surface between them. And lots more. It’s quite an impressive program. I wish them great success and will continue my subscription even though I’ll probably not make too many 3D things. Or, who knows, maybe I will.
Anyway, as soon as it was downloaded and I had watched six or eight short tutorial videos, I made an object that looks like this:
I saved that out as a .obj
file, and in Codea, did this:
function setup()
-- Create a new craft scene
scene = craft.scene()
scene.sky.active = false
createGround(-1.125)
-- Create a new entity
myEntity = scene:entity()
-- Set its model for drawing
myEntity.model = craft.model("Documents:Untitled")
-- Adjust position and scale
myEntity.y = -1
myEntity.z = 0
myEntity.scale = vec3(1,1,1) / 8
ronEntity = scene:entity()
ronEntity.model = craft.model("CastleKit:shieldRed")
ronEntity.parent = myEntity -- shield vanishes if this is uncommented
table.insert(myEntity.children, ronEntity)
ronEntity.x = 0
ronEntity.y = 8
ronEntity.z = 2
ronEntity.eulerAngles = vec3(0,180, 0)
ronEntity.scale = vec3(1,1,1) * 2
-- Move camera back a little
scene.camera.z = -4
parameter.number("Rotate", 0, 360, 180)
end
Basically just changed the model from the robot link to the saved .obj
file. And in comes the object:
So that’s nearly good! I have learned at least one simple flow for getting that external thing in there. It does seem to have a problem. Looking at the concave part of the top, it appears to me that there are no faces there. I believe that to be a problem in uMake, that has caused it to “invert normals” on those faces. They have already let me know that they are working on a known problem like that, and I sent them my file as an example to check. Like I said, great support.
I’ve also had some hints from the Codea forum, so let’s push forward here a bit. I’ll resize this thing to be larger, and try to paint it:
-- Set its model for drawing
myEntity.model = craft.model("Documents:Untitled")
myEntity.material = craft.material("Materials:Specular")
myEntity.material.diffuse = color(155,187,222,255)
myEntity.material.map = readImage("Surfaces:Basic Bricks AO")
-- Adjust position and scale
myEntity.y = -3
myEntity.z = 0
myEntity.scale = vec3(1,1,1) / 2
And we get this:
You’ll notice that I fiddled with the positioning and camera view a bit. Still more to learn there, and I think going forward in this kind of sketching mode, I’ll move to the use of the orbit camera that we’ve seen before, rather than this flat one. It’ll make it easier to figure out what I’m doing.
So there’s plenty left to learn, about how to texture things, whether we can access the faces of this object, whether we can color it at all inside uMake, and so on. We’ve just sort of tossed a rope across the ravine where we need a bridge, but the rope seems fairly firmly tied on the other side, and, so far at least, we haven’t encountered anything to make me think moving to 3D is impossible if my product owner (me) wants it (and he does). So that’s what we did yesterday. Let me make some general comments, and we’ll see you next time.
The Point
As I’ve alluded to before, these little “Programming in Public” exercises have a few purposes. Mostly, they entertain me. I do enjoy sharing what happens as I go along, although writing these articles contemporaneously is kind of a pain. I’m interested in exploring incremental development and its implications. There are many aspects to that but two that come to mind right now are:
- Can we come up with a “good” design while working incrementally? Some people fear that without up front design, we’re doomed to have a bad design. Now, I think people should do as much design ahead of time as they wish, but I also think that our formal training and our past methods may lead us to do more up front design than is ideal. So I like to try to show, at least in these small exercises, that we can get good, clean sensible design, with good abstractions, working as we go.
- Can those “good” designs survive large requirements changes? Some people imagine that doing a lot of design up front equips us with a system that will be resilient to change. That may be so, although my long experience doing software, and helping others do software, and talking with people who do software, … all those things make me suspect that doing a lot of design up front really doesn’t protect us against change. I think it’s more about simple design. So I like to explore “surprise” changes, like the 3D one, and I hope you can tell by what’s gone on so far that I didn’t even have it in mind during most of what we’ve done so far.
I hope you’ll follow along and see what happens next. I’m excited to find out as well!
-
One-based indexing, because Lua uses one-based indexing. Go with the flow, that’s my motto. Well, not really but anyway, one-based. ↩