12 #include <OpenGL/CGLMacro.h>
24 "title" :
"Scene Object",
25 "description" :
"A 3D Object: visible (mesh), or virtual (group, light, camera).",
40 "VuoList_VuoSceneObject"
53 static uint64_t
id = 0;
54 return __sync_add_and_fetch(&
id, 1);
65 o.type = VuoSceneObjectSubType_Empty;
73 o.childObjects = NULL;
79 o.font = (
VuoFont){NULL, 0,
false, (
VuoColor){0,0,0,0}, VuoHorizontalAlignment_Left, 0, 0};
80 o.scaleWithScene =
false;
81 o.wrapWidth = INFINITY;
94 o.type = VuoSceneObjectSubType_Group;
102 o.childObjects = childObjects;
105 o.transform = transform;
108 o.font = (
VuoFont){NULL, 0,
false, (
VuoColor){0,0,0,0}, VuoHorizontalAlignment_Left, 0, 0};
109 o.scaleWithScene =
false;
110 o.wrapWidth = INFINITY;
123 o.type = VuoSceneObjectSubType_Mesh;
136 o.childObjects = childObjects;
140 o.transform = transform;
143 o.font = (
VuoFont){NULL, 0,
false, (
VuoColor){0,0,0,0}, VuoHorizontalAlignment_Left, 0, 0};
144 o.scaleWithScene =
false;
145 o.wrapWidth = INFINITY;
344 o.type = VuoSceneObjectSubType_Text;
347 o.scaleWithScene = scaleWithScene;
348 o.wrapWidth = wrapWidth;
358 o.type = VuoSceneObjectSubType_PerspectiveCamera;
360 o.transform = transform;
373 o.type = VuoSceneObjectSubType_StereoCamera;
375 o.transform = transform;
390 o.type = VuoSceneObjectSubType_OrthographicCamera;
392 o.transform = transform;
405 o.type = VuoSceneObjectSubType_FisheyeCamera;
407 o.transform = transform;
459 for (
unsigned long i = 1; i <= childObjectCount; ++i)
483 if (so.
id == idToMatch)
492 for (
unsigned long i = 1; i <= childObjectCount; ++i)
516 if (so.type == typeToMatch)
526 for (
unsigned long i = 1; i <= childObjectCount; ++i)
549 __block
bool didFindCamera =
false;
551 if ((currentObject->type == VuoSceneObjectSubType_PerspectiveCamera
552 || currentObject->type == VuoSceneObjectSubType_StereoCamera
553 || currentObject->type == VuoSceneObjectSubType_OrthographicCamera
554 || currentObject->type == VuoSceneObjectSubType_FisheyeCamera)
555 && (!nameToMatch || (currentObject->name && nameToMatch && strstr(currentObject->name, nameToMatch))))
557 *foundCamera = *currentObject;
558 foundCamera->transform = VuoTransform_makeFromMatrix4x4(modelviewMatrix);
559 didFindCamera = true;
565 return didFindCamera;
575 if (so.type != VuoSceneObjectSubType_Empty)
581 for (
unsigned long i = 1; i <= childObjectCount; ++i)
597 if (strcmp(typeString,
"empty")==0)
598 return VuoSceneObjectSubType_Empty;
599 else if (strcmp(typeString,
"group")==0)
600 return VuoSceneObjectSubType_Group;
601 else if (strcmp(typeString,
"mesh")==0)
602 return VuoSceneObjectSubType_Mesh;
603 else if (strcmp(typeString,
"camera-perspective")==0)
604 return VuoSceneObjectSubType_PerspectiveCamera;
605 else if (strcmp(typeString,
"camera-stereo")==0)
606 return VuoSceneObjectSubType_StereoCamera;
607 else if (strcmp(typeString,
"camera-orthographic")==0)
608 return VuoSceneObjectSubType_OrthographicCamera;
609 else if (strcmp(typeString,
"camera-fisheye")==0)
610 return VuoSceneObjectSubType_FisheyeCamera;
611 else if (strcmp(typeString,
"light-ambient")==0)
612 return VuoSceneObjectSubType_AmbientLight;
613 else if (strcmp(typeString,
"light-point")==0)
614 return VuoSceneObjectSubType_PointLight;
615 else if (strcmp(typeString,
"light-spot")==0)
616 return VuoSceneObjectSubType_Spotlight;
617 else if (strcmp(typeString,
"text")==0)
618 return VuoSceneObjectSubType_Text;
620 return VuoSceneObjectSubType_Empty;
630 case VuoSceneObjectSubType_Group:
632 case VuoSceneObjectSubType_Mesh:
634 case VuoSceneObjectSubType_PerspectiveCamera:
635 return "camera-perspective";
636 case VuoSceneObjectSubType_StereoCamera:
637 return "camera-stereo";
638 case VuoSceneObjectSubType_OrthographicCamera:
639 return "camera-orthographic";
640 case VuoSceneObjectSubType_FisheyeCamera:
641 return "camera-fisheye";
642 case VuoSceneObjectSubType_AmbientLight:
643 return "light-ambient";
644 case VuoSceneObjectSubType_PointLight:
645 return "light-point";
646 case VuoSceneObjectSubType_Spotlight:
648 case VuoSceneObjectSubType_Text:
664 o.type = VuoSceneObjectSubType_AmbientLight;
665 o.lightColor = color;
666 o.lightBrightness = brightness;
684 o.type = VuoSceneObjectSubType_PointLight;
685 o.lightColor = color;
686 o.lightBrightness = brightness;
708 o.type = VuoSceneObjectSubType_Spotlight;
709 o.lightColor = color;
710 o.lightBrightness = brightness;
714 o.transform = transform;
730 *ambientBrightness = 0;
735 if (currentObject->type == VuoSceneObjectSubType_AmbientLight)
737 VuoListAppendValue_VuoColor(ambientColors, currentObject->lightColor);
738 *ambientBrightness += currentObject->lightBrightness;
740 else if (currentObject->type == VuoSceneObjectSubType_PointLight)
742 VuoSceneObject l = *currentObject;
743 l.transform = VuoTransform_makeFromMatrix4x4(modelviewMatrix);
744 VuoListAppendValue_VuoSceneObject(*pointLights, l);
746 else if (currentObject->type == VuoSceneObjectSubType_Spotlight)
748 VuoSceneObject l = *currentObject;
749 l.transform = VuoTransform_makeFromMatrix4x4(modelviewMatrix);
750 VuoListAppendValue_VuoSceneObject(*spotLights, l);
760 *ambientBrightness = 0.05;
786 float modelviewMatrix[16];
802 rootState.objectCount = 1;
803 rootState.objects = &object;
806 std::list<VuoSceneObject_treeState> objectsToVisit(1, rootState);
807 while (!objectsToVisit.empty())
810 objectsToVisit.pop_front();
812 for (
long i = 0; i < currentState.objectCount; ++i)
814 float localModelviewMatrix[16];
816 float compositeModelviewMatrix[16];
819 if (!
function(¤tState.objects[i], compositeModelviewMatrix))
824 if (childObjectCount)
827 childState.objectCount = childObjectCount;
829 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
830 objectsToVisit.push_front(childState);
841 float localModelviewMatrix[16];
843 float compositeModelviewMatrix[16];
846 function(object, compositeModelviewMatrix);
848 if (object->childObjects)
851 for (
unsigned long i = 1; i <= childObjectCount; ++i)
869 float localModelviewMatrix[16];
885 if (currentObject->mesh)
886 for (
unsigned long i = 0; i < currentObject->mesh->
submeshCount; ++i)
906 currentObject->blendMode = blendMode;
925 if (
object.childObjects)
929 for (
unsigned long i = 1; i <= childObjectCount; ++i)
943 __block
bool haveGlobalBounds =
false;
944 __block
VuoBox globalBounds;
952 haveGlobalBounds =
true;
957 if (haveGlobalBounds)
960 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
972 || so.type == VuoSceneObjectSubType_Text)
1011 float scale = fmax(fmax(bounds.size.x, bounds.size.y), bounds.size.z);
1012 if (fabs(scale) < 0.00001)
1049 if (json_object_object_get_ex(js,
"id", &o))
1050 id = json_object_get_int64(o);
1053 if (json_object_object_get_ex(js,
"type", &o))
1057 if (json_object_object_get_ex(js,
"mesh", &o))
1061 if (json_object_object_get_ex(js,
"shader", &o))
1064 bool isRealSize =
false;
1065 if (json_object_object_get_ex(js,
"isRealSize", &o))
1068 bool preservePhysicalSize =
false;
1069 if (json_object_object_get_ex(js,
"preservePhysicalSize", &o))
1073 if (json_object_object_get_ex(js,
"blendMode", &o))
1077 if (json_object_object_get_ex(js,
"childObjects", &o))
1080 float cameraFieldOfView;
1081 if (json_object_object_get_ex(js,
"cameraFieldOfView", &o))
1082 cameraFieldOfView = json_object_get_double(o);
1085 if (json_object_object_get_ex(js,
"cameraWidth", &o))
1086 cameraWidth = json_object_get_double(o);
1088 float cameraDistanceMin;
1089 if (json_object_object_get_ex(js,
"cameraDistanceMin", &o))
1090 cameraDistanceMin = json_object_get_double(o);
1092 float cameraDistanceMax;
1093 if (json_object_object_get_ex(js,
"cameraDistanceMax", &o))
1094 cameraDistanceMax = json_object_get_double(o);
1096 float cameraConfocalDistance;
1097 if (json_object_object_get_ex(js,
"cameraConfocalDistance", &o))
1098 cameraConfocalDistance = json_object_get_double(o);
1100 float cameraIntraocularDistance;
1101 if (json_object_object_get_ex(js,
"cameraIntraocularDistance", &o))
1102 cameraIntraocularDistance = json_object_get_double(o);
1104 float cameraVignetteWidth;
1105 if (json_object_object_get_ex(js,
"cameraVignetteWidth", &o))
1106 cameraVignetteWidth = json_object_get_double(o);
1108 float cameraVignetteSharpness;
1109 if (json_object_object_get_ex(js,
"cameraVignetteSharpness", &o))
1110 cameraVignetteSharpness = json_object_get_double(o);
1113 if (json_object_object_get_ex(js,
"lightColor", &o))
1116 float lightBrightness;
1117 if (json_object_object_get_ex(js,
"lightBrightness", &o))
1118 lightBrightness = json_object_get_double(o);
1121 if (json_object_object_get_ex(js,
"lightCone", &o))
1122 lightCone = json_object_get_double(o);
1125 if (json_object_object_get_ex(js,
"lightRange", &o))
1126 lightRange = json_object_get_double(o);
1128 float lightSharpness;
1129 if (json_object_object_get_ex(js,
"lightSharpness", &o))
1130 lightSharpness = json_object_get_double(o);
1133 if (json_object_object_get_ex(js,
"name", &o))
1136 json_object_object_get_ex(js,
"transform", &o);
1140 if (json_object_object_get_ex(js,
"text", &o))
1144 if (json_object_object_get_ex(js,
"font", &o))
1147 bool scaleWithScene =
false;
1148 if (json_object_object_get_ex(js,
"scaleWithScene", &o))
1151 float wrapWidth = INFINITY;
1152 if (json_object_object_get_ex(js,
"wrapWidth", &o))
1153 wrapWidth = json_object_get_double(o);
1158 case VuoSceneObjectSubType_Empty:
1161 case VuoSceneObjectSubType_Group:
1164 case VuoSceneObjectSubType_Mesh:
1168 obj.blendMode = blendMode;
1171 case VuoSceneObjectSubType_PerspectiveCamera:
1180 case VuoSceneObjectSubType_StereoCamera:
1187 cameraConfocalDistance,
1188 cameraIntraocularDistance
1191 case VuoSceneObjectSubType_OrthographicCamera:
1200 case VuoSceneObjectSubType_FisheyeCamera:
1205 cameraVignetteWidth,
1206 cameraVignetteSharpness
1209 case VuoSceneObjectSubType_AmbientLight:
1212 case VuoSceneObjectSubType_PointLight:
1215 case VuoSceneObjectSubType_Spotlight:
1218 case VuoSceneObjectSubType_Text:
1220 obj.transform = transform;
1237 json_object_object_add(js,
"id", json_object_new_int64(value.
id));
1242 case VuoSceneObjectSubType_Empty:
1245 case VuoSceneObjectSubType_Group:
1246 case VuoSceneObjectSubType_Mesh:
1251 json_object_object_add(js,
"mesh", meshObject);
1257 json_object_object_add(js,
"shader", shaderObject);
1261 json_object_object_add(js,
"isRealSize", isRealSizeObject);
1264 json_object_object_add(js,
"preservePhysicalSize", preservePhysicalSizeObject);
1269 json_object_object_add(js,
"blendMode", blendModeObject);
1272 if (value.childObjects)
1275 json_object_object_add(js,
"childObjects", childObjectsObject);
1281 case VuoSceneObjectSubType_PerspectiveCamera:
1282 case VuoSceneObjectSubType_StereoCamera:
1283 case VuoSceneObjectSubType_OrthographicCamera:
1284 case VuoSceneObjectSubType_FisheyeCamera:
1286 if (value.type != VuoSceneObjectSubType_FisheyeCamera)
1288 json_object_object_add(js,
"cameraDistanceMin", json_object_new_double(value.
cameraDistanceMin));
1289 json_object_object_add(js,
"cameraDistanceMax", json_object_new_double(value.
cameraDistanceMax));
1292 if (value.type == VuoSceneObjectSubType_PerspectiveCamera
1293 || value.type == VuoSceneObjectSubType_StereoCamera
1294 || value.type == VuoSceneObjectSubType_FisheyeCamera)
1295 json_object_object_add(js,
"cameraFieldOfView", json_object_new_double(value.
cameraFieldOfView));
1297 if (value.type == VuoSceneObjectSubType_StereoCamera)
1299 json_object_object_add(js,
"cameraConfocalDistance", json_object_new_double(value.
cameraConfocalDistance));
1303 if (value.type == VuoSceneObjectSubType_OrthographicCamera)
1304 json_object_object_add(js,
"cameraWidth", json_object_new_double(value.
cameraWidth));
1306 if (value.type == VuoSceneObjectSubType_FisheyeCamera)
1308 json_object_object_add(js,
"cameraVignetteWidth", json_object_new_double(value.
cameraVignetteWidth));
1315 case VuoSceneObjectSubType_AmbientLight:
1316 case VuoSceneObjectSubType_PointLight:
1317 case VuoSceneObjectSubType_Spotlight:
1319 json_object_object_add(js,
"lightColor",
VuoColor_getJson(value.lightColor));
1320 json_object_object_add(js,
"lightBrightness", json_object_new_double(value.lightBrightness));
1322 if (value.type == VuoSceneObjectSubType_PointLight
1323 || value.type == VuoSceneObjectSubType_Spotlight)
1325 json_object_object_add(js,
"lightRange", json_object_new_double(value.
lightRange));
1326 json_object_object_add(js,
"lightSharpness", json_object_new_double(value.
lightSharpness));
1328 if (value.type == VuoSceneObjectSubType_Spotlight)
1329 json_object_object_add(js,
"lightCone", json_object_new_double(value.
lightCone));
1334 case VuoSceneObjectSubType_Text:
1339 json_object_object_add(js,
"text", textObject);
1343 json_object_object_add(js,
"font", fontObject);
1348 json_object_object_add(js,
"mesh", meshObject);
1351 json_object_object_add(js,
"scaleWithScene",
VuoBoolean_getJson(value.scaleWithScene));
1352 json_object_object_add(js,
"wrapWidth",
VuoReal_getJson(value.wrapWidth));
1361 json_object_object_add(js,
"name", nameObject);
1364 if (value.type != VuoSceneObjectSubType_AmbientLight)
1367 json_object_object_add(js,
"transform", transformObject);
1381 unsigned long vertexCount = 0;
1382 for (
unsigned int i = 0; i < value.mesh->
submeshCount; ++i)
1396 unsigned long elementCount = 0;
1397 for (
unsigned int i = 0; i < value.mesh->
submeshCount; ++i)
1400 return elementCount;
1410 unsigned long childObjectCount = 0;
1411 if (value.childObjects)
1413 *descendantCount += childObjectCount;
1417 for (
unsigned long i = 1; i <= childObjectCount; ++i)
1427 __block
json_object *names = json_object_new_object();
1429 if (currentObject->shader)
1430 json_object_object_add(names, currentObject->shader->
name, NULL);
1435 json_object_object_foreach(names, key, val)
1437 json_object_put(names);
1446 if (value.type == VuoSceneObjectSubType_Text)
1449 char *textSummary =
VuoText_format(
"<div>\"%s\"</div><div>%sat (%g,%g)</div><div>id %llu</div>", value.text, fontSummary, value.transform.translation.x, value.transform.translation.y, value.
id);
1454 if (value.type == VuoSceneObjectSubType_PerspectiveCamera
1455 || value.type == VuoSceneObjectSubType_StereoCamera
1456 || value.type == VuoSceneObjectSubType_OrthographicCamera
1457 || value.type == VuoSceneObjectSubType_FisheyeCamera)
1461 float cameraViewValue = 0;
1462 const char *cameraViewString =
"";
1463 if (value.type == VuoSceneObjectSubType_PerspectiveCamera)
1466 cameraViewString =
"° field of view";
1468 else if (value.type == VuoSceneObjectSubType_StereoCamera)
1471 cameraViewString =
"° field of view (stereoscopic)";
1473 else if (value.type == VuoSceneObjectSubType_OrthographicCamera)
1476 cameraViewString =
" unit width";
1478 else if (value.type == VuoSceneObjectSubType_FisheyeCamera)
1481 cameraViewString =
"° field of view (fisheye)";
1486 const char *rotationLabel;
1487 char *rotationString;
1488 if (value.transform.type == VuoTransformTypeEuler)
1490 rotationLabel =
"rotated";
1495 rotationLabel =
"target";
1499 char *valueAsString =
VuoText_format(
"<div>%s named \"%s\"</div><div>at (%s)</div><div>%s (%s)</div><div>%g%s</div><div>shows objects between depth %g and %g</div>",
1500 type, value.name ? value.name :
"",
1502 rotationLabel, rotationString,
1503 cameraViewValue, cameraViewString,
1505 free(rotationString);
1506 free(translationString);
1507 return valueAsString;
1510 if (value.type == VuoSceneObjectSubType_AmbientLight
1511 || value.type == VuoSceneObjectSubType_PointLight
1512 || value.type == VuoSceneObjectSubType_Spotlight)
1517 char *positionRangeString;
1518 if (value.type == VuoSceneObjectSubType_PointLight
1519 || value.type == VuoSceneObjectSubType_Spotlight)
1523 positionRangeString =
VuoText_format(
"<div>position (%s)</div><div>range %g units (%g sharpness)</div>",
1526 free(positionString);
1529 positionRangeString = strdup(
"");
1531 char *directionConeString;
1532 if (value.type == VuoSceneObjectSubType_Spotlight)
1537 directionConeString =
VuoText_format(
"<div>direction (%s)</div><div>cone %g°</div>",
1538 directionString, value.
lightCone * 180./M_PI);
1540 free(directionString);
1543 directionConeString = strdup(
"");
1545 char *valueAsString =
VuoText_format(
"<div>%s</div><div>color %s</div><div>brightness %g</div>%s%s",
1546 type, colorString, value.lightBrightness, positionRangeString, directionConeString);
1548 free(directionConeString);
1549 free(positionRangeString);
1552 return valueAsString;
1560 unsigned long childObjectCount = 0;
1561 if (value.childObjects)
1563 const char *childObjectPlural = childObjectCount == 1 ?
"" :
"s";
1566 if (childObjectCount)
1568 unsigned long descendantCount = 0;
1569 unsigned long totalVertexCount = 0;
1570 unsigned long totalElementCount = 0;
1572 const char *descendantPlural = descendantCount == 1 ?
"" :
"s";
1574 descendants =
VuoText_format(
"<div>%ld descendant%s</div><div>total, including descendants:</div><div>%ld vertices, %ld elements</div>",
1575 descendantCount, descendantPlural, totalVertexCount, totalElementCount);
1578 descendants = strdup(
"");
1582 char *shaderNamesSummary;
1586 const char *header =
"<div>shaders:<ul>";
1587 VuoInteger shaderNameLength = strlen(header);
1588 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
1590 shaderNameLength += strlen(
"</ul></div>");
1592 shaderNamesSummary = (
char *)malloc(shaderNameLength + 1);
1593 char *t = shaderNamesSummary;
1594 t = strcpy(t, header) + strlen(header);
1595 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
1597 t = strcpy(t,
"<li>") + strlen(
"<li>");
1599 t = strcpy(t,
"</li>") + strlen(
"</li>");
1601 t = strcpy(t,
"</ul></div>");
1604 shaderNamesSummary = strdup(
"");
1607 char *valueAsString =
VuoText_format(
"<div>object named \"%s\"</div><div>%ld vertices, %ld elements</div><div>%s</div><div>id %lld</div><div>%ld child object%s</div>%s%s",
1608 value.name ? value.name :
"",
1609 vertexCount, elementCount,
1612 childObjectCount, childObjectPlural,
1613 descendants, shaderNamesSummary);
1617 free(shaderNamesSummary);
1619 return valueAsString;
1627 for (
unsigned int i=0; i<level; ++i)
1628 fprintf(stderr,
"\t");
1631 if (so.type == VuoSceneObjectSubType_Mesh)
1633 fprintf(stderr,
"\n");
1635 if (so.childObjects)
1638 for (
unsigned int i=1; i<=childObjectCount; ++i)
1665 __block
unsigned long triangleVertexCount = 0;
1666 __block
unsigned long trianglePrimitiveCount = 0;
1667 __block
unsigned int triangleFaceCullingMode = GL_BACK;
1669 __block
unsigned long lineVertexCount = 0;
1670 __block
unsigned long linePrimitiveCount = 0;
1671 __block
double linePrimitiveSize = 0;
1673 __block
unsigned long pointVertexCount = 0;
1674 __block
unsigned long pointPrimitiveCount = 0;
1675 __block
double pointPrimitiveSize = 0;
1678 if (!currentObject->mesh)
1681 for (
unsigned int i = 0; i < currentObject->mesh->
submeshCount; ++i)
1688 triangleVertexCount += submesh.vertexCount;
1689 trianglePrimitiveCount += VuoSubmesh_getSplitPrimitiveCount(submesh);
1690 triangleFaceCullingMode = submesh.faceCullingMode;
1695 lineVertexCount += submesh.vertexCount;
1696 linePrimitiveCount += VuoSubmesh_getSplitPrimitiveCount(submesh);
1697 linePrimitiveSize = submesh.primitiveSize;
1701 pointVertexCount += submesh.vertexCount;
1702 pointPrimitiveCount += VuoSubmesh_getSplitPrimitiveCount(submesh);
1703 pointPrimitiveSize = submesh.primitiveSize;
1713 int submeshCount = 0;
1714 if (trianglePrimitiveCount)
1716 triangleSubmesh =
VuoSubmesh_make(triangleVertexCount, trianglePrimitiveCount * 3);
1718 triangleSubmesh.faceCullingMode = triangleFaceCullingMode;
1721 if (linePrimitiveCount)
1723 lineSubmesh =
VuoSubmesh_make(lineVertexCount, linePrimitiveCount * 2);
1728 if (pointPrimitiveCount)
1730 pointSubmesh =
VuoSubmesh_make(pointVertexCount, pointPrimitiveCount);
1735 if (!trianglePrimitiveCount && !linePrimitiveCount && !pointPrimitiveCount)
1740 __block
unsigned long triangleVertexIndex = 0;
1741 __block
unsigned long triangleElementIndex = 0;
1742 __block
unsigned long lineVertexIndex = 0;
1743 __block
unsigned long lineElementIndex = 0;
1744 __block
unsigned long pointVertexIndex = 0;
1745 __block
unsigned long pointElementIndex = 0;
1746 __block
bool anyTextureCoordinates =
false;
1748 if (!currentObject->mesh)
1751 for (
unsigned int i = 0; i < currentObject->mesh->
submeshCount; ++i)
1759 anyTextureCoordinates =
true;
1765 unsigned long indexOffset = triangleVertexIndex;
1766 for (unsigned int n = 0; n < submesh.vertexCount; ++n)
1768 VuoPoint3d p = (VuoPoint3d){submesh.positions[n].x, submesh.positions[n].y, submesh.positions[n].z};
1769 VuoPoint3d pt = VuoTransform_transformPoint((float*)modelviewMatrix, p);
1770 triangleSubmesh.positions[triangleVertexIndex] = (VuoPoint4d){pt.x, pt.y, pt.z, 1};
1772 if (submesh.normals)
1774 VuoPoint3d r = (VuoPoint3d){submesh.normals[n].x, submesh.normals[n].y, submesh.normals[n].z};
1775 VuoPoint3d rt = VuoTransform_transformVector((float*)modelviewMatrix, r);
1776 triangleSubmesh.normals[triangleVertexIndex] = (VuoPoint4d){rt.x, rt.y, rt.z, 1};
1779 if (submesh.textureCoordinates)
1780 triangleSubmesh.textureCoordinates[triangleVertexIndex] = submesh.textureCoordinates[n];
1782 ++triangleVertexIndex;
1787 if (submesh.elementCount)
1788 for (unsigned int n = 0; n < submesh.elementCount; ++n)
1789 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n];
1791 for (unsigned int n = 0; n < submesh.vertexCount; ++n)
1792 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n;
1797 if (submesh.elementCount)
1798 for (unsigned int n = 2; n < submesh.elementCount; ++n)
1801 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n-2];
1802 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n-1];
1803 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n ];
1807 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n-1];
1808 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n-2];
1809 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n ];
1812 for (
unsigned int n = 0; n < submesh.
vertexCount; ++n)
1815 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n-2;
1816 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n-1;
1817 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n ;
1821 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n-1;
1822 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n-2;
1823 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n ;
1829 if (submesh.elementCount)
1830 for (unsigned int n = 2; n < submesh.elementCount; ++n)
1832 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[0 ];
1833 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n-1];
1834 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + submesh.elements[n ];
1837 for (
unsigned int n = 2; n < submesh.vertexCount; ++n)
1839 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + 0;
1840 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n-1;
1841 triangleSubmesh.elements[triangleElementIndex++] = indexOffset + n;
1848 unsigned long indexOffset = lineVertexIndex;
1849 for (unsigned int n = 0; n < submesh.vertexCount; ++n)
1851 VuoPoint3d p = (VuoPoint3d){submesh.positions[n].x, submesh.positions[n].y, submesh.positions[n].z};
1852 VuoPoint3d pt = VuoTransform_transformPoint((float*)modelviewMatrix, p);
1853 lineSubmesh.positions[lineVertexIndex] = (VuoPoint4d){pt.x, pt.y, pt.z, 1};
1855 if (submesh.normals)
1857 VuoPoint3d r = (VuoPoint3d){submesh.normals[n].x, submesh.normals[n].y, submesh.normals[n].z};
1858 VuoPoint3d rt = VuoTransform_transformVector((float*)modelviewMatrix, r);
1859 lineSubmesh.normals[lineVertexIndex] = (VuoPoint4d){rt.x, rt.y, rt.z, 1};
1862 if (submesh.textureCoordinates)
1863 lineSubmesh.textureCoordinates[lineVertexIndex] = submesh.textureCoordinates[n];
1870 if (submesh.elementCount)
1871 for (unsigned int n = 0; n < submesh.elementCount; ++n)
1872 lineSubmesh.elements[lineElementIndex++] = indexOffset + submesh.elements[n];
1874 for (unsigned int n = 0; n < submesh.vertexCount; ++n)
1875 lineSubmesh.elements[lineElementIndex++] = indexOffset + n;
1880 if (submesh.elementCount)
1881 for (unsigned int n = 1; n < submesh.elementCount; ++n)
1883 lineSubmesh.elements[lineElementIndex++] = indexOffset + submesh.elements[n-1];
1884 lineSubmesh.elements[lineElementIndex++] = indexOffset + submesh.elements[n ];
1887 for (
unsigned int n = 1; n < submesh.vertexCount; ++n)
1889 lineSubmesh.elements[lineElementIndex++] = indexOffset + n-1;
1890 lineSubmesh.elements[lineElementIndex++] = indexOffset + n;
1896 unsigned long indexOffset = pointVertexIndex;
1897 for (unsigned int n = 0; n < submesh.vertexCount; ++n)
1899 VuoPoint3d p = (VuoPoint3d){submesh.positions[n].x, submesh.positions[n].y, submesh.positions[n].z};
1900 VuoPoint3d pt = VuoTransform_transformPoint((float*)modelviewMatrix, p);
1901 pointSubmesh.positions[pointVertexIndex] = (VuoPoint4d){pt.x, pt.y, pt.z, 1};
1903 if (submesh.normals)
1905 VuoPoint3d r = (VuoPoint3d){submesh.normals[n].x, submesh.normals[n].y, submesh.normals[n].z};
1906 VuoPoint3d rt = VuoTransform_transformVector((float*)modelviewMatrix, r);
1907 pointSubmesh.normals[pointVertexIndex] = (VuoPoint4d){rt.x, rt.y, rt.z, 1};
1910 if (submesh.textureCoordinates)
1911 pointSubmesh.textureCoordinates[pointVertexIndex] = submesh.textureCoordinates[n];
1916 if (submesh.elementCount)
1918 for (
unsigned int n = 0; n < submesh.elementCount; ++n)
1919 pointSubmesh.elements[pointElementIndex++] = indexOffset + submesh.elements[n];
1922 for (unsigned int n = 0; n < submesh.vertexCount; ++n)
1923 pointSubmesh.elements[pointElementIndex++] = indexOffset + n;
1932 int submeshIndex = 0;
1933 if (trianglePrimitiveCount)
1935 if (calculateTangents)
1937 if (!anyTextureCoordinates)
1939 free(triangleSubmesh.textureCoordinates);
1940 triangleSubmesh.textureCoordinates = NULL;
1942 mesh->submeshes[submeshIndex++] = triangleSubmesh;
1944 if (linePrimitiveCount)
1946 if (!anyTextureCoordinates)
1948 free(lineSubmesh.textureCoordinates);
1949 lineSubmesh.textureCoordinates = NULL;
1951 mesh->submeshes[submeshIndex++] = lineSubmesh;
1953 if (pointPrimitiveCount)
1955 if (!anyTextureCoordinates)
1957 free(pointSubmesh.textureCoordinates);
1958 pointSubmesh.textureCoordinates = NULL;
1960 mesh->submeshes[submeshIndex++] = pointSubmesh;
1966 #define CSGJS_HEADER_ONLY
1976 return csgjs_model();
1982 return csgjs_model();
1986 for (
unsigned int n = 0; n < submesh.
vertexCount; ++n)
1994 cm.vertices.push_back(v);
1996 for (
unsigned int n = 0; n < submesh.
elementCount; ++n)
1997 cm.indices.push_back(submesh.
elements[n]);
2009 const csgjs_vertex *vertex = &cm.vertices[0];
2010 for (
unsigned int n = 0; n < submesh.
vertexCount; ++n)
2012 submesh.
positions[n] = (VuoPoint4d){vertex[n].pos.x,vertex[n].pos.y,vertex[n].pos.z,1};
2013 submesh.
normals[n] = (VuoPoint4d){vertex[n].normal.x,vertex[n].normal.y,vertex[n].normal.z,1};
2014 submesh.
textureCoordinates[n] = (VuoPoint4d){vertex[n].uv.x,vertex[n].uv.y,vertex[n].uv.z,1};
2017 const int *index = &cm.indices[0];
2018 for (
unsigned int n = 0; n < submesh.
elementCount; ++n)
2044 if (objectCount == 0)
2046 if (objectCount == 1)
2049 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.union", DISPATCH_QUEUE_CONCURRENT);
2051 csgjs_model *models =
new csgjs_model[objectCount];
2052 for (
unsigned long i = 0; i < objectCount; ++i)
2053 dispatch_async(queue, ^{
2057 dispatch_barrier_sync(queue, ^{});
2058 dispatch_release(queue);
2060 csgjs_model cu = models[0];
2061 for (
unsigned long i = 1; i < objectCount; ++i)
2062 cu = csgjs_union(cu, models[i], epsilon);
2074 dispatch_semaphore_t finished = dispatch_semaphore_create(0);
2076 __block csgjs_model ca;
2077 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
2079 dispatch_semaphore_signal(finished);
2084 dispatch_semaphore_wait(finished, DISPATCH_TIME_FOREVER);
2085 dispatch_release(finished);
2087 csgjs_model d = csgjs_difference(ca, cb, epsilon);
2099 if (objectCount == 0)
2101 if (objectCount == 1)
2104 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.intersect", DISPATCH_QUEUE_CONCURRENT);
2106 csgjs_model *models =
new csgjs_model[objectCount];
2107 for (
unsigned long i = 0; i < objectCount; ++i)
2108 dispatch_async(queue, ^{
2112 dispatch_barrier_sync(queue, ^{});
2113 dispatch_release(queue);
2115 csgjs_model ci = models[0];
2116 for (
unsigned long i = 1; i < objectCount; ++i)
2117 ci = csgjs_intersection(ci, models[i], epsilon);