blob: 432224bf734b7e1a5699b1a3d36546f4611b116e [file] [log] [blame]
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
part of vector_math_geometry;
class CylinderGenerator extends GeometryGenerator {
double _topRadius;
double _bottomRadius;
double _height;
int _segments;
@override
int get vertexCount => ((_segments + 1) * 2) + (_segments * 2);
@override
int get indexCount => (_segments * 6) + ((_segments - 2) * 6);
MeshGeometry createCylinder(num topRadius, num bottomRadius, num height,
{int segments: 16,
GeometryGeneratorFlags flags,
List<GeometryFilter> filters}) {
_topRadius = topRadius.toDouble();
_bottomRadius = bottomRadius.toDouble();
_height = height.toDouble();
_segments = segments;
return createGeometry(flags: flags, filters: filters);
}
@override
void generateIndices(Uint16List indices) {
int i = 0;
// Sides
int base1 = 0;
final int base2 = _segments + 1;
for (int x = 0; x < _segments; ++x) {
indices[i++] = base1 + x;
indices[i++] = base1 + x + 1;
indices[i++] = base2 + x;
indices[i++] = base1 + x + 1;
indices[i++] = base2 + x + 1;
indices[i++] = base2 + x;
}
// Top cap
base1 = (_segments + 1) * 2;
for (int x = 1; x < _segments - 1; ++x) {
indices[i++] = base1;
indices[i++] = base1 + x + 1;
indices[i++] = base1 + x;
}
// Bottom cap
base1 = (_segments + 1) * 2 + _segments;
for (int x = 1; x < _segments - 1; ++x) {
indices[i++] = base1;
indices[i++] = base1 + x;
indices[i++] = base1 + x + 1;
}
}
@override
void generateVertexPositions(Vector3List positions, Uint16List indices) {
int i = 0;
// Top
for (int x = 0; x <= _segments; ++x) {
final double u = x / _segments;
positions[i++] = new Vector3(_topRadius * math.cos(u * math.PI * 2.0),
_height * 0.5, _topRadius * math.sin(u * math.PI * 2.0));
}
// Bottom
for (int x = 0; x <= _segments; ++x) {
final double u = x / _segments;
positions[i++] = new Vector3(_bottomRadius * math.cos(u * math.PI * 2.0),
_height * -0.5, _bottomRadius * math.sin(u * math.PI * 2.0));
}
// Top cap
for (int x = 0; x < _segments; ++x) {
final double u = x / _segments;
positions[i++] = new Vector3(_topRadius * math.cos(u * math.PI * 2.0),
_height * 0.5, _topRadius * math.sin(u * math.PI * 2.0));
}
// Bottom cap
for (int x = 0; x < _segments; ++x) {
final double u = x / _segments;
positions[i++] = new Vector3(_bottomRadius * math.cos(u * math.PI * 2.0),
_height * -0.5, _bottomRadius * math.sin(u * math.PI * 2.0));
}
}
@override
void generateVertexTexCoords(
Vector2List texCoords, Vector3List positions, Uint16List indices) {
int i = 0;
// Cylinder top
for (int x = 0; x <= _segments; ++x) {
final double u = 1.0 - (x / _segments);
texCoords[i++] = new Vector2(u, 0.0);
}
// Cylinder bottom
for (int x = 0; x <= _segments; ++x) {
final double u = 1.0 - (x / _segments);
texCoords[i++] = new Vector2(u, 1.0);
}
// Top cap
for (int x = 0; x < _segments; ++x) {
final double r = (x / _segments) * math.PI * 2.0;
texCoords[i++] =
new Vector2((math.cos(r) * 0.5 + 0.5), (math.sin(r) * 0.5 + 0.5));
}
// Bottom cap
for (int x = 0; x < _segments; ++x) {
final double r = (x / _segments) * math.PI * 2.0;
texCoords[i++] =
new Vector2((math.cos(r) * 0.5 + 0.5), (math.sin(r) * 0.5 + 0.5));
}
}
}