ARCore Cupcakes #2 — Render 3D objects at Runtime using Sceneform

Upgrade yourself form AndroidDev to ARCoreDev

Hari Vignesh Jayapalan
ProAndroidDev

--

image credits — me :-P

ARCore Cupcakes is a blog series, intended to showcase quick hacks, pro-tips and concepts on ARCore and Sceneform development for Android Developers. The goal of this series is to provide necessary support for AndroidDevs to upgrade themselves to ARCoreDevs.

If you’re an AndroidDev, trying to become an ARCoreDev, start from the series below, which covers basic ARCore and Sceneform fundamentals.

Previous Episode — #1

Episode #2 — Render 3D objects at Runtime using Sceneform

Sceneform allows us to create 3D models dynamically on the fly, supporting few basic shapes like sphere, cylinder and cube.

Note: I’m writing this post when Sceneform 1.4.0 was released, if you witness any change in the shapes API, comment below or send me a private note for updating the content.

Use-cases

Just if an API has such capability, we always need a right use-case for us to use. In this case, we can reduce the size of the app, by not importing the models but to just use them on the fly.

Many small use-case 3D models like a ball or table can be easily constructed using a flat cuboid with few cylinders. This will save us a lot of space.

I agree that we need to write more code, but it’s really not that more. Sceneform APIs have provided it to us beautifully.

How is this achieved?

ShapeFactory and MaterialFactory classes will allow us to create renderable objects from simple shapes and materials. We can also provide our own materials or textures for it.

Enough talk! Let’s code!

We’re going to run an experiment with few shapes, materials and textures to create 3D models. Just like the image below.

That’s our end result

Step 1: Create ArFragment

To show our 3D model, let’s add our ArFragment within our XML file

Step 2: Initialising ArFragment

We need to initialise the ArFragment from our Activity file, so that Sceneform manages our runtime permissions, user prompt, detecting feature points, concurrent odometric mapping (COM) and rendering a virtual plane.

If you’re not aware of these concepts, refer to my talk below or skim through the article mentioned in the beginning of this article.

Note : Make sure you add the necessary permissions for camera and ARCore metadata in your manifest file.

Step 3: Adding Tap listener for detected planes

Since our Sceneform fragment leaves us after detecting planes, we need to place the object on tap of the screen (to be accurate, a tap on the detected plane)

Let’s add our tap listener

fragment.setOnTapArPlaneListener { hitResult, plane, motionEvent -> // write instructions here
}

Step 4: Creating 3D objects

Now we need to render the objects and place them on the tapped region — to be exact, we need to create an Anchor on the position returned by the HitTest and then place the object there.

Creating Sphere

We just need to pass on the Color and the hitResult object from our tap listener to this method — then Sceneform creates us a sphere of

  • Radius of size — 0.1f
  • Position — x: 0f, y: 0.15f, z: 0f
creating a sphere

Walkthrough

  • We’re using MaterialFactory to manufacture a material for us in the given color — here Color.BLUE for example.
  • This material will be rendered in the background thread and it will arrive at the method thenAccept.
  • We then use ShapeFactory to render us our required shape, here — Sphere.
  • We construct the Sphere of radius 0.1f and assign a position via Vector3(x, y, z)
  • After creating this shape model, we wrap our rendered material on top.

This is the same for all other shapes.

Creating Cylinder

We create cylinder using makeCylinder method, which takes radius, height, position and material as the parameters.

a green cylinder

Creating Cube

We create cube using makeCube method, which takes size, position and material as the parameters.

a red cube

Step 5: Adding Textures

Now let’s add a texture instead of colors. Texture is nothing but an image along with some properties, which will wrap around the 3D model.

To keep things simple, I’m using an image of a sun and try to create a ball of fire. Download the image below and add it to your drawable folder.

To add this as texture, We’re going to use our Texture builder. Texture builder accepts Bitmap, so we convert our image to bitmap and send it to our builder. Our builder, gives us the texture, rendered in the background thread.

Then we pass this texture, to our MaterialFactory class in place of color.

Last but not the least, addNodeToScene method — not doing any fancy work, just creating a node at anchor, assigning renderable and adding it to the ArScene. I’m assuming that you know this already, if not please refer the resources mentioned in the beginning.

TL;DR

  • Sceneform allows us to render 3D objects dynamically
  • Currently, supported objects are square, cube and cylinder (hope they release custom polygons)
  • We can construct objects and provide color or texture to them
  • This is achieved using ShapeFactory and MaterialFactory classes
  • This can be used for very basic objects, hence saving our app from getting bloated

Project

See you soon in another episode!

Follow me on Twitter, Facebook or LinkedIn, will post an update when I write the post.

Thank you for spending your precious time in reading this article. Loved it? Clap your 👏 to say “thanks!” and help others find this article.

--

--

Android Dev at WeTransfer| ex Backbase | #1 Google AAD | Public Speaker | Blogger | Creative Coder & Logical Designer