parent
ab30437529
commit
48308a5e0a
1 changed files with 32 additions and 28 deletions
|
@ -938,36 +938,40 @@ CSGBrush *CSGSphere::_build_brush() {
|
|||
PoolVector<Ref<Material>>::Write materialsw = materials.write();
|
||||
PoolVector<bool>::Write invertw = invert.write();
|
||||
|
||||
const double lat_step = 1.0 / rings;
|
||||
const double lon_step = 1.0 / radial_segments;
|
||||
// We want to follow an order that's convenient for UVs.
|
||||
// For latitude step we start at the top and move down like in an image.
|
||||
const double latitude_step = -Math_PI / rings;
|
||||
const double longitude_step = Math_TAU / radial_segments;
|
||||
int face = 0;
|
||||
for (int i = 1; i <= rings; i++) {
|
||||
double lat0 = Math_PI * (0.5 - (i - 1) * lat_step);
|
||||
double c0 = Math::cos(lat0);
|
||||
double s0 = Math::sin(lat0);
|
||||
double v0 = double(i - 1) / rings;
|
||||
for (int i = 0; i < rings; i++) {
|
||||
double latitude0 = latitude_step * i + Math_TAU / 4;
|
||||
double cos0 = Math::cos(latitude0);
|
||||
double sin0 = Math::sin(latitude0);
|
||||
double v0 = double(i) / rings;
|
||||
|
||||
double lat1 = Math_PI * (0.5 - i * lat_step);
|
||||
double c1 = Math::cos(lat1);
|
||||
double s1 = Math::sin(lat1);
|
||||
double v1 = double(i) / rings;
|
||||
double latitude1 = latitude_step * (i + 1) + Math_TAU / 4;
|
||||
double cos1 = Math::cos(latitude1);
|
||||
double sin1 = Math::sin(latitude1);
|
||||
double v1 = double(i + 1) / rings;
|
||||
|
||||
for (int j = 1; j <= radial_segments; j++) {
|
||||
double lng0 = Math_TAU * (0.5 - (j - 1) * lon_step);
|
||||
double x0 = Math::cos(lng0);
|
||||
double y0 = Math::sin(lng0);
|
||||
double u0 = double(j - 1) / radial_segments;
|
||||
for (int j = 0; j < radial_segments; j++) {
|
||||
double longitude0 = longitude_step * j;
|
||||
// We give sin to X and cos to Z on purpose.
|
||||
// This allows UVs to be CCW on +X so it maps to images well.
|
||||
double x0 = Math::sin(longitude0);
|
||||
double z0 = Math::cos(longitude0);
|
||||
double u0 = double(j) / radial_segments;
|
||||
|
||||
double lng1 = Math_TAU * (0.5 - j * lon_step);
|
||||
double x1 = Math::cos(lng1);
|
||||
double y1 = Math::sin(lng1);
|
||||
double u1 = double(j) / radial_segments;
|
||||
double longitude1 = longitude_step * (j + 1);
|
||||
double x1 = Math::sin(longitude1);
|
||||
double z1 = Math::cos(longitude1);
|
||||
double u1 = double(j + 1) / radial_segments;
|
||||
|
||||
Vector3 v[4] = {
|
||||
Vector3(x0 * c0, s0, y0 * c0) * radius,
|
||||
Vector3(x1 * c0, s0, y1 * c0) * radius,
|
||||
Vector3(x1 * c1, s1, y1 * c1) * radius,
|
||||
Vector3(x0 * c1, s1, y0 * c1) * radius,
|
||||
Vector3(x0 * cos0, sin0, z0 * cos0) * radius,
|
||||
Vector3(x1 * cos0, sin0, z1 * cos0) * radius,
|
||||
Vector3(x1 * cos1, sin1, z1 * cos1) * radius,
|
||||
Vector3(x0 * cos1, sin1, z0 * cos1) * radius,
|
||||
};
|
||||
|
||||
Vector2 u[4] = {
|
||||
|
@ -977,8 +981,8 @@ CSGBrush *CSGSphere::_build_brush() {
|
|||
Vector2(u0, v1),
|
||||
};
|
||||
|
||||
if (i < rings) {
|
||||
//face 1
|
||||
// Draw the first face, but skip this at the north pole (i == 0).
|
||||
if (i > 0) {
|
||||
facesw[face * 3 + 0] = v[0];
|
||||
facesw[face * 3 + 1] = v[1];
|
||||
facesw[face * 3 + 2] = v[2];
|
||||
|
@ -994,8 +998,8 @@ CSGBrush *CSGSphere::_build_brush() {
|
|||
face++;
|
||||
}
|
||||
|
||||
if (i > 1) {
|
||||
//face 2
|
||||
// Draw the second face, but skip this at the south pole (i == rings - 1).
|
||||
if (i < rings - 1) {
|
||||
facesw[face * 3 + 0] = v[2];
|
||||
facesw[face * 3 + 1] = v[3];
|
||||
facesw[face * 3 + 2] = v[0];
|
||||
|
|
Loading…
Reference in a new issue