34 .
description(
N_(
"Distance from the generated points to the origin"));
40 return segments * (rings - 1) + 2;
45 return segments * (rings * 2 - 1);
50 const int quad_corners = 4 * segments * (rings - 2);
51 const int tri_corners = 3 * segments * 2;
52 return quad_corners + tri_corners;
57 const int quads = segments * (rings - 2);
58 const int triangles = segments * 2;
59 return quads + triangles;
72 const float delta_theta =
M_PI / rings;
90 for (
const int ring :
IndexRange(1, rings - 1)) {
91 const float theta = ring * delta_theta;
92 const float sin_theta =
std::sin(theta);
95 const float x = sin_theta * segment_cosines[
segment];
96 const float y = sin_theta * segment_sines[
segment];
98 vert_normals[vert_index] =
float3(
x,
y,
z);
104 vert_normals.
last() =
float3(0.0f, 0.0f, -1.0f);
114 const int first_vert_ring_index_start = 1;
116 MEdge &edge = edges[edge_index++];
118 edge.v2 = first_vert_ring_index_start +
segment;
122 int ring_vert_index_start = 1;
123 for (
const int ring :
IndexRange(rings - 1)) {
124 const int next_ring_vert_index_start = ring_vert_index_start + segments;
128 MEdge &edge = edges[edge_index++];
129 edge.v1 = ring_vert_index_start +
segment;
130 edge.v2 = ring_vert_index_start + ((
segment + 1) % segments);
135 if (ring < rings - 2) {
137 MEdge &edge = edges[edge_index++];
138 edge.v1 = ring_vert_index_start +
segment;
139 edge.v2 = next_ring_vert_index_start +
segment;
143 ring_vert_index_start += segments;
148 const int last_vert_ring_start = last_vert_index - segments;
150 MEdge &edge = edges[edge_index++];
151 edge.v1 = last_vert_index;
152 edge.v2 = last_vert_ring_start +
segment;
163 poly.loopstart = loop_index;
170 poly.loopstart = loop_index;
177 poly.loopstart = loop_index;
188 auto segment_next_or_first = [&](
const int segment) {
193 const int first_vert_ring_index_start = 1;
195 const int segment_next = segment_next_or_first(
segment);
197 MLoop &loop_a = loops[loop_index++];
200 MLoop &loop_b = loops[loop_index++];
201 loop_b.
v = first_vert_ring_index_start +
segment;
203 MLoop &loop_c = loops[loop_index++];
204 loop_c.
v = first_vert_ring_index_start + segment_next;
205 loop_c.
e = segment_next;
208 int ring_vert_index_start = 1;
209 int ring_edge_index_start = segments;
210 for ([[maybe_unused]]
const int ring :
IndexRange(1, rings - 2)) {
211 const int next_ring_vert_index_start = ring_vert_index_start + segments;
212 const int next_ring_edge_index_start = ring_edge_index_start + segments * 2;
213 const int ring_vertical_edge_index_start = ring_edge_index_start + segments;
216 const int segment_next = segment_next_or_first(
segment);
218 MLoop &loop_a = loops[loop_index++];
219 loop_a.
v = ring_vert_index_start +
segment;
220 loop_a.
e = ring_vertical_edge_index_start +
segment;
221 MLoop &loop_b = loops[loop_index++];
222 loop_b.
v = next_ring_vert_index_start +
segment;
223 loop_b.
e = next_ring_edge_index_start +
segment;
224 MLoop &loop_c = loops[loop_index++];
225 loop_c.
v = next_ring_vert_index_start + segment_next;
226 loop_c.
e = ring_vertical_edge_index_start + segment_next;
227 MLoop &loop_d = loops[loop_index++];
228 loop_d.
v = ring_vert_index_start + segment_next;
229 loop_d.
e = ring_edge_index_start +
segment;
231 ring_vert_index_start += segments;
232 ring_edge_index_start += segments * 2;
236 const int last_edge_ring_start = segments * (rings - 2) * 2 + segments;
237 const int bottom_edge_fan_start = last_edge_ring_start + segments;
239 const int last_vert_ring_start = last_vert_index - segments;
241 const int segment_next = segment_next_or_first(
segment);
243 MLoop &loop_a = loops[loop_index++];
244 loop_a.
v = last_vert_index;
245 loop_a.
e = bottom_edge_fan_start + segment_next;
246 MLoop &loop_b = loops[loop_index++];
247 loop_b.
v = last_vert_ring_start + segment_next;
248 loop_b.
e = last_edge_ring_start +
segment;
249 MLoop &loop_c = loops[loop_index++];
250 loop_c.
v = last_vert_ring_start +
segment;
251 loop_c.
e = bottom_edge_fan_start +
segment;
264 const float dy = 1.0f / rings;
266 const float segments_inv = 1.0f / segments;
268 for (
const int i_segment :
IndexRange(segments)) {
269 const float segment =
static_cast<float>(i_segment);
270 uvs[loop_index++] =
float2((
segment + 0.5f) * segments_inv, 0.0f);
272 uvs[loop_index++] =
float2((
segment + 1.0f) * segments_inv, dy);
275 for (
const int i_ring :
IndexRange(1, rings - 2)) {
276 const float ring =
static_cast<float>(i_ring);
277 for (
const int i_segment :
IndexRange(segments)) {
278 const float segment =
static_cast<float>(i_segment);
279 uvs[loop_index++] =
float2(
segment * segments_inv, ring / rings);
280 uvs[loop_index++] =
float2(
segment * segments_inv, (ring + 1.0f) / rings);
281 uvs[loop_index++] =
float2((
segment + 1.0f) * segments_inv, (ring + 1.0f) / rings);
282 uvs[loop_index++] =
float2((
segment + 1.0f) * segments_inv, ring / rings);
286 for (
const int i_segment :
IndexRange(segments)) {
287 const float segment =
static_cast<float>(i_segment);
288 uvs[loop_index++] =
float2((
segment + 0.5f) * segments_inv, 1.0f);
289 uvs[loop_index++] =
float2((
segment + 1.0f) * segments_inv, 1.0f - dy);
290 uvs[loop_index++] =
float2(
segment * segments_inv, 1.0f - dy);
310 1024 < segments * rings,
327 const int rings_num =
params.extract_input<
int>(
"Rings");
335 params.set_default_remaining_outputs();
339 const float radius =
params.extract_input<
float>(
"Radius");
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(struct ID *id)
float(* BKE_mesh_vertex_normals_for_write(struct Mesh *mesh))[3]
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
void BKE_mesh_vertex_normals_clear_dirty(struct Mesh *mesh)
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_MESH_PRIMITIVE_UV_SPHERE
void nodeRegisterType(struct bNodeType *ntype)
MINLINE void copy_v3_v3(float r[3], const float a[3])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
in reality light always falls off quadratically Particle Info
ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t)
constexpr MutableSpan take_back(const int64_t n) const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr T & last(const int64_t n=0) const
constexpr T & first() const
constexpr MutableSpan take_front(const int64_t n) const
GSpanAttributeWriter lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type)
StringRefNull description() const
Segment< FEdge *, Vec3r > segment
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
int segments_num(const int points_num, const bool cyclic)
MutableAttributeAccessor mesh_attributes_for_write(Mesh &mesh)
static int sphere_edge_total(const int segments, const int rings)
static int sphere_vert_total(const int segments, const int rings)
static int sphere_corner_total(const int segments, const int rings)
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
static BLI_NOINLINE void calculate_sphere_faces(MutableSpan< MPoly > polys, const int segments)
static BLI_NOINLINE void calculate_sphere_uvs(Mesh *mesh, const float segments, const float rings)
static BLI_NOINLINE void calculate_sphere_corners(MutableSpan< MLoop > loops, const int segments, const int rings)
static Mesh * create_uv_sphere_mesh(const float radius, const int segments, const int rings)
static int sphere_face_total(const int segments, const int rings)
static BLI_NOINLINE void calculate_sphere_vertex_data(MutableSpan< MVert > verts, MutableSpan< float3 > vert_normals, const float radius, const int segments, const int rings)
static BLI_NOINLINE void calculate_sphere_edge_indices(MutableSpan< MEdge > edges, const int segments, const int rings)
void parallel_invoke(Functions &&...functions)
vec_base< float, 3 > float3
vec_base< float, 2 > float2
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_geo_mesh_primitive_uv_sphere()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
NodeGeometryExecFunction geometry_node_execute
NodeDeclareFunction declare
MutableVArraySpan< T > span