/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.graphics.g3d.utils.shapebuilders;
import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder;
import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder.VertexInfo;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.utils.ShortArray;
/** Helper class with static methods to build sphere shapes using {@link MeshPartBuilder}.
* @author xoppa */
public class SphereShapeBuilder extends BaseShapeBuilder {
private final static ShortArray tmpIndices = new ShortArray();
public static void build (MeshPartBuilder builder, float width, float height, float depth, int divisionsU, int divisionsV) {
build(builder, width, height, depth, divisionsU, divisionsV, 0, 360, 0, 180);
}
/** @deprecated use {@link MeshPartBuilder#setVertexTransform(Matrix4)} instead of using the method signature taking a matrix. */
@Deprecated
public static void build (MeshPartBuilder builder, final Matrix4 transform, float width, float height, float depth,
int divisionsU, int divisionsV) {
build(builder, transform, width, height, depth, divisionsU, divisionsV, 0, 360, 0, 180);
}
public static void build (MeshPartBuilder builder, float width, float height, float depth, int divisionsU, int divisionsV,
float angleUFrom, float angleUTo, float angleVFrom, float angleVTo) {
build(builder, matTmp1.idt(), width, height, depth, divisionsU, divisionsV, angleUFrom, angleUTo, angleVFrom, angleVTo);
}
/** @deprecated use {@link MeshPartBuilder#setVertexTransform(Matrix4)} instead of using the method signature taking a matrix. */
@Deprecated
public static void build (MeshPartBuilder builder, final Matrix4 transform, float width, float height, float depth,
int divisionsU, int divisionsV, float angleUFrom, float angleUTo, float angleVFrom, float angleVTo) {
// FIXME create better sphere method (- only one vertex for each pole, - position)
final float hw = width * 0.5f;
final float hh = height * 0.5f;
final float hd = depth * 0.5f;
final float auo = MathUtils.degreesToRadians * angleUFrom;
final float stepU = (MathUtils.degreesToRadians * (angleUTo - angleUFrom)) / divisionsU;
final float avo = MathUtils.degreesToRadians * angleVFrom;
final float stepV = (MathUtils.degreesToRadians * (angleVTo - angleVFrom)) / divisionsV;
final float us = 1f / divisionsU;
final float vs = 1f / divisionsV;
float u = 0f;
float v = 0f;
float angleU = 0f;
float angleV = 0f;
VertexInfo curr1 = vertTmp3.set(null, null, null, null);
curr1.hasUV = curr1.hasPosition = curr1.hasNormal = true;
final int s = divisionsU + 3;
tmpIndices.clear();
tmpIndices.ensureCapacity(divisionsU * 2);
tmpIndices.size = s;
int tempOffset = 0;
builder.ensureVertices((divisionsV + 1) * (divisionsU + 1));
builder.ensureRectangleIndices(divisionsU);
for (int iv = 0; iv <= divisionsV; iv++) {
angleV = avo + stepV * iv;
v = vs * iv;
final float t = MathUtils.sin(angleV);
final float h = MathUtils.cos(angleV) * hh;
for (int iu = 0; iu <= divisionsU; iu++) {
angleU = auo + stepU * iu;
u = 1f - us * iu;
// Fixme : wrong normal calculation if transform
curr1.position.set(MathUtils.cos(angleU) * hw * t, h, MathUtils.sin(angleU) * hd * t).mul(transform);
curr1.normal.set(curr1.position).nor();
curr1.uv.set(u, v);
tmpIndices.set(tempOffset, builder.vertex(curr1));
final int o = tempOffset + s;
if ((iv > 0) && (iu > 0)) // FIXME don't duplicate lines and points
builder.rect(tmpIndices.get(tempOffset), tmpIndices.get((o - 1) % s), tmpIndices.get((o - (divisionsU + 2)) % s),
tmpIndices.get((o - (divisionsU + 1)) % s));
tempOffset = (tempOffset + 1) % tmpIndices.size;
}
}
}
}