Skip to content

Commit

Permalink
Fixed normals/tangents generation in cylinder. Closes away3d#209
Browse files Browse the repository at this point in the history
Now properly respects the slope of the lateral surface,
meaning that cones will now get slanting normals instead
of normals that are parallel with the base plane. Also
fixes issue when radius = 0, which it will always be for
one segment in cones. This previously resulted in zero
normals, which is no longer the case.
  • Loading branch information
richardolsson committed Jul 12, 2012
1 parent 987ff38 commit b96e3dc
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/away3d/primitives/ConeGeometry.as
Expand Up @@ -31,7 +31,7 @@ package away3d.primitives
*/
public function ConeGeometry(radius : Number = 50, height : Number = 100, segmentsW : uint = 16, segmentsH : uint = 1, closed:Boolean = true, yUp : Boolean = true)
{
super(0.00001, radius, height, segmentsW, segmentsH, false, closed, yUp);
super(0, radius, height, segmentsW, segmentsH, false, closed, yUp);
}
}
}
27 changes: 20 additions & 7 deletions src/away3d/primitives/CylinderGeometry.as
Expand Up @@ -63,6 +63,7 @@ package away3d.primitives
{
var i:uint, j:uint;
var x:Number, y:Number, z:Number, radius:Number, revolutionAngle:Number;
var dr : Number, latNormElev : Number, latNormBase : Number;

// reset utility variables
_numVertices = 0;
Expand Down Expand Up @@ -104,7 +105,7 @@ package away3d.primitives
var revolutionAngleDelta:Number = 2 * Math.PI / _segmentsW;

// top
if (_topClosed) {
if (_topClosed && _topRadius > 0) {

z = -0.5 * _height;

Expand Down Expand Up @@ -132,7 +133,7 @@ package away3d.primitives
}

// bottom
if (_bottomClosed) {
if (_bottomClosed && _bottomRadius > 0) {

z = 0.5 * _height;

Expand All @@ -159,11 +160,21 @@ package away3d.primitives

_vertexIndexOffset = _nextVertexIndex;
}

// The normals on the lateral surface all have the same incline, i.e.
// the "elevation" component (Y or Z depending on yUp) is constant.
// Same principle goes for the "base" of these vectors, which will be
// calculated such that a vector [base,elev] will be a unit vector.
dr = (_bottomRadius - _topRadius);
latNormElev = dr / _height;
latNormBase = (latNormElev==0)? 1 : _height / dr;


// lateral surface
if(_surfaceClosed)
{
var a:uint, b:uint, c:uint, d:uint;
var na0 : Number, na1 : Number;

for(j = 0; j <= _segmentsH; ++j)
{
Expand All @@ -176,15 +187,17 @@ package away3d.primitives
revolutionAngle = i * revolutionAngleDelta;
x = radius * Math.cos(revolutionAngle);
y = radius * Math.sin(revolutionAngle);
var tanLen:Number = Math.sqrt(y * y + x * x);
na0 = latNormBase * Math.cos(revolutionAngle);
na1 = latNormBase * Math.sin(revolutionAngle);

if(_yUp)
addVertex(x, -z, y,
x / tanLen, 0, y / tanLen,
tanLen > .007 ? -y / tanLen : 1, 0, tanLen > .007 ? x / tanLen : 0);
na0, latNormElev, na1,
na1, 0, -na0);
else
addVertex(x, y, z,
x / tanLen, y / tanLen, 0,
tanLen > .007 ? -y / tanLen : 1, tanLen > .007 ? x / tanLen : 0, 0);
na0, na1, latNormElev,
na1, -na0, 0);

// close triangle
if(i > 0 && j > 0)
Expand Down

0 comments on commit b96e3dc

Please sign in to comment.