Skip to content

Commit

Permalink
Changes to picking example to show how to get
Browse files Browse the repository at this point in the history
the surface normal for the spot picked.

Apparently no screenshots are taken for picking
so no deps files need up be updated

Review URL: http://codereview.chromium.org/159442

git-svn-id: http://src.chromium.org/svn/trunk/src/o3d/samples/o3djs@21805 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
  • Loading branch information
[email protected] committed Jul 28, 2009
1 parent c4162e1 commit c5fc2e2
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 14 deletions.
68 changes: 68 additions & 0 deletions element.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,72 @@ o3djs.element.duplicateElement = function(pack, sourceElement) {
return newElement;
};

/**
* Gets the normal for specific triangle in a Primitive in that Primitive's
* local space.
*
* NOTE: THIS FUNCTION IS SLOW! If you want to do collisions you should use a
* different solution.
*
* @param {!o3d.Primitive} primitive Primitive to get normal from. The
* primitive MUST be a TRIANGLELIST or a TRIANGLESTRIP and it must have a
* POSITION,0 stream.
* @param {number} index Index of triangle.
* @param {boolean} opt_winding The winding of the triangles of the
* Primitive. False = Clockwise, True = Counterclockwise. The default is
* false. This is only used for Primitives that have no normals.
* @return {!o3djs.math.Vector3} The normal for the triangle.
*/
o3djs.element.getNormalForTriangle = function(primitive, index, opt_winding) {
// Check that we can do this
var primitiveType = primitive.primitiveType;
if (primitiveType != o3djs.base.o3d.Primitive.TRIANGLELIST &&
primitiveType != o3djs.base.o3d.Primitive.TRIANGLESTRIP) {
throw 'primitive is not a TRIANGLELIST or TRIANGLESTRIP';
}

var indexBuffer = primitive.indexBuffer;
var vertexIndex = (primitiveType == o3djs.base.o3d.Primitive.TRIANGLELIST) ?
(index * 3) : (index + 2);
var vertexIndices;
if (indexBuffer) {
var indexField = indexBuffer.fields[0];
vertexIndices = indexField.getAt(vertexIndex, 3);
} else {
vertexIndices = [vertexIndex, vertexIndex + 1, vertexIndex + 2]
}

var normalStream = primitive.streamBank.getVertexStream(
o3djs.base.o3d.Stream.NORMAL, 0);
if (normalStream) {
var normalField = normalStream.field;
// Look up the 3 normals that make the triangle.
var summedNormal = [0, 0, 0];
for (var ii = 0; ii < 3; ++ii) {
var normal = normalField.getAt(vertexIndices[ii], 1);
summedNormal = o3djs.math.addVector(summedNormal, normal);
}
return o3djs.math.normalize(summedNormal);
} else {
var positionStream = primitive.streamBank.getVertexStream(
o3djs.base.o3d.Stream.POSITION, 0);
if (!positionStream) {
throw 'no POSITION,0 stream in primitive';
}
var positionField = positionStream.field;
// Lookup the 3 positions that make the triangle.
var positions = [];
for (var ii = 0; ii < 3; ++ii) {
positions[ii] = positionField.getAt(vertexIndices[ii], 1);
}

// Compute a face normal from the positions.
var v0 = o3djs.math.normalize(o3djs.math.subVector(positions[1],
positions[0]));
var v1 = o3djs.math.normalize(o3djs.math.subVector(positions[2],
positions[1]));
return opt_winding ? o3djs.math.cross(v1, v0) : o3djs.math.cross(v0, v1);
}
};


38 changes: 24 additions & 14 deletions picking.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,20 @@ o3djs.picking.Ray = goog.typedef;

/**
* Creates a new PickInfo.
* @param {!o3djs.picking.ShapeInfo} shapeInfo The ShapeInfo that
* was picked.
* @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Information
* about the pick.
* @param {!o3djs.math.Vector3} worldIntersectionPosition
* world position of intersection.
* @param {!o3d.Element} element The Element that was picked.
* @param {!o3djs.picking.ShapeInfo} shapeInfo The ShapeInfo that was picked.
* @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Information about the
* pick.
* @param {!o3djs.math.Vector3} worldIntersectionPosition world position of
* intersection.
* @return {!o3djs.picking.PickInfo} The new PickInfo.
*/
o3djs.picking.createPickInfo = function(shapeInfo,
o3djs.picking.createPickInfo = function(element,
shapeInfo,
rayIntersectionInfo,
worldIntersectionPosition) {
return new o3djs.picking.PickInfo(shapeInfo,
return new o3djs.picking.PickInfo(element,
shapeInfo,
rayIntersectionInfo,
worldIntersectionPosition);
};
Expand Down Expand Up @@ -219,16 +221,23 @@ o3djs.picking.dumpRayIntersectionInfo = function(label,
/**
* Creates a new PickInfo. Used to return picking information.
* @constructor
* @param {!o3djs.picking.ShapeInfo} shapeInfo The ShapeInfo that
* was picked.
* @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Information
* about the pick.
* @param {!o3d.Element} element The Element that was picked.
* @param {!o3djs.picking.ShapeInfo} shapeInfo The ShapeInfo that was picked.
* @param {!o3d.RayIntersectionInfo} rayIntersectionInfo Information about the
* pick.
* @param {!o3djs.math.Vector3} worldIntersectionPosition world position of
* intersection.
*/
o3djs.picking.PickInfo = function(shapeInfo,
o3djs.picking.PickInfo = function(element,
shapeInfo,
rayIntersectionInfo,
worldIntersectionPosition) {
/**
* The Element that was picked (Primitive).
* @type {!o3d.Element}
*/
this.element = element;

/**
* The ShapeInfo that was picked.
* @type {!o3djs.picking.ShapeInfo}
Expand Down Expand Up @@ -335,7 +344,8 @@ o3djs.picking.ShapeInfo.prototype.pick = function(worldRay) {
if (rayIntersectionInfo.intersected) {
var worldIntersectionPosition = o3djs.math.matrix4.transformPoint(
worldMatrix, rayIntersectionInfo.position);
return o3djs.picking.createPickInfo(this,
return o3djs.picking.createPickInfo(element,
this,
rayIntersectionInfo,
worldIntersectionPosition);
}
Expand Down

0 comments on commit c5fc2e2

Please sign in to comment.