Ok, I have finally figured it out. Here is what I believe to be the minimal code necessary to create a simple, flat, red, triangle. Explanations follow.
CreateTriangle.prototype.initialize = function() {
// Create Mesh
var mesh = pc.createMesh(this.app.graphicsDevice, [0,0,0,0,0,5,5,0,0], {
normals: [0,1,0,0,1,0,0,1,0],
uvs: [0,0,0,1,1,0]
});
// Create Material and set diffuse color to red
var material = new pc.StandardMaterial();
material.diffuse.set(1, 0, 0);
// Create mesh instance
var node = new pc.GraphNode();
var meshInstance = new pc.MeshInstance(node, mesh, material);
// Create model
var model = new pc.Model();
model.meshInstances.push(meshInstance);
// Create entity
var entity = new pc.Entity();
// Add a new Model Component to the entity
entity.addComponent("model", {
model: model
});
// Add Entity to the scene hierarchy
this.app.root.addChild(entity);
};
How did I figure this out?
At first, I thought the problem was with the material. To test my theory, I replaced pc.createMesh
with pc.createPlane
. I figured a plane was the closest thing to what I was trying to create and I knew there wouldn’t be any trouble with the mesh since it was being created behind the scenes by PlayCanvas. Lo and behold, a red plane appeared on screen. Conclusion: the material was fine, the problem was with the way I created the mesh. But what was I doing wrong?
I decided to take a look at the engine source code for pc.createPlane
, to see how it was using pc.createMesh
. That’s where I realized that it was passing more than just vertex positions, but it was also passing normals, uvs, uvs1, indices and tangents. I figured that this might be the problem with my mesh; I was only passing vertex positions. So I started by passing normals. Still nothing on screen. Then I added uvs… Bingo, my red triangle appeared. uvs1, indices and tangents were not necessary.
I think that the pc.createMesh(device, positions, opts)
documentation could be improved. Right now it says that the third argument, opts
, is “An object that specifies optional inputs for the function”. In my mind, optional means not necessary, not compulsory. In practice, though, if you don’t pass normals and uvs to the function, your mesh won’t work. Unless I’m wrong about this, the documentation should probably be updated to reflect this reality.