2
votes

I have the ascii ply file loading fine now, but it has a texture and I can not seem to get it to load not matter how I configure things.

    cameraMain = new THREE.Camera(8, MainWidth / MainHeight, 1, 10000);
sceneMain = new THREE.Scene();
ambientLightMain = new THREE.AmbientLight(0x202020);
directionalLightMainRight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLightMainLeft = new THREE.DirectionalLight(0xffffff, 0.5);
pointLightMain = new THREE.PointLight(0xffffff, 0.3);

directionalLightMainRight.position.x = dlpx;
directionalLightMainRight.position.y = dlpy;
directionalLightMainRight.position.z = dlpz;
directionalLightMainRight.position.normalize();

directionalLightMainLeft.position.x = -dlpx;
directionalLightMainLeft.position.y = dlpy;
directionalLightMainLeft.position.z = dlpz;
directionalLightMainLeft.position.normalize();  

pointLightMain.position.x = plpx;
pointLightMain.position.y = plpy;
pointLightMain.position.z = plpz;

sceneMain.addLight(ambientLightMain);
sceneMain.addLight(directionalLightMainRight);
sceneMain.addLight(directionalLightMainLeft);
sceneMain.addLight(pointLightMain);

rendererMain = new THREE.WebGLRenderer();
texture = THREE.ImageUtils.loadTexture('3D/'+ mainURL +'.jpg', {}, function() {
    rendererMain.render(sceneMain);
});

rendererMain.domElement.style.backgroundColor = backgroundColor;
rendererMain.setSize(MainWidth, MainHeight);
rendererMain.domElement.addEventListener('DOMMouseScroll', onRendererMainScroll, false);
rendererMain.domElement.addEventListener('mousewheel', onRendererMainScroll, false);
rendererMain.domElement.addEventListener('dblclick', onRendererMainDblClick, false);
rendererMain.domElement.addEventListener('mousedown', onRendererMainMouseDown, false);

$("#viewerMain").append(rendererMain.domElement);

window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mouseup', onMouseUp, false);

That chunk of code initializes the model. Some of it is not needed for question purposes, it has code for zooming, rotating, etc. I know there is another line, I have it commented out but for some reason it wont show here so I will do it separately.

material = new THREE.MeshBasicMaterial({map: texture});

That line is after the loadTexture code.

The rest of it is loaded with a loadPly function

        var geometryMain = new THREE.Geometry();
    for (i in event.data.content[0])
      geometryMain.vertices.push(new THREE.Vertex(new THREE.Vector3(event.data.content[0][i][0], event.data.content[0][i][1], event.data.content[0][i][2])));
    for (i in event.data.content[1])
      geometryMain.faces.push(new THREE.Face3(event.data.content[1][i][0], event.data.content[1][i][1], event.data.content[1][i][2]));
    geometryMain.computeCentroids();
    geometryMain.computeFaceNormals();
    mainModel = new THREE.Mesh(geometryMain, new THREE.MeshLambertMaterial({color:0xffffff, shading:THREE.FlatShading}));
    sceneMain.addObject(mainModel);
    mainModel.overdraw = true;
    mainModel.doubleSided = true;

I have tried tweaking the THREE.mesh() section to include the material but it breaks everything. I have tried just adding the map:material to the MeshLambertMaterial, also a no go. Anyone have any insight? Sorry if this is over complicated but i am far from knowing this enough to be efficient yet.

If I add

map:THREE.ImageUtils.loadTexture('3D/'+ mainURL +'.jpg')

to the THREE.Mesh() line, I get

.WebGLRenderingContext: GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 2

2

2 Answers

3
votes

In order to display a texture on an object, it needs texture coordinates. You only seem to add vertices and faces to the geometry. Looking at THREE.PLYLoader sources, it doesn't seem to support loading the texture coords. (Although I'm not sure if you use that loader as it should already return a ready Geometry instance instead of requiring you to construct arrays manually)

1
votes

Use THREE.MeshNormalMaterial. It shows texture when you use MeshNormalMaterial.