15 #include <OpenGL/CGLMacro.h>
17 #define glGenVertexArrays glGenVertexArraysAPPLE
18 #define glBindVertexArray glBindVertexArrayAPPLE
19 #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
28 "description" :
"A 3D shape represented by a set of vertices with associated normals and other per-vertex data.",
29 "keywords" : [
"mesh",
"vertex" ],
53 unsigned int vertexCount;
56 float *textureCoordinates;
59 unsigned int elementCount;
63 unsigned int *elements;
81 unsigned int combinedBuffer;
82 unsigned int combinedBufferSize;
83 unsigned int combinedBufferStride;
86 void *textureCoordinateOffset;
89 unsigned int elementBuffer;
90 unsigned int elementBufferSize;
106 float **positions,
float **normals,
float **textureCoordinates,
float **colors,
107 unsigned int elementCount,
unsigned int **elements)
110 *positions = (
float *)malloc(
sizeof(
float) * 3 * vertexCount);
112 *normals = (
float *)malloc(
sizeof(
float) * 3 * vertexCount);
113 if (textureCoordinates)
114 *textureCoordinates = (
float *)malloc(
sizeof(
float) * 2 * vertexCount);
116 *colors = (
float *)malloc(
sizeof(
float) * 4 * vertexCount);
118 *elements = elementCount ? (
unsigned int *)malloc(
sizeof(
unsigned int) * elementCount) : NULL;
126 VuoMesh_internal *m = (VuoMesh_internal *)value;
130 free(m->textureCoordinates);
134 VuoGlPool_release(VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize, m->glUpload.combinedBuffer);
135 VuoGlPool_release(VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize, m->glUpload.elementBuffer);
143 static VuoMesh_internal *VuoMesh_makeInternal(
void)
145 VuoMesh_internal *m = (VuoMesh_internal *)calloc(1,
sizeof(VuoMesh_internal));
154 static VuoMesh_internal *VuoMesh_makeSingletonInternal(
void)
156 VuoMesh_internal *m = (VuoMesh_internal *)calloc(1,
sizeof(VuoMesh_internal));
177 float *positions,
float *normals,
float *textureCoordinates,
float *colors,
180 VuoMesh_internal *m = VuoMesh_makeInternal();
182 m->vertexCount = vertexCount;
183 m->positions = positions;
184 m->normals = normals;
185 m->textureCoordinates = textureCoordinates;
187 m->elementCount = elementCount;
188 m->elements = elements;
189 m->elementAssemblyMethod = elementAssemblyMethod;
198 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)
200 VuoMesh_internal *m = VuoMesh_makeInternal();
202 m->vertexCount = vertexCount;
203 m->elementCount = elementCount;
204 m->elementAssemblyMethod = elementAssemblyMethod;
205 m->glUpload.combinedBuffer = combinedBuffer;
206 m->glUpload.combinedBufferSize = combinedBufferSize;
207 m->glUpload.normalOffset = normalOffset;
208 m->glUpload.textureCoordinateOffset = textureCoordinateOffset;
209 m->glUpload.colorOffset = colorOffset;
210 m->glUpload.elementBuffer = elementBuffer;
211 m->glUpload.elementBufferSize = elementBufferSize;
224 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
229 return GL_TRIANGLE_STRIP;
231 return GL_TRIANGLE_FAN;
235 return GL_LINE_STRIP;
255 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
258 return m->elementCount ? m->elementCount/3 : m->vertexCount/3;
260 return m->elementCount ? m->elementCount-2 : m->vertexCount-2;
262 return m->elementCount ? m->elementCount-2 : m->vertexCount-2;
264 return m->elementCount ? m->elementCount/2 : m->vertexCount/2;
266 return m->elementCount ? m->elementCount-1 : m->vertexCount-1;
268 return m->elementCount ? m->elementCount : m->vertexCount;
286 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
288 if (m->elementCount == 0 && m->vertexCount == 0)
292 return m->elementCount ? m->elementCount : m->vertexCount;
294 return m->elementCount ? (m->elementCount-2)*3 : (m->vertexCount-2)*3;
296 return m->elementCount ? (m->elementCount-2)*3 : (m->vertexCount-2)*3;
298 return m->elementCount ? m->elementCount : m->vertexCount;
300 return m->elementCount ? (m->elementCount-1)*2 : (m->vertexCount-1)*2;
302 return m->elementCount ? m->elementCount : m->vertexCount;
323 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
325 unsigned long elementCount = m->elementCount ? m->elementCount : m->vertexCount;
334 if (!m || m->glUpload.combinedBuffer)
346 m->glUpload.combinedBufferSize =
sizeof(float) * 3 * m->vertexCount;
348 uint64_t normalOffsetBytes = 0;
351 normalOffsetBytes = m->glUpload.combinedBufferSize;
352 m->glUpload.combinedBufferSize +=
sizeof(float) * 3 * m->vertexCount;
354 m->glUpload.normalOffset = (
void *)normalOffsetBytes;
356 uint64_t textureCoordinateOffsetBytes = 0;
357 if (m->textureCoordinates)
359 textureCoordinateOffsetBytes = m->glUpload.combinedBufferSize;
360 m->glUpload.combinedBufferSize +=
sizeof(float) * 2 * m->vertexCount;
362 m->glUpload.textureCoordinateOffset = (
void *)textureCoordinateOffsetBytes;
364 uint64_t colorOffsetBytes = 0;
367 colorOffsetBytes = m->glUpload.combinedBufferSize;
368 m->glUpload.combinedBufferSize +=
sizeof(float) * 4 * m->vertexCount;
370 m->glUpload.colorOffset = (
void *)colorOffsetBytes;
372 float *combinedData = (
float *)malloc(m->glUpload.combinedBufferSize);
373 for (
int i =0; i < m->glUpload.combinedBufferSize/
sizeof(float); ++i)
378 for (
unsigned long i = 0; i < m->vertexCount; ++i)
380 combinedData[i * 3 ] = m->positions[i * 3 ];
381 combinedData[i * 3 + 1] = m->positions[i * 3 + 1];
382 combinedData[i * 3 + 2] = m->positions[i * 3 + 2];
385 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) ] = m->normals[i * 3 ];
386 combinedData[i * 3 + normalOffsetBytes /
sizeof(
float) + 1] = m->normals[i * 3 + 1];
387 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) + 2] = m->normals[i * 3 + 2];
389 if (m->textureCoordinates)
391 combinedData[i * 2 + textureCoordinateOffsetBytes /
sizeof(float) ] = m->textureCoordinates[i * 2 ];
392 combinedData[i * 2 + textureCoordinateOffsetBytes /
sizeof(
float) + 1] = m->textureCoordinates[i * 2 + 1];
396 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) ] = m->colors[i * 4 ];
397 combinedData[i * 4 + colorOffsetBytes /
sizeof(
float) + 1] = m->colors[i * 4 + 1];
398 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) + 2] = m->colors[i * 4 + 2];
399 combinedData[i * 4 + colorOffsetBytes /
sizeof(
float) + 3] = m->colors[i * 4 + 3];
409 m->glUpload.combinedBuffer =
VuoGlPool_use(cgl_ctx, VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize);
411 glBindBuffer(GL_ARRAY_BUFFER, m->glUpload.combinedBuffer);
412 glBufferSubData(GL_ARRAY_BUFFER, 0, m->glUpload.combinedBufferSize, combinedData);
417 m->glUpload.elementBufferSize =
sizeof(
unsigned int)*m->elementCount;
418 m->glUpload.elementBuffer =
VuoGlPool_use(cgl_ctx, VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize);
420 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->glUpload.elementBuffer);
421 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0,
sizeof(
unsigned int) * m->elementCount, m->elements);
423 glBindBuffer(GL_ARRAY_BUFFER, 0);
430 glFlushRenderAPPLE();
440 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
443 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
452 for (
int i = 0; i < m->vertexCount; ++i)
483 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
489 m->positions[0] = -.5;
490 m->positions[1] = -.5;
493 m->positions[3] = .5;
494 m->positions[4] = -.5;
497 m->positions[6] = -.5;
498 m->positions[7] = .5;
501 m->positions[9] = .5;
502 m->positions[10] = .5;
503 m->positions[11] = 0;
506 m->textureCoordinates[0] = 0;
507 m->textureCoordinates[1] = 0;
509 m->textureCoordinates[2] = 1;
510 m->textureCoordinates[3] = 0;
512 m->textureCoordinates[4] = 0;
513 m->textureCoordinates[5] = 1;
515 m->textureCoordinates[6] = 1;
516 m->textureCoordinates[7] = 1;
538 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
541 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
544 for (
int i = 0; i < m->vertexCount; ++i)
546 float angle = M_PI/2. + i * 2*M_PI/3.;
547 VuoPoint3d_setArray(&m->positions[i * 3], (VuoPoint3d){ cos(angle) / sqrt(3), sin(angle) / sqrt(3), 0 });
551 for (
int i = 0; i < m->vertexCount; ++i)
576 static VuoMesh sharedQuadWithNormals;
577 static dispatch_once_t token = 0;
578 dispatch_once(&token, ^{
582 return sharedQuadWithNormals;
594 static VuoMesh sharedQuadWithoutNormals;
595 static dispatch_once_t token = 0;
596 dispatch_once(&token, ^{
600 return sharedQuadWithoutNormals;
610 static VuoMesh sharedEquilateralTriangle;
611 static dispatch_once_t token = 0;
612 dispatch_once(&token, ^{
616 return sharedEquilateralTriangle;
626 VuoPoint3d positions[] = (VuoPoint3d[]){
659 VuoPoint3d normals[] = (VuoPoint3d[]){
692 VuoPoint2d textureCoordinates[] = (VuoPoint2d[]){
725 unsigned int elements[] = (
unsigned int[]){
746 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
747 m->vertexCount = 6 * 4;
748 m->elementCount = 6 * 6;
749 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
751 for (
int i = 0; i < m->vertexCount; ++i)
757 memcpy(m->elements, elements,
sizeof(elements));
771 static dispatch_once_t token = 0;
772 dispatch_once(&token, ^{
786 unsigned int vertexCount = rows * columns;
787 unsigned int triangleCount = (rows-1) * (columns-1) * 6;
789 float *positions, *normals, *textureCoordinates;
790 unsigned int *elements;
793 unsigned int index = 0, t_index = 0;
795 for(
unsigned int i = 0; i < rows; i++)
797 float y = (i/(float)(rows-1)) - .5;
799 for(
unsigned int n = 0; n < columns; n++)
801 float x = (n/(float)(columns-1)) - .5;
807 if(n < columns-1 && i < rows-1)
809 elements[t_index++] = index + columns;
810 elements[t_index++] = index;
811 elements[t_index++] = index + 1;
813 elements[t_index++] = index + 1;
814 elements[t_index++] = index + columns + 1;
815 elements[t_index++] = index + columns;
823 positions, normals, textureCoordinates, NULL,
834 return (elementCount / 3) * 3;
839 return elementCount < 3 ? 0 : elementCount;
843 return (elementCount / 2) * 2;
847 return elementCount < 2 ? 0 : elementCount;
855 VUserLog(
"Error: Unknown submesh element assembly method: %d", elementAssemblyMethod);
876 float *positionsFloat, *normals, *colorsFloat = NULL;
878 for (
unsigned long i = 0; i < positionCount; ++i)
880 VuoPoint2d xy = positionValues[i];
881 positionsFloat[i * 3 ] = xy.x;
882 positionsFloat[i * 3 + 1] = xy.y;
883 positionsFloat[i * 3 + 2] = 0;
886 normals[i * 3 + 1] = 0;
887 normals[i * 3 + 2] = 1;
891 float progress = (float)i /
MAX(1, positionCount - 1);
892 unsigned long colorIndex = round(progress * (colorCount - 1));
893 VuoColor c = colorValues[colorIndex];
894 colorsFloat[i * 4 ] = c.r * c.a;
895 colorsFloat[i * 4 + 1] = c.g * c.a;
896 colorsFloat[i * 4 + 2] = c.b * c.a;
897 colorsFloat[i * 4 + 3] = c.a;
902 positionsFloat, normals, NULL, colorsFloat,
903 0, NULL, elementAssemblyMethod);
924 float *positionsFloat, *normals, *colorsFloat = NULL;
926 for (
unsigned long i = 0; i < positionCount; ++i)
931 normals[i * 3 + 1] = 0;
932 normals[i * 3 + 2] = 1;
936 float progress = (float)i /
MAX(1, positionCount - 1);
937 unsigned long colorIndex = round(progress * (colorCount - 1));
938 VuoColor c = colorValues[colorIndex];
939 colorsFloat[i * 4 ] = c.r * c.a;
940 colorsFloat[i * 4 + 1] = c.g * c.a;
941 colorsFloat[i * 4 + 2] = c.b * c.a;
942 colorsFloat[i * 4 + 3] = c.a;
947 positionsFloat, normals, NULL, colorsFloat,
948 0, NULL, elementAssemblyMethod);
961 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
962 VuoMesh_internal *copiedMesh = VuoMesh_makeInternal();
963 copiedMesh->vertexCount = m->vertexCount;
964 copiedMesh->elementCount = m->elementCount;
968 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
969 copiedMesh->positions = (
float *)malloc(size);
970 memcpy(copiedMesh->positions, m->positions, size);
973 copiedMesh->positions = NULL;
977 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
978 copiedMesh->normals = (
float *)malloc(size);
979 memcpy(copiedMesh->normals, m->normals, size);
982 copiedMesh->normals = NULL;
984 if (m->textureCoordinates)
986 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
987 copiedMesh->textureCoordinates = (
float *)malloc(size);
988 memcpy(copiedMesh->textureCoordinates, m->textureCoordinates, size);
991 copiedMesh->textureCoordinates = NULL;
995 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
996 copiedMesh->colors = (
float *)malloc(size);
997 memcpy(copiedMesh->colors, m->colors, size);
1000 copiedMesh->colors = NULL;
1002 copiedMesh->elementCount = m->elementCount;
1005 unsigned long elementByteCount =
sizeof(
unsigned int)*m->elementCount;
1006 copiedMesh->elements = (
unsigned int *)malloc(elementByteCount);
1007 memcpy(copiedMesh->elements, m->elements, elementByteCount);
1010 copiedMesh->elements = NULL;
1012 copiedMesh->elementAssemblyMethod = m->elementAssemblyMethod;
1013 copiedMesh->primitiveSize = m->primitiveSize;
1014 copiedMesh->faceCulling = m->faceCulling;
1016 memcpy(&copiedMesh->glUpload, &m->glUpload,
sizeof(copiedMesh->glUpload));
1038 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1039 VuoMesh_internal *copiedMesh = VuoMesh_makeInternal();
1041 copiedMesh->vertexCount = m->vertexCount;
1042 copiedMesh->elementCount = m->elementCount;
1044 copiedMesh->elementAssemblyMethod = m->elementAssemblyMethod;
1045 copiedMesh->primitiveSize = m->primitiveSize;
1046 copiedMesh->faceCulling = m->faceCulling;
1048 memcpy(&copiedMesh->glUpload, &m->glUpload,
sizeof(copiedMesh->glUpload));
1065 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1066 if (m->textureCoordinates)
1068 free(m->textureCoordinates);
1069 m->textureCoordinates = NULL;
1072 if (m->glUpload.combinedBuffer && m->glUpload.textureCoordinateOffset)
1074 m->glUpload.textureCoordinateOffset = NULL;
1092 float **positions,
float **normals,
float **textureCoordinates,
float **colors,
1093 unsigned int *elementCount,
unsigned int **elements)
1098 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1101 *vertexCount = m->vertexCount;
1103 *positions = m->positions;
1105 *normals = m->normals;
1106 if (textureCoordinates)
1107 *textureCoordinates = m->textureCoordinates;
1109 *colors = m->colors;
1111 *elementCount = m->elementCount;
1113 *elements = m->elements;
1124 unsigned int *combinedBuffer,
1125 void **normalOffset,
void **textureCoordinateOffset,
void **colorOffset,
1126 unsigned int *elementCount,
unsigned int *elementBuffer)
1131 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1134 *vertexCount = m->vertexCount;
1136 *combinedBuffer = m->glUpload.combinedBuffer;
1138 *normalOffset = m->glUpload.normalOffset;
1139 if (textureCoordinateOffset)
1140 *textureCoordinateOffset = m->glUpload.textureCoordinateOffset;
1142 *colorOffset = m->glUpload.colorOffset;
1144 *elementCount = m->elementCount;
1146 *elementBuffer = m->glUpload.elementBuffer;
1159 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1160 return m->elementAssemblyMethod;
1173 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1174 return m->faceCulling;
1187 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1206 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1207 return m->primitiveSize;
1220 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1221 return m->glUpload.elementBufferSize;
1233 float *positions,
float *normals,
float *textureCoordinates,
float *colors,
1234 unsigned int elementCount,
unsigned int *elements)
1239 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1241 m->vertexCount = vertexCount;
1243 if (m->positions != positions)
1246 m->positions = positions;
1249 if (m->normals != normals)
1252 m->normals = normals;
1255 if (m->textureCoordinates != textureCoordinates)
1257 free(m->textureCoordinates);
1258 m->textureCoordinates = textureCoordinates;
1261 if (m->colors != colors)
1267 m->elementCount = elementCount;
1269 if (m->elements != elements)
1272 m->elements = elements;
1275 VuoGlPool_release(VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize, m->glUpload.combinedBuffer);
1276 VuoGlPool_release(VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize, m->glUpload.elementBuffer);
1277 m->glUpload.combinedBufferSize = 0;
1278 m->glUpload.combinedBuffer = 0;
1279 m->glUpload.elementBufferSize = 0;
1280 m->glUpload.elementBuffer = 0;
1295 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1296 m->faceCulling = faceCulling;
1309 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1310 m->primitiveSize = primitiveSize;
1319 if (strcmp(elementAssemblyMethodString,
"individualTriangles")==0)
1321 else if (strcmp(elementAssemblyMethodString,
"triangleStrip")==0)
1323 else if (strcmp(elementAssemblyMethodString,
"triangleFan")==0)
1325 else if (strcmp(elementAssemblyMethodString,
"individualLines")==0)
1327 else if (strcmp(elementAssemblyMethodString,
"lineStrip")==0)
1329 else if (strcmp(elementAssemblyMethodString,
"points")==0)
1342 switch (elementAssemblyMethod)
1345 return "individualTriangles";
1347 return "triangleStrip";
1349 return "triangleFan";
1351 return "individualLines";
1364 if (!m->glUpload.combinedBuffer
1366 && (m->normals || !m->glUpload.normalOffset)
1367 && (m->textureCoordinates || !m->glUpload.textureCoordinateOffset)
1368 && (m->colors || !m->glUpload.colorOffset)
1369 && (m->elements || !m->glUpload.elementBuffer)))
1373 glBindBuffer(GL_ARRAY_BUFFER, m->glUpload.combinedBuffer);
1378 float *vertexData = (
float *)malloc(m->glUpload.combinedBufferSize);
1379 glGetBufferSubData(GL_ARRAY_BUFFER, 0, m->glUpload.combinedBufferSize, vertexData);
1380 glBindBuffer(GL_ARRAY_BUFFER, 0);
1384 m->positions = (
float *)malloc(
sizeof(
float) * 3 * m->vertexCount);
1385 memcpy(m->positions, vertexData,
sizeof(
float) * 3 * m->vertexCount);
1388 if (!m->normals && m->glUpload.normalOffset)
1390 m->normals = (
float *)malloc(
sizeof(
float) * 3 * m->vertexCount);
1391 memcpy(m->normals, (
char *)vertexData + (
int)m->glUpload.normalOffset,
sizeof(
float) * 3 * m->vertexCount);
1394 if (!m->textureCoordinates && m->glUpload.textureCoordinateOffset)
1396 m->textureCoordinates = (
float *)malloc(
sizeof(
float) * 2 * m->vertexCount);
1397 memcpy(m->textureCoordinates, (
char *)vertexData + (
int)m->glUpload.textureCoordinateOffset,
sizeof(
float) * 2 * m->vertexCount);
1400 if (!m->colors && m->glUpload.colorOffset)
1402 m->colors = (
float *)malloc(
sizeof(
float) * 4 * m->vertexCount);
1403 memcpy(m->colors, (
char *)vertexData + (
int)m->glUpload.colorOffset,
sizeof(
float) * 4 * m->vertexCount);
1406 if (!m->elements && m->glUpload.elementBuffer)
1408 m->elements = malloc(m->glUpload.elementBufferSize);
1409 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->glUpload.elementBuffer);
1410 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m->glUpload.elementBufferSize, m->elements);
1411 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1422 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1424 VuoPoint3d min, max;
1427 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1428 unsigned int vertexCount = m->vertexCount;
1432 if(vertexCount > 0 && !init)
1438 for(
int n = 0; n < vertexCount; n++)
1442 min.x =
MIN(p.x, min.x);
1443 min.y =
MIN(p.y, min.y);
1444 min.z =
MIN(p.z, min.z);
1446 max.x =
MAX(p.x, max.x);
1447 max.y =
MAX(p.y, max.y);
1448 max.z =
MAX(p.z, max.z);
1455 return VuoBox_make((min + max) / (VuoPoint3d)(2.), max - min);
1457 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1468 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1469 return m->vertexCount > 0;
1482 if (json_object_object_get_ex(js,
"pointer", &o))
1483 return (
VuoMesh)json_object_get_int64(o);
1498 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value));
1518 return strdup(
"Empty mesh");
1520 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1522 if (!m->vertexCount)
1523 return strdup(
"Mesh without any vertices");
1526 const char * objectString =
"";
1527 const char * assemblyMethod =
" (unknown element assembly method)";
1530 assemblyMethod =
", ";
1531 objectString =
"triangle";
1536 assemblyMethod =
" in a strip of ";
1537 objectString =
"triangle";
1541 assemblyMethod =
" in a fan of ";
1542 objectString =
"triangle";
1546 assemblyMethod =
", ";
1547 objectString =
"line";
1551 assemblyMethod =
" in a strip of ";
1552 objectString =
"line";
1556 assemblyMethod =
", ";
1557 objectString =
"point";
1560 const char * vertexCountString = m->vertexCount==1 ?
"vertex" :
"vertices";
1561 const char * objectStringPlural = objectCount==1 ?
"" :
"s";
1563 char *firstPosition = NULL;
1567 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>",
1568 m->vertexCount, vertexCountString, assemblyMethod, objectCount, objectString, objectStringPlural,
1569 firstPosition ? firstPosition :
"",
1570 (m->positions || m->glUpload.combinedBuffer ) ?
"✓" :
"◻",
1571 (m->normals || m->glUpload.normalOffset ) ?
"✓" :
"◻",
1572 (m->textureCoordinates || m->glUpload.textureCoordinateOffset) ?
"✓" :
"◻",
1573 (m->colors || m->glUpload.colorOffset ) ?
"✓" :
"◻");
1575 free(firstPosition);