14 #include <OpenGL/CGLMacro.h>
16 #define glGenVertexArrays glGenVertexArraysAPPLE
17 #define glBindVertexArray glBindVertexArrayAPPLE
18 #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
27 "description" :
"A 3D shape represented by a set of vertices with associated normals and other per-vertex data.",
28 "keywords" : [
"mesh",
"vertex" ],
52 unsigned int vertexCount;
55 float *textureCoordinates;
58 unsigned int elementCount;
62 unsigned int *elements;
80 unsigned int combinedBuffer;
81 unsigned int combinedBufferSize;
82 unsigned int combinedBufferStride;
85 void *textureCoordinateOffset;
88 unsigned int elementBuffer;
89 unsigned int elementBufferSize;
105 float **positions,
float **normals,
float **textureCoordinates,
float **colors,
106 unsigned int elementCount,
unsigned int **elements)
109 *positions = (
float *)malloc(
sizeof(
float) * 3 * vertexCount);
111 *normals = (
float *)malloc(
sizeof(
float) * 3 * vertexCount);
112 if (textureCoordinates)
113 *textureCoordinates = (
float *)malloc(
sizeof(
float) * 2 * vertexCount);
115 *colors = (
float *)malloc(
sizeof(
float) * 4 * vertexCount);
117 *elements = elementCount ? (
unsigned int *)malloc(
sizeof(
unsigned int) * elementCount) : NULL;
125 VuoMesh_internal *m = (VuoMesh_internal *)value;
129 free(m->textureCoordinates);
133 VuoGlPool_release(VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize, m->glUpload.combinedBuffer);
134 VuoGlPool_release(VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize, m->glUpload.elementBuffer);
142 static VuoMesh_internal *VuoMesh_makeInternal(
void)
144 VuoMesh_internal *m = (VuoMesh_internal *)calloc(1,
sizeof(VuoMesh_internal));
153 static VuoMesh_internal *VuoMesh_makeSingletonInternal(
void)
155 VuoMesh_internal *m = (VuoMesh_internal *)calloc(1,
sizeof(VuoMesh_internal));
176 float *positions,
float *normals,
float *textureCoordinates,
float *colors,
179 VuoMesh_internal *m = VuoMesh_makeInternal();
181 m->vertexCount = vertexCount;
182 m->positions = positions;
183 m->normals = normals;
184 m->textureCoordinates = textureCoordinates;
186 m->elementCount = elementCount;
187 m->elements = elements;
188 m->elementAssemblyMethod = elementAssemblyMethod;
197 VuoMesh VuoMesh_makeFromGPUBuffers(
unsigned int vertexCount,
unsigned int combinedBuffer,
unsigned int combinedBufferSize,
void *normalOffset,
void *textureCoordinateOffset,
void *colorOffset,
unsigned int elementCount,
unsigned int elementBuffer,
unsigned int elementBufferSize,
VuoMesh_ElementAssemblyMethod elementAssemblyMethod)
199 VuoMesh_internal *m = VuoMesh_makeInternal();
201 m->vertexCount = vertexCount;
202 m->elementCount = elementCount;
203 m->elementAssemblyMethod = elementAssemblyMethod;
204 m->glUpload.combinedBuffer = combinedBuffer;
205 m->glUpload.combinedBufferSize = combinedBufferSize;
206 m->glUpload.normalOffset = normalOffset;
207 m->glUpload.textureCoordinateOffset = textureCoordinateOffset;
208 m->glUpload.colorOffset = colorOffset;
209 m->glUpload.elementBuffer = elementBuffer;
210 m->glUpload.elementBufferSize = elementBufferSize;
223 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
228 return GL_TRIANGLE_STRIP;
230 return GL_TRIANGLE_FAN;
234 return GL_LINE_STRIP;
254 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
257 return m->elementCount ? m->elementCount/3 : m->vertexCount/3;
259 return m->elementCount ? m->elementCount-2 : m->vertexCount-2;
261 return m->elementCount ? m->elementCount-2 : m->vertexCount-2;
263 return m->elementCount ? m->elementCount/2 : m->vertexCount/2;
265 return m->elementCount ? m->elementCount-1 : m->vertexCount-1;
267 return m->elementCount ? m->elementCount : m->vertexCount;
285 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
287 if (m->elementCount == 0 && m->vertexCount == 0)
291 return m->elementCount ? m->elementCount : m->vertexCount;
293 return m->elementCount ? (m->elementCount-2)*3 : (m->vertexCount-2)*3;
295 return m->elementCount ? (m->elementCount-2)*3 : (m->vertexCount-2)*3;
297 return m->elementCount ? m->elementCount : m->vertexCount;
299 return m->elementCount ? (m->elementCount-1)*2 : (m->vertexCount-1)*2;
301 return m->elementCount ? m->elementCount : m->vertexCount;
322 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
324 unsigned long elementCount = m->elementCount ? m->elementCount : m->vertexCount;
333 if (!m || m->glUpload.combinedBuffer)
345 m->glUpload.combinedBufferSize =
sizeof(float) * 3 * m->vertexCount;
347 uint64_t normalOffsetBytes = 0;
350 normalOffsetBytes = m->glUpload.combinedBufferSize;
351 m->glUpload.combinedBufferSize +=
sizeof(float) * 3 * m->vertexCount;
353 m->glUpload.normalOffset = (
void *)normalOffsetBytes;
355 uint64_t textureCoordinateOffsetBytes = 0;
356 if (m->textureCoordinates)
358 textureCoordinateOffsetBytes = m->glUpload.combinedBufferSize;
359 m->glUpload.combinedBufferSize +=
sizeof(float) * 2 * m->vertexCount;
361 m->glUpload.textureCoordinateOffset = (
void *)textureCoordinateOffsetBytes;
363 uint64_t colorOffsetBytes = 0;
366 colorOffsetBytes = m->glUpload.combinedBufferSize;
367 m->glUpload.combinedBufferSize +=
sizeof(float) * 4 * m->vertexCount;
369 m->glUpload.colorOffset = (
void *)colorOffsetBytes;
371 float *combinedData = (
float *)malloc(m->glUpload.combinedBufferSize);
372 for (
int i =0; i < m->glUpload.combinedBufferSize/
sizeof(float); ++i)
377 for (
unsigned long i = 0; i < m->vertexCount; ++i)
379 combinedData[i * 3 ] = m->positions[i * 3 ];
380 combinedData[i * 3 + 1] = m->positions[i * 3 + 1];
381 combinedData[i * 3 + 2] = m->positions[i * 3 + 2];
384 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) ] = m->normals[i * 3 ];
385 combinedData[i * 3 + normalOffsetBytes /
sizeof(
float) + 1] = m->normals[i * 3 + 1];
386 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) + 2] = m->normals[i * 3 + 2];
388 if (m->textureCoordinates)
390 combinedData[i * 2 + textureCoordinateOffsetBytes /
sizeof(float) ] = m->textureCoordinates[i * 2 ];
391 combinedData[i * 2 + textureCoordinateOffsetBytes /
sizeof(
float) + 1] = m->textureCoordinates[i * 2 + 1];
395 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) ] = m->colors[i * 4 ];
396 combinedData[i * 4 + colorOffsetBytes /
sizeof(
float) + 1] = m->colors[i * 4 + 1];
397 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) + 2] = m->colors[i * 4 + 2];
398 combinedData[i * 4 + colorOffsetBytes /
sizeof(
float) + 3] = m->colors[i * 4 + 3];
408 m->glUpload.combinedBuffer =
VuoGlPool_use(cgl_ctx, VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize);
410 glBindBuffer(GL_ARRAY_BUFFER, m->glUpload.combinedBuffer);
411 glBufferSubData(GL_ARRAY_BUFFER, 0, m->glUpload.combinedBufferSize, combinedData);
416 m->glUpload.elementBufferSize =
sizeof(
unsigned int)*m->elementCount;
417 m->glUpload.elementBuffer =
VuoGlPool_use(cgl_ctx, VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize);
419 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->glUpload.elementBuffer);
420 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0,
sizeof(
unsigned int) * m->elementCount, m->elements);
422 glBindBuffer(GL_ARRAY_BUFFER, 0);
429 glFlushRenderAPPLE();
439 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
442 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
451 for (
int i = 0; i < m->vertexCount; ++i)
482 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
488 m->positions[0] = -.5;
489 m->positions[1] = -.5;
492 m->positions[3] = .5;
493 m->positions[4] = -.5;
496 m->positions[6] = -.5;
497 m->positions[7] = .5;
500 m->positions[9] = .5;
501 m->positions[10] = .5;
502 m->positions[11] = 0;
505 m->textureCoordinates[0] = 0;
506 m->textureCoordinates[1] = 0;
508 m->textureCoordinates[2] = 1;
509 m->textureCoordinates[3] = 0;
511 m->textureCoordinates[4] = 0;
512 m->textureCoordinates[5] = 1;
514 m->textureCoordinates[6] = 1;
515 m->textureCoordinates[7] = 1;
537 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
540 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
543 for (
int i = 0; i < m->vertexCount; ++i)
545 float angle = M_PI/2. + i * 2*M_PI/3.;
546 VuoPoint3d_setArray(&m->positions[i * 3], (VuoPoint3d){ cos(angle) / sqrt(3), sin(angle) / sqrt(3), 0 });
550 for (
int i = 0; i < m->vertexCount; ++i)
575 static VuoMesh sharedQuadWithNormals;
576 static dispatch_once_t token = 0;
577 dispatch_once(&token, ^{
581 return sharedQuadWithNormals;
593 static VuoMesh sharedQuadWithoutNormals;
594 static dispatch_once_t token = 0;
595 dispatch_once(&token, ^{
599 return sharedQuadWithoutNormals;
609 static VuoMesh sharedEquilateralTriangle;
610 static dispatch_once_t token = 0;
611 dispatch_once(&token, ^{
615 return sharedEquilateralTriangle;
625 VuoPoint3d positions[] = (VuoPoint3d[]){
658 VuoPoint3d normals[] = (VuoPoint3d[]){
691 VuoPoint2d textureCoordinates[] = (VuoPoint2d[]){
724 unsigned int elements[] = (
unsigned int[]){
745 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
746 m->vertexCount = 6 * 4;
747 m->elementCount = 6 * 6;
748 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
750 for (
int i = 0; i < m->vertexCount; ++i)
756 memcpy(m->elements, elements,
sizeof(elements));
770 static dispatch_once_t token = 0;
771 dispatch_once(&token, ^{
785 unsigned int vertexCount = rows * columns;
786 unsigned int triangleCount = (rows-1) * (columns-1) * 6;
788 float *positions, *normals, *textureCoordinates;
789 unsigned int *elements;
792 unsigned int index = 0, t_index = 0;
794 for(
unsigned int i = 0; i < rows; i++)
796 float y = (i/(float)(rows-1)) - .5;
798 for(
unsigned int n = 0; n < columns; n++)
800 float x = (n/(float)(columns-1)) - .5;
806 if(n < columns-1 && i < rows-1)
808 elements[t_index++] = index + columns;
809 elements[t_index++] = index;
810 elements[t_index++] = index + 1;
812 elements[t_index++] = index + 1;
813 elements[t_index++] = index + columns + 1;
814 elements[t_index++] = index + columns;
822 positions, normals, textureCoordinates, NULL,
833 return (elementCount / 3) * 3;
838 return elementCount < 3 ? 0 : elementCount;
842 return (elementCount / 2) * 2;
846 return elementCount < 2 ? 0 : elementCount;
854 VUserLog(
"Error: Unknown submesh element assembly method: %d", elementAssemblyMethod);
875 float *positionsFloat, *normals, *colorsFloat = NULL;
877 for (
unsigned long i = 0; i < positionCount; ++i)
879 VuoPoint2d xy = positionValues[i];
880 positionsFloat[i * 3 ] = xy.x;
881 positionsFloat[i * 3 + 1] = xy.y;
882 positionsFloat[i * 3 + 2] = 0;
885 normals[i * 3 + 1] = 0;
886 normals[i * 3 + 2] = 1;
890 float progress = (float)i /
MAX(1, positionCount - 1);
891 unsigned long colorIndex = round(progress * (colorCount - 1));
892 VuoColor c = colorValues[colorIndex];
893 colorsFloat[i * 4 ] = c.r * c.a;
894 colorsFloat[i * 4 + 1] = c.g * c.a;
895 colorsFloat[i * 4 + 2] = c.b * c.a;
896 colorsFloat[i * 4 + 3] = c.a;
901 positionsFloat, normals, NULL, colorsFloat,
902 0, NULL, elementAssemblyMethod);
923 float *positionsFloat, *normals, *colorsFloat = NULL;
925 for (
unsigned long i = 0; i < positionCount; ++i)
930 normals[i * 3 + 1] = 0;
931 normals[i * 3 + 2] = 1;
935 float progress = (float)i /
MAX(1, positionCount - 1);
936 unsigned long colorIndex = round(progress * (colorCount - 1));
937 VuoColor c = colorValues[colorIndex];
938 colorsFloat[i * 4 ] = c.r * c.a;
939 colorsFloat[i * 4 + 1] = c.g * c.a;
940 colorsFloat[i * 4 + 2] = c.b * c.a;
941 colorsFloat[i * 4 + 3] = c.a;
946 positionsFloat, normals, NULL, colorsFloat,
947 0, NULL, elementAssemblyMethod);
960 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
961 VuoMesh_internal *copiedMesh = VuoMesh_makeInternal();
962 copiedMesh->vertexCount = m->vertexCount;
963 copiedMesh->elementCount = m->elementCount;
967 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
968 copiedMesh->positions = (
float *)malloc(size);
969 memcpy(copiedMesh->positions, m->positions, size);
972 copiedMesh->positions = NULL;
976 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
977 copiedMesh->normals = (
float *)malloc(size);
978 memcpy(copiedMesh->normals, m->normals, size);
981 copiedMesh->normals = NULL;
983 if (m->textureCoordinates)
985 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
986 copiedMesh->textureCoordinates = (
float *)malloc(size);
987 memcpy(copiedMesh->textureCoordinates, m->textureCoordinates, size);
990 copiedMesh->textureCoordinates = NULL;
994 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
995 copiedMesh->colors = (
float *)malloc(size);
996 memcpy(copiedMesh->colors, m->colors, size);
999 copiedMesh->colors = NULL;
1001 copiedMesh->elementCount = m->elementCount;
1004 unsigned long elementByteCount =
sizeof(
unsigned int)*m->elementCount;
1005 copiedMesh->elements = (
unsigned int *)malloc(elementByteCount);
1006 memcpy(copiedMesh->elements, m->elements, elementByteCount);
1009 copiedMesh->elements = NULL;
1011 copiedMesh->elementAssemblyMethod = m->elementAssemblyMethod;
1012 copiedMesh->primitiveSize = m->primitiveSize;
1013 copiedMesh->faceCulling = m->faceCulling;
1015 memcpy(&copiedMesh->glUpload, &m->glUpload,
sizeof(copiedMesh->glUpload));
1037 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1038 VuoMesh_internal *copiedMesh = VuoMesh_makeInternal();
1040 copiedMesh->vertexCount = m->vertexCount;
1041 copiedMesh->elementCount = m->elementCount;
1043 copiedMesh->elementAssemblyMethod = m->elementAssemblyMethod;
1044 copiedMesh->primitiveSize = m->primitiveSize;
1045 copiedMesh->faceCulling = m->faceCulling;
1047 memcpy(&copiedMesh->glUpload, &m->glUpload,
sizeof(copiedMesh->glUpload));
1064 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1065 if (m->textureCoordinates)
1067 free(m->textureCoordinates);
1068 m->textureCoordinates = NULL;
1071 if (m->glUpload.combinedBuffer && m->glUpload.textureCoordinateOffset)
1073 m->glUpload.textureCoordinateOffset = NULL;
1091 float **positions,
float **normals,
float **textureCoordinates,
float **colors,
1092 unsigned int *elementCount,
unsigned int **elements)
1097 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1100 *vertexCount = m->vertexCount;
1102 *positions = m->positions;
1104 *normals = m->normals;
1105 if (textureCoordinates)
1106 *textureCoordinates = m->textureCoordinates;
1108 *colors = m->colors;
1110 *elementCount = m->elementCount;
1112 *elements = m->elements;
1123 unsigned int *combinedBuffer,
1124 void **normalOffset,
void **textureCoordinateOffset,
void **colorOffset,
1125 unsigned int *elementCount,
unsigned int *elementBuffer)
1130 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1133 *vertexCount = m->vertexCount;
1135 *combinedBuffer = m->glUpload.combinedBuffer;
1137 *normalOffset = m->glUpload.normalOffset;
1138 if (textureCoordinateOffset)
1139 *textureCoordinateOffset = m->glUpload.textureCoordinateOffset;
1141 *colorOffset = m->glUpload.colorOffset;
1143 *elementCount = m->elementCount;
1145 *elementBuffer = m->glUpload.elementBuffer;
1158 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1159 return m->elementAssemblyMethod;
1172 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1173 return m->faceCulling;
1186 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1205 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1206 return m->primitiveSize;
1219 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1220 return m->glUpload.elementBufferSize;
1232 float *positions,
float *normals,
float *textureCoordinates,
float *colors,
1233 unsigned int elementCount,
unsigned int *elements)
1238 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1240 m->vertexCount = vertexCount;
1242 if (m->positions != positions)
1245 m->positions = positions;
1248 if (m->normals != normals)
1251 m->normals = normals;
1254 if (m->textureCoordinates != textureCoordinates)
1256 free(m->textureCoordinates);
1257 m->textureCoordinates = textureCoordinates;
1260 if (m->colors != colors)
1266 m->elementCount = elementCount;
1268 if (m->elements != elements)
1271 m->elements = elements;
1274 VuoGlPool_release(VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize, m->glUpload.combinedBuffer);
1275 VuoGlPool_release(VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize, m->glUpload.elementBuffer);
1276 m->glUpload.combinedBufferSize = 0;
1277 m->glUpload.combinedBuffer = 0;
1278 m->glUpload.elementBufferSize = 0;
1279 m->glUpload.elementBuffer = 0;
1294 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1295 m->faceCulling = faceCulling;
1308 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1309 m->primitiveSize = primitiveSize;
1318 if (strcmp(elementAssemblyMethodString,
"individualTriangles")==0)
1320 else if (strcmp(elementAssemblyMethodString,
"triangleStrip")==0)
1322 else if (strcmp(elementAssemblyMethodString,
"triangleFan")==0)
1324 else if (strcmp(elementAssemblyMethodString,
"individualLines")==0)
1326 else if (strcmp(elementAssemblyMethodString,
"lineStrip")==0)
1328 else if (strcmp(elementAssemblyMethodString,
"points")==0)
1341 switch (elementAssemblyMethod)
1344 return "individualTriangles";
1346 return "triangleStrip";
1348 return "triangleFan";
1350 return "individualLines";
1363 if (!m->glUpload.combinedBuffer
1365 && (m->normals || !m->glUpload.normalOffset)
1366 && (m->textureCoordinates || !m->glUpload.textureCoordinateOffset)
1367 && (m->colors || !m->glUpload.colorOffset)
1368 && (m->elements || !m->glUpload.elementBuffer)))
1372 glBindBuffer(GL_ARRAY_BUFFER, m->glUpload.combinedBuffer);
1377 float *vertexData = (
float *)malloc(m->glUpload.combinedBufferSize);
1378 glGetBufferSubData(GL_ARRAY_BUFFER, 0, m->glUpload.combinedBufferSize, vertexData);
1379 glBindBuffer(GL_ARRAY_BUFFER, 0);
1383 m->positions = (
float *)malloc(
sizeof(
float) * 3 * m->vertexCount);
1384 memcpy(m->positions, vertexData,
sizeof(
float) * 3 * m->vertexCount);
1387 if (!m->normals && m->glUpload.normalOffset)
1389 m->normals = (
float *)malloc(
sizeof(
float) * 3 * m->vertexCount);
1390 memcpy(m->normals, (
char *)vertexData + (
int)m->glUpload.normalOffset,
sizeof(
float) * 3 * m->vertexCount);
1393 if (!m->textureCoordinates && m->glUpload.textureCoordinateOffset)
1395 m->textureCoordinates = (
float *)malloc(
sizeof(
float) * 2 * m->vertexCount);
1396 memcpy(m->textureCoordinates, (
char *)vertexData + (
int)m->glUpload.textureCoordinateOffset,
sizeof(
float) * 2 * m->vertexCount);
1399 if (!m->colors && m->glUpload.colorOffset)
1401 m->colors = (
float *)malloc(
sizeof(
float) * 4 * m->vertexCount);
1402 memcpy(m->colors, (
char *)vertexData + (
int)m->glUpload.colorOffset,
sizeof(
float) * 4 * m->vertexCount);
1405 if (!m->elements && m->glUpload.elementBuffer)
1407 m->elements = malloc(m->glUpload.elementBufferSize);
1408 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->glUpload.elementBuffer);
1409 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m->glUpload.elementBufferSize, m->elements);
1410 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1421 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1423 VuoPoint3d min, max;
1426 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1427 unsigned int vertexCount = m->vertexCount;
1431 if(vertexCount > 0 && !init)
1437 for(
int n = 0; n < vertexCount; n++)
1441 min.x =
MIN(p.x, min.x);
1442 min.y =
MIN(p.y, min.y);
1443 min.z =
MIN(p.z, min.z);
1445 max.x =
MAX(p.x, max.x);
1446 max.y =
MAX(p.y, max.y);
1447 max.z =
MAX(p.z, max.z);
1454 return VuoBox_make((min + max) / (VuoPoint3d)(2.), max - min);
1456 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1467 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1468 return m->vertexCount > 0;
1481 if (json_object_object_get_ex(js,
"pointer", &o))
1482 return (
VuoMesh)json_object_get_int64(o);
1497 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value));
1517 return strdup(
"Empty mesh");
1519 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1521 if (!m->vertexCount)
1522 return strdup(
"Mesh without any vertices");
1525 const char * objectString =
"";
1526 const char * assemblyMethod =
" (unknown element assembly method)";
1529 assemblyMethod =
", ";
1530 objectString =
"triangle";
1535 assemblyMethod =
" in a strip of ";
1536 objectString =
"triangle";
1540 assemblyMethod =
" in a fan of ";
1541 objectString =
"triangle";
1545 assemblyMethod =
", ";
1546 objectString =
"line";
1550 assemblyMethod =
" in a strip of ";
1551 objectString =
"line";
1555 assemblyMethod =
", ";
1556 objectString =
"point";
1559 const char * vertexCountString = m->vertexCount==1 ?
"vertex" :
"vertices";
1560 const char * objectStringPlural = objectCount==1 ?
"" :
"s";
1562 char *firstPosition = NULL;
1566 char *summary =
VuoText_format(
"<div>%u %s%s%lu %s%s</div>%s<div>%s positions</div><div>%s normals</div><div>%s texture coordinates</div><div>%s vertex colors</div>",
1567 m->vertexCount, vertexCountString, assemblyMethod, objectCount, objectString, objectStringPlural,
1568 firstPosition ? firstPosition :
"",
1569 (m->positions || m->glUpload.combinedBuffer ) ?
"✓" :
"◻",
1570 (m->normals || m->glUpload.normalOffset ) ?
"✓" :
"◻",
1571 (m->textureCoordinates || m->glUpload.textureCoordinateOffset) ?
"✓" :
"◻",
1572 (m->colors || m->glUpload.colorOffset ) ?
"✓" :
"◻");
1574 free(firstPosition);