12 #include <OpenGL/CGLMacro.h>
24 "title" :
"Scene Object",
25 "description" :
"A 3D Object: visible (mesh), or virtual (group, light, camera).",
40 "VuoList_VuoSceneObject"
67 bool preservePhysicalSize;
80 float confocalDistance;
81 float intraocularDistance;
83 float vignetteSharpness;
103 } VuoSceneObject_internal;
111 static uint64_t
id = 0;
112 return __sync_add_and_fetch(&
id, 1);
122 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
127 if (so->type == VuoSceneObjectSubType_Group)
129 else if (so->type == VuoSceneObjectSubType_Text)
143 VuoSceneObject_internal *so = (VuoSceneObject_internal *)calloc(1,
sizeof(VuoSceneObject_internal));
147 so->type = VuoSceneObjectSubType_Empty;
151 so->isRealSize =
false;
152 so->preservePhysicalSize =
false;
168 so->type = VuoSceneObjectSubType_Group;
172 so->transform = transform;
184 so->type = VuoSceneObjectSubType_Mesh;
193 so->transform = transform;
376 so->type = VuoSceneObjectSubType_Text;
379 so->text.scaleWithScene = scaleWithScene;
380 so->text.wrapWidth = wrapWidth;
390 so->type = VuoSceneObjectSubType_PerspectiveCamera;
392 so->transform = transform;
393 so->camera.fieldOfView = fieldOfView;
394 so->camera.distanceMin = distanceMin;
395 so->camera.distanceMax = distanceMax;
405 so->type = VuoSceneObjectSubType_StereoCamera;
407 so->transform = transform;
408 so->camera.fieldOfView = fieldOfView;
409 so->camera.distanceMin = distanceMin;
410 so->camera.distanceMax = distanceMax;
411 so->camera.confocalDistance = confocalDistance;
412 so->camera.intraocularDistance = intraocularDistance;
422 so->type = VuoSceneObjectSubType_OrthographicCamera;
424 so->transform = transform;
425 so->camera.width = width;
426 so->camera.distanceMin = distanceMin;
427 so->camera.distanceMax = distanceMax;
437 so->type = VuoSceneObjectSubType_FisheyeCamera;
439 so->transform = transform;
440 so->camera.fieldOfView = fieldOfView;
443 so->camera.distanceMin = 0;
444 so->camera.distanceMax = 1000;
446 so->camera.vignetteWidth = vignetteWidth;
447 so->camera.vignetteSharpness = vignetteSharpness;
485 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
493 if (so->type == VuoSceneObjectSubType_Group)
498 for (
unsigned long i = 1; i <= childObjectCount; ++i)
526 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
528 if (so->id == idToMatch)
534 if (so->type == VuoSceneObjectSubType_Group)
539 for (
unsigned long i = 1; i <= childObjectCount; ++i)
567 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
569 if (so->type == typeToMatch)
575 if (so->type == VuoSceneObjectSubType_Group)
581 for (
unsigned long i = 1; i <= childObjectCount; ++i)
608 __block
bool didFindCamera =
false;
610 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
611 if ((co->type == VuoSceneObjectSubType_PerspectiveCamera
612 || co->type == VuoSceneObjectSubType_StereoCamera
613 || co->type == VuoSceneObjectSubType_OrthographicCamera
614 || co->type == VuoSceneObjectSubType_FisheyeCamera)
615 && (!nameToMatch || (co->name && nameToMatch && strstr(co->name, nameToMatch))))
617 *foundCamera = currentObject;
619 didFindCamera =
true;
625 return didFindCamera;
636 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
637 return so->type != VuoSceneObjectSubType_Empty;
645 if (strcmp(typeString,
"empty")==0)
646 return VuoSceneObjectSubType_Empty;
647 else if (strcmp(typeString,
"group")==0)
648 return VuoSceneObjectSubType_Group;
649 else if (strcmp(typeString,
"mesh")==0)
650 return VuoSceneObjectSubType_Mesh;
651 else if (strcmp(typeString,
"camera-perspective")==0)
652 return VuoSceneObjectSubType_PerspectiveCamera;
653 else if (strcmp(typeString,
"camera-stereo")==0)
654 return VuoSceneObjectSubType_StereoCamera;
655 else if (strcmp(typeString,
"camera-orthographic")==0)
656 return VuoSceneObjectSubType_OrthographicCamera;
657 else if (strcmp(typeString,
"camera-fisheye")==0)
658 return VuoSceneObjectSubType_FisheyeCamera;
659 else if (strcmp(typeString,
"light-ambient")==0)
660 return VuoSceneObjectSubType_AmbientLight;
661 else if (strcmp(typeString,
"light-point")==0)
662 return VuoSceneObjectSubType_PointLight;
663 else if (strcmp(typeString,
"light-spot")==0)
664 return VuoSceneObjectSubType_Spotlight;
665 else if (strcmp(typeString,
"text")==0)
666 return VuoSceneObjectSubType_Text;
668 return VuoSceneObjectSubType_Empty;
678 case VuoSceneObjectSubType_Group:
680 case VuoSceneObjectSubType_Mesh:
682 case VuoSceneObjectSubType_PerspectiveCamera:
683 return "camera-perspective";
684 case VuoSceneObjectSubType_StereoCamera:
685 return "camera-stereo";
686 case VuoSceneObjectSubType_OrthographicCamera:
687 return "camera-orthographic";
688 case VuoSceneObjectSubType_FisheyeCamera:
689 return "camera-fisheye";
690 case VuoSceneObjectSubType_AmbientLight:
691 return "light-ambient";
692 case VuoSceneObjectSubType_PointLight:
693 return "light-point";
694 case VuoSceneObjectSubType_Spotlight:
696 case VuoSceneObjectSubType_Text:
711 so->type = VuoSceneObjectSubType_AmbientLight;
713 so->light.color = color;
714 so->light.brightness = brightness;
731 so->type = VuoSceneObjectSubType_PointLight;
734 so->light.color = color;
735 so->light.brightness = brightness;
736 so->light.range = range;
737 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
756 so->type = VuoSceneObjectSubType_Spotlight;
758 so->light.color = color;
759 so->light.brightness = brightness;
760 so->light.cone = cone;
761 so->light.range = range;
762 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
763 so->transform = transform;
780 *ambientBrightness = 0;
785 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
786 if (co->type == VuoSceneObjectSubType_AmbientLight)
789 *ambientBrightness += co->light.brightness;
791 else if (co->type == VuoSceneObjectSubType_PointLight)
797 else if (co->type == VuoSceneObjectSubType_Spotlight)
811 *ambientBrightness = 0.05;
837 float modelviewMatrix[16];
858 rootState.objectCount = 1;
859 rootState.objects = &object;
862 std::list<VuoSceneObject_treeState> objectsToVisit(1, rootState);
863 while (!objectsToVisit.empty())
866 objectsToVisit.pop_front();
868 for (
long i = 0; i < currentState.objectCount; ++i)
870 VuoSceneObject_internal *currentObject = (VuoSceneObject_internal *)currentState.objects[i];
874 float localModelviewMatrix[16];
876 float compositeModelviewMatrix[16];
879 if (!
function((
VuoSceneObject)currentObject, compositeModelviewMatrix))
882 if (currentObject->type == VuoSceneObjectSubType_Group)
886 if (childObjectCount)
889 childState.objectCount = childObjectCount;
891 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
892 objectsToVisit.push_front(childState);
907 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
909 float localModelviewMatrix[16];
911 float compositeModelviewMatrix[16];
914 function(sceneObject, compositeModelviewMatrix);
916 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
919 for (
unsigned long i = 1; i <= childObjectCount; ++i)
942 float localModelviewMatrix[16];
958 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
972 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
973 so->transform.translation += translation;
986 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
987 so->transform.scale *= scale;
1000 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1017 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1018 if (so->type != VuoSceneObjectSubType_Group)
1021 return so->childObjects;
1034 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1035 return so->blendMode;
1046 return VuoSceneObjectSubType_Empty;
1048 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1063 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1080 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1095 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1096 return so->isRealSize;
1111 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1112 return so->preservePhysicalSize;
1128 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1142 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1143 return so->text.text;
1156 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1157 return so->text.font;
1172 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1173 return so->text.scaleWithScene;
1186 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1187 return so->text.wrapWidth;
1200 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1201 return so->camera.fieldOfView;
1214 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1215 return so->camera.width;
1228 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1229 return so->camera.distanceMin;
1242 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1243 return so->camera.distanceMax;
1256 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1257 return so->camera.vignetteWidth;
1270 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1271 return so->camera.vignetteSharpness;
1284 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1285 return so->camera.intraocularDistance;
1298 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1299 return so->camera.confocalDistance;
1312 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1313 return so->light.color;
1326 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1327 return so->light.brightness;
1340 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1341 return so->light.range;
1354 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1355 return so->light.sharpness;
1368 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1369 return so->light.cone;
1382 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1383 return so->transform;
1394 return (VuoPoint3d){0,0,0};
1396 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1397 return so->transform.translation;
1410 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1425 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1439 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1455 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1456 if (so->type != VuoSceneObjectSubType_Group)
1461 so->childObjects = childObjects;
1474 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1490 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1491 so->transform = transform;
1504 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1505 so->transform.translation = translation;
1518 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1519 so->transform.scale = scale;
1532 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1535 so->shader = shader;
1547 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
1570 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
1571 co->blendMode = blendMode;
1586 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1587 so->isRealSize = isRealSize;
1601 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1602 so->preservePhysicalSize = shouldPreservePhysicalSize;
1615 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1618 so->text.text = text;
1631 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1634 so->text.font = font;
1647 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1648 so->camera.fieldOfView = fieldOfView;
1661 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1662 so->camera.distanceMin = distanceMin;
1675 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1676 so->camera.distanceMax = distanceMax;
1695 VuoSceneObject_internal *o = (VuoSceneObject_internal *)
object;
1702 co->transform = o->transform;
1705 co->isRealSize = o->isRealSize;
1706 co->preservePhysicalSize = o->preservePhysicalSize;
1707 co->blendMode = o->blendMode;
1709 if (o->type == VuoSceneObjectSubType_Group && o->childObjects)
1714 VuoListAppendValue_VuoSceneObject(co->childObjects, VuoSceneObject_copy(object));
1719 if (o->type == VuoSceneObjectSubType_PerspectiveCamera
1720 || o->type == VuoSceneObjectSubType_StereoCamera
1721 || o->type == VuoSceneObjectSubType_OrthographicCamera
1722 || o->type == VuoSceneObjectSubType_FisheyeCamera)
1724 co->camera.fieldOfView = o->camera.fieldOfView;
1725 co->camera.width = o->camera.width;
1726 co->camera.distanceMin = o->camera.distanceMin;
1727 co->camera.distanceMax = o->camera.distanceMax;
1728 co->camera.confocalDistance = o->camera.confocalDistance;
1729 co->camera.intraocularDistance = o->camera.intraocularDistance;
1730 co->camera.vignetteWidth = o->camera.vignetteWidth;
1731 co->camera.vignetteSharpness = o->camera.vignetteSharpness;
1733 else if (o->type == VuoSceneObjectSubType_AmbientLight
1734 || o->type == VuoSceneObjectSubType_PointLight
1735 || o->type == VuoSceneObjectSubType_Spotlight)
1737 co->light.color = o->light.color;
1738 co->light.brightness = o->light.brightness;
1739 co->light.range = o->light.range;
1740 co->light.cone = o->light.cone;
1741 co->light.sharpness = o->light.sharpness;
1743 else if (o->type == VuoSceneObjectSubType_Text)
1747 co->text.scaleWithScene = o->text.scaleWithScene;
1748 co->text.wrapWidth = o->text.wrapWidth;
1760 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1762 __block
bool haveGlobalBounds =
false;
1763 __block
VuoBox globalBounds;
1771 haveGlobalBounds =
true;
1776 if (haveGlobalBounds)
1777 return globalBounds;
1779 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1793 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1795 || so->type == VuoSceneObjectSubType_Text)
1807 bounds->size.x *= so->shader->objectScale;
1808 bounds->size.y *= so->shader->objectScale;
1809 bounds->size.z *= so->shader->objectScale;
1824 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1826 so->transform.translation =
VuoPoint3d_subtract(so->transform.translation, bounds.center);
1838 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1841 float scale = fmax(fmax(bounds.size.x, bounds.size.y), bounds.size.z);
1842 if (fabs(scale) < 0.00001)
1879 if (json_object_object_get_ex(js,
"id", &o))
1880 id = json_object_get_int64(o);
1883 if (json_object_object_get_ex(js,
"type", &o))
1887 if (json_object_object_get_ex(js,
"mesh", &o))
1891 if (json_object_object_get_ex(js,
"shader", &o))
1894 bool isRealSize =
false;
1895 if (json_object_object_get_ex(js,
"isRealSize", &o))
1898 bool preservePhysicalSize =
false;
1899 if (json_object_object_get_ex(js,
"preservePhysicalSize", &o))
1903 if (json_object_object_get_ex(js,
"blendMode", &o))
1907 if (json_object_object_get_ex(js,
"childObjects", &o))
1910 float cameraFieldOfView;
1911 if (json_object_object_get_ex(js,
"cameraFieldOfView", &o))
1912 cameraFieldOfView = json_object_get_double(o);
1915 if (json_object_object_get_ex(js,
"cameraWidth", &o))
1916 cameraWidth = json_object_get_double(o);
1918 float cameraDistanceMin;
1919 if (json_object_object_get_ex(js,
"cameraDistanceMin", &o))
1920 cameraDistanceMin = json_object_get_double(o);
1922 float cameraDistanceMax;
1923 if (json_object_object_get_ex(js,
"cameraDistanceMax", &o))
1924 cameraDistanceMax = json_object_get_double(o);
1926 float cameraConfocalDistance;
1927 if (json_object_object_get_ex(js,
"cameraConfocalDistance", &o))
1928 cameraConfocalDistance = json_object_get_double(o);
1930 float cameraIntraocularDistance;
1931 if (json_object_object_get_ex(js,
"cameraIntraocularDistance", &o))
1932 cameraIntraocularDistance = json_object_get_double(o);
1934 float cameraVignetteWidth;
1935 if (json_object_object_get_ex(js,
"cameraVignetteWidth", &o))
1936 cameraVignetteWidth = json_object_get_double(o);
1938 float cameraVignetteSharpness;
1939 if (json_object_object_get_ex(js,
"cameraVignetteSharpness", &o))
1940 cameraVignetteSharpness = json_object_get_double(o);
1943 if (json_object_object_get_ex(js,
"lightColor", &o))
1946 float lightBrightness;
1947 if (json_object_object_get_ex(js,
"lightBrightness", &o))
1948 lightBrightness = json_object_get_double(o);
1951 if (json_object_object_get_ex(js,
"lightCone", &o))
1952 lightCone = json_object_get_double(o);
1955 if (json_object_object_get_ex(js,
"lightRange", &o))
1956 lightRange = json_object_get_double(o);
1958 float lightSharpness;
1959 if (json_object_object_get_ex(js,
"lightSharpness", &o))
1960 lightSharpness = json_object_get_double(o);
1963 if (json_object_object_get_ex(js,
"name", &o))
1966 json_object_object_get_ex(js,
"transform", &o);
1970 if (json_object_object_get_ex(js,
"text", &o))
1974 if (json_object_object_get_ex(js,
"textFont", &o))
1977 bool scaleWithScene =
false;
1978 if (json_object_object_get_ex(js,
"textScaleWithScene", &o))
1981 float wrapWidth = INFINITY;
1982 if (json_object_object_get_ex(js,
"textWrapWidth", &o))
1983 wrapWidth = json_object_get_double(o);
1988 case VuoSceneObjectSubType_Empty:
1991 case VuoSceneObjectSubType_Group:
1994 case VuoSceneObjectSubType_Mesh:
1997 VuoSceneObject_internal *so = (VuoSceneObject_internal *)obj;
1998 so->isRealSize = isRealSize;
1999 so->preservePhysicalSize = preservePhysicalSize;
2000 so->blendMode = blendMode;
2004 case VuoSceneObjectSubType_PerspectiveCamera:
2013 case VuoSceneObjectSubType_StereoCamera:
2020 cameraConfocalDistance,
2021 cameraIntraocularDistance
2024 case VuoSceneObjectSubType_OrthographicCamera:
2033 case VuoSceneObjectSubType_FisheyeCamera:
2038 cameraVignetteWidth,
2039 cameraVignetteSharpness
2042 case VuoSceneObjectSubType_AmbientLight:
2045 case VuoSceneObjectSubType_PointLight:
2048 case VuoSceneObjectSubType_Spotlight:
2051 case VuoSceneObjectSubType_Text:
2071 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2075 json_object_object_add(js,
"id", json_object_new_int64(so->id));
2080 case VuoSceneObjectSubType_Empty:
2083 case VuoSceneObjectSubType_Mesh:
2092 json_object_object_add(js,
"preservePhysicalSize",
VuoBoolean_getJson(so->preservePhysicalSize));
2098 case VuoSceneObjectSubType_Group:
2099 if (so->childObjects)
2103 case VuoSceneObjectSubType_PerspectiveCamera:
2104 case VuoSceneObjectSubType_StereoCamera:
2105 case VuoSceneObjectSubType_OrthographicCamera:
2106 case VuoSceneObjectSubType_FisheyeCamera:
2108 if (so->type != VuoSceneObjectSubType_FisheyeCamera)
2110 json_object_object_add(js,
"cameraDistanceMin", json_object_new_double(so->camera.distanceMin));
2111 json_object_object_add(js,
"cameraDistanceMax", json_object_new_double(so->camera.distanceMax));
2114 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2115 || so->type == VuoSceneObjectSubType_StereoCamera
2116 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2117 json_object_object_add(js,
"cameraFieldOfView", json_object_new_double(so->camera.fieldOfView));
2119 if (so->type == VuoSceneObjectSubType_StereoCamera)
2121 json_object_object_add(js,
"cameraConfocalDistance", json_object_new_double(so->camera.confocalDistance));
2122 json_object_object_add(js,
"cameraIntraocularDistance", json_object_new_double(so->camera.intraocularDistance));
2125 if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2126 json_object_object_add(js,
"cameraWidth", json_object_new_double(so->camera.width));
2128 if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2130 json_object_object_add(js,
"cameraVignetteWidth", json_object_new_double(so->camera.vignetteWidth));
2131 json_object_object_add(js,
"cameraVignetteSharpness", json_object_new_double(so->camera.vignetteSharpness));
2137 case VuoSceneObjectSubType_AmbientLight:
2138 case VuoSceneObjectSubType_PointLight:
2139 case VuoSceneObjectSubType_Spotlight:
2141 json_object_object_add(js,
"lightColor",
VuoColor_getJson(so->light.color));
2142 json_object_object_add(js,
"lightBrightness", json_object_new_double(so->light.brightness));
2144 if (so->type == VuoSceneObjectSubType_PointLight
2145 || so->type == VuoSceneObjectSubType_Spotlight)
2147 json_object_object_add(js,
"lightRange", json_object_new_double(so->light.range));
2148 json_object_object_add(js,
"lightSharpness", json_object_new_double(so->light.sharpness));
2150 if (so->type == VuoSceneObjectSubType_Spotlight)
2151 json_object_object_add(js,
"lightCone", json_object_new_double(so->light.cone));
2156 case VuoSceneObjectSubType_Text:
2161 json_object_object_add(js,
"textFont",
VuoFont_getJson(so->text.font));
2166 json_object_object_add(js,
"textScaleWithScene",
VuoBoolean_getJson(so->text.scaleWithScene));
2167 json_object_object_add(js,
"textWrapWidth",
VuoReal_getJson(so->text.wrapWidth));
2176 if (so->type != VuoSceneObjectSubType_AmbientLight)
2190 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2194 unsigned int vertexCount;
2195 VuoMesh_getCPUBuffers(so->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2207 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2211 unsigned int elementCount;
2212 VuoMesh_getCPUBuffers(so->mesh,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, &elementCount,
nullptr);
2213 return elementCount;
2226 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2227 unsigned long childObjectCount = 0;
2228 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2230 *descendantCount += childObjectCount;
2234 if (so->type == VuoSceneObjectSubType_Group)
2235 for (
unsigned long i = 1; i <= childObjectCount; ++i)
2248 __block
json_object *names = json_object_new_object();
2250 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2252 json_object_object_add(names, co->shader->name, NULL);
2257 json_object_object_foreach(names, key, val)
2259 json_object_put(names);
2269 return strdup(
"no object");
2271 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2273 if (so->type == VuoSceneObjectSubType_Text)
2276 char *textSummary =
VuoText_format(
"<div>\"%s\"</div><div>%sat (%g,%g)</div><div>id %llu</div>", so->text.text, fontSummary, so->transform.translation.x, so->transform.translation.y, so->id);
2281 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2282 || so->type == VuoSceneObjectSubType_StereoCamera
2283 || so->type == VuoSceneObjectSubType_OrthographicCamera
2284 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2288 float cameraViewValue = 0;
2289 const char *cameraViewString =
"";
2290 if (so->type == VuoSceneObjectSubType_PerspectiveCamera)
2292 cameraViewValue = so->camera.fieldOfView;
2293 cameraViewString =
"° field of view";
2295 else if (so->type == VuoSceneObjectSubType_StereoCamera)
2297 cameraViewValue = so->camera.fieldOfView;
2298 cameraViewString =
"° field of view (stereoscopic)";
2300 else if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2302 cameraViewValue = so->camera.width;
2303 cameraViewString =
" unit width";
2305 else if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2307 cameraViewValue = so->camera.fieldOfView;
2308 cameraViewString =
"° field of view (fisheye)";
2313 const char *rotationLabel;
2314 char *rotationString;
2315 if (so->transform.type == VuoTransformTypeEuler)
2317 rotationLabel =
"rotated";
2322 rotationLabel =
"target";
2326 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>",
2327 type, so->name ? so->name :
"",
2329 rotationLabel, rotationString,
2330 cameraViewValue, cameraViewString,
2331 so->camera.distanceMin, so->camera.distanceMax);
2332 free(rotationString);
2333 free(translationString);
2334 return valueAsString;
2337 if (so->type == VuoSceneObjectSubType_AmbientLight
2338 || so->type == VuoSceneObjectSubType_PointLight
2339 || so->type == VuoSceneObjectSubType_Spotlight)
2344 char *positionRangeString;
2345 if (so->type == VuoSceneObjectSubType_PointLight
2346 || so->type == VuoSceneObjectSubType_Spotlight)
2350 positionRangeString =
VuoText_format(
"<div>position (%s)</div><div>range %g units (%g sharpness)</div>",
2351 positionString, so->light.range, so->light.sharpness);
2353 free(positionString);
2356 positionRangeString = strdup(
"");
2358 char *directionConeString;
2359 if (so->type == VuoSceneObjectSubType_Spotlight)
2364 directionConeString =
VuoText_format(
"<div>direction (%s)</div><div>cone %g°</div>",
2365 directionString, so->light.cone * 180./M_PI);
2367 free(directionString);
2370 directionConeString = strdup(
"");
2372 char *valueAsString =
VuoText_format(
"<div>%s</div><div>color %s</div><div>brightness %g</div>%s%s",
2373 type, colorString, so->light.brightness, positionRangeString, directionConeString);
2375 free(directionConeString);
2376 free(positionRangeString);
2379 return valueAsString;
2387 unsigned long childObjectCount = 0;
2388 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2390 const char *childObjectPlural = childObjectCount == 1 ?
"" :
"s";
2393 if (childObjectCount)
2395 unsigned long descendantCount = 0;
2396 unsigned long totalVertexCount = 0;
2397 unsigned long totalElementCount = 0;
2399 const char *descendantPlural = descendantCount == 1 ?
"" :
"s";
2401 descendants =
VuoText_format(
"<div>%ld descendant%s</div><div>total, including descendants:</div><div>%ld vertices, %ld elements</div>",
2402 descendantCount, descendantPlural, totalVertexCount, totalElementCount);
2405 descendants = strdup(
"");
2409 char *shaderNamesSummary;
2413 const char *header =
"<div>shaders:<ul>";
2414 VuoInteger shaderNameLength = strlen(header);
2415 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2417 shaderNameLength += strlen(
"</ul></div>");
2419 shaderNamesSummary = (
char *)malloc(shaderNameLength + 1);
2420 char *t = shaderNamesSummary;
2421 t = strcpy(t, header) + strlen(header);
2422 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2424 t = strcpy(t,
"<li>") + strlen(
"<li>");
2426 t = strcpy(t,
"</li>") + strlen(
"</li>");
2428 t = strcpy(t,
"</ul></div>");
2431 shaderNamesSummary = strdup(
"");
2434 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",
2435 so->name ? so->name :
"",
2436 vertexCount, elementCount,
2439 childObjectCount, childObjectPlural,
2440 descendants, shaderNamesSummary);
2444 free(shaderNamesSummary);
2446 return valueAsString;
2454 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2456 for (
unsigned int i=0; i<level; ++i)
2457 fprintf(stderr,
"\t");
2461 fprintf(stderr,
"no object\n");
2466 if (so->type == VuoSceneObjectSubType_Mesh)
2468 fprintf(stderr,
"\n");
2470 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2473 for (
unsigned int i=1; i<=childObjectCount; ++i)
2503 __block
unsigned long triangleVertexCount = 0;
2504 __block
unsigned long trianglePrimitiveCount = 0;
2507 __block
unsigned long lineVertexCount = 0;
2508 __block
unsigned long linePrimitiveCount = 0;
2509 __block
double linePrimitiveSize = 0;
2511 __block
unsigned long pointVertexCount = 0;
2512 __block
unsigned long pointPrimitiveCount = 0;
2513 __block
double pointPrimitiveSize = 0;
2516 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2522 unsigned int vertexCount;
2523 VuoMesh_getCPUBuffers(co->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2529 triangleVertexCount += vertexCount;
2536 lineVertexCount += vertexCount;
2542 pointVertexCount += vertexCount;
2551 if (!trianglePrimitiveCount && !linePrimitiveCount && !pointPrimitiveCount)
2555 unsigned int *triangleElements =
nullptr;
2556 VuoPoint4d *trianglePositions =
nullptr, *triangleNormals =
nullptr, *triangleTextureCoordinates =
nullptr;
2557 unsigned int *lineElements =
nullptr;
2558 VuoPoint4d *linePositions =
nullptr, *lineNormals =
nullptr, *lineTextureCoordinates =
nullptr;
2559 unsigned int *pointElements =
nullptr;
2560 VuoPoint4d *pointPositions =
nullptr, *pointNormals =
nullptr, *pointTextureCoordinates =
nullptr;
2561 if (trianglePrimitiveCount)
2562 VuoMesh_allocateCPUBuffers(triangleVertexCount, &trianglePositions, &triangleNormals,
nullptr,
nullptr, &triangleTextureCoordinates, trianglePrimitiveCount * 3, &triangleElements);
2563 if (linePrimitiveCount)
2564 VuoMesh_allocateCPUBuffers(lineVertexCount, &linePositions, &lineNormals,
nullptr,
nullptr, &lineTextureCoordinates, linePrimitiveCount * 2, &lineElements);
2565 if (pointPrimitiveCount)
2566 VuoMesh_allocateCPUBuffers(pointVertexCount, &pointPositions, &pointNormals,
nullptr,
nullptr, &pointTextureCoordinates, pointPrimitiveCount, &pointElements);
2569 __block
unsigned long triangleVertexIndex = 0;
2570 __block
unsigned long triangleElementIndex = 0;
2571 __block
unsigned long lineVertexIndex = 0;
2572 __block
unsigned long lineElementIndex = 0;
2573 __block
unsigned long pointVertexIndex = 0;
2574 __block
unsigned long pointElementIndex = 0;
2575 __block
bool anyTextureCoordinates =
false;
2577 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2583 unsigned int vertexCount, elementCount, *elements;
2584 VuoPoint4d *positions, *normals, *textureCoordinates;
2585 VuoMesh_getCPUBuffers(co->mesh, &vertexCount, &positions, &normals,
nullptr,
nullptr, &textureCoordinates, &elementCount, &elements);
2587 if (textureCoordinates)
2588 anyTextureCoordinates =
true;
2594 unsigned long indexOffset = triangleVertexIndex;
2595 for (
unsigned int n = 0; n < vertexCount; ++n)
2597 VuoPoint3d p = positions[n].xyz;
2599 trianglePositions[triangleVertexIndex] = (VuoPoint4d){pt.x, pt.y, pt.z, 1};
2603 VuoPoint3d r = normals[n].xyz;
2605 triangleNormals[triangleVertexIndex] = (VuoPoint4d){rt.x, rt.y, rt.z, 1};
2608 if (textureCoordinates)
2609 triangleTextureCoordinates[triangleVertexIndex] = textureCoordinates[n];
2611 ++triangleVertexIndex;
2617 for (
unsigned int n = 0; n < elementCount; ++n)
2618 triangleElements[triangleElementIndex++] = indexOffset + elements[n];
2620 for (
unsigned int n = 0; n < vertexCount; ++n)
2621 triangleElements[triangleElementIndex++] = indexOffset + n;
2627 for (
unsigned int n = 2; n < elementCount; ++n)
2630 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2631 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2632 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2636 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2637 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2638 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2641 for (
unsigned int n = 0; n < vertexCount; ++n)
2644 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2645 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2646 triangleElements[triangleElementIndex++] = indexOffset + n ;
2650 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2651 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2652 triangleElements[triangleElementIndex++] = indexOffset + n ;
2659 for (
unsigned int n = 2; n < elementCount; ++n)
2661 triangleElements[triangleElementIndex++] = indexOffset + elements[0 ];
2662 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2663 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2666 for (
unsigned int n = 2; n < vertexCount; ++n)
2668 triangleElements[triangleElementIndex++] = indexOffset + 0;
2669 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2670 triangleElements[triangleElementIndex++] = indexOffset + n;
2677 unsigned long indexOffset = lineVertexIndex;
2678 for (
unsigned int n = 0; n < vertexCount; ++n)
2680 VuoPoint3d p = positions[n].xyz;
2682 linePositions[lineVertexIndex] = (VuoPoint4d){pt.x, pt.y, pt.z, 1};
2686 VuoPoint3d r = normals[n].xyz;
2688 lineNormals[lineVertexIndex] = (VuoPoint4d){rt.x, rt.y, rt.z, 1};
2691 if (textureCoordinates)
2692 lineTextureCoordinates[lineVertexIndex] = textureCoordinates[n];
2700 for (
unsigned int n = 0; n < elementCount; ++n)
2701 lineElements[lineElementIndex++] = indexOffset + elements[n];
2703 for (
unsigned int n = 0; n < vertexCount; ++n)
2704 lineElements[lineElementIndex++] = indexOffset + n;
2710 for (
unsigned int n = 1; n < elementCount; ++n)
2712 lineElements[lineElementIndex++] = indexOffset + elements[n-1];
2713 lineElements[lineElementIndex++] = indexOffset + elements[n ];
2716 for (
unsigned int n = 1; n < vertexCount; ++n)
2718 lineElements[lineElementIndex++] = indexOffset + n-1;
2719 lineElements[lineElementIndex++] = indexOffset + n;
2725 unsigned long indexOffset = pointVertexIndex;
2726 for (
unsigned int n = 0; n < vertexCount; ++n)
2728 VuoPoint3d p = positions[n].xyz;
2730 pointPositions[pointVertexIndex] = (VuoPoint4d){pt.x, pt.y, pt.z, 1};
2734 VuoPoint3d r = normals[n].xyz;
2736 pointNormals[pointVertexIndex] = (VuoPoint4d){rt.x, rt.y, rt.z, 1};
2739 if (textureCoordinates)
2740 pointTextureCoordinates[pointVertexIndex] = textureCoordinates[n];
2747 for (
unsigned int n = 0; n < elementCount; ++n)
2748 pointElements[pointElementIndex++] = indexOffset + elements[n];
2751 for (
unsigned int n = 0; n < vertexCount; ++n)
2752 pointElements[pointElementIndex++] = indexOffset + n;
2760 VuoMesh triangleMesh =
nullptr;
2763 if (trianglePrimitiveCount)
2765 if (!anyTextureCoordinates)
2767 free(triangleTextureCoordinates);
2768 triangleTextureCoordinates =
nullptr;
2772 if (calculateTangents)
2775 if (linePrimitiveCount)
2777 if (!anyTextureCoordinates)
2779 free(lineTextureCoordinates);
2780 lineTextureCoordinates =
nullptr;
2785 if (pointPrimitiveCount)
2787 if (!anyTextureCoordinates)
2789 free(pointTextureCoordinates);
2790 pointTextureCoordinates =
nullptr;
2796 if (triangleMesh && !lineMesh && !pointMesh)
2798 else if (!triangleMesh && lineMesh && !pointMesh)
2800 else if (!triangleMesh && !lineMesh && pointMesh)
2815 #define CSGJS_HEADER_ONLY
2824 return csgjs_model();
2827 VuoSceneObject_internal *f = (VuoSceneObject_internal *)flat;
2829 return csgjs_model();
2834 return csgjs_model();
2836 unsigned int vertexCount, elementCount, *elements;
2837 VuoPoint4d *positions, *normals, *textureCoordinates;
2838 VuoMesh_getCPUBuffers(f->mesh, &vertexCount, &positions, &normals,
nullptr,
nullptr, &textureCoordinates, &elementCount, &elements);
2841 for (
unsigned int n = 0; n < vertexCount; ++n)
2844 v.pos = csgjs_vector(positions[n].x, positions[n].y, positions[n].z);
2846 v.normal = csgjs_vector(normals[n].x, normals[n].y, normals[n].z);
2847 if (textureCoordinates)
2848 v.uv = csgjs_vector(textureCoordinates[n].x, textureCoordinates[n].y, 0);
2849 cm.vertices.push_back(v);
2851 for (
unsigned int n = 0; n < elementCount; ++n)
2852 cm.indices.push_back(elements[n]);
2862 unsigned int vertexCount = cm.vertices.size();
2863 unsigned int elementCount = cm.indices.size();
2864 unsigned int *elements;
2865 VuoPoint4d *positions, *normals, *textureCoordinates;
2866 VuoMesh_allocateCPUBuffers(vertexCount, &positions, &normals,
nullptr,
nullptr, &textureCoordinates, elementCount, &elements);
2868 const csgjs_vertex *vertex = &cm.vertices[0];
2869 for (
unsigned int n = 0; n < vertexCount; ++n)
2871 positions[n] = (VuoPoint4d){vertex[n].pos.x,vertex[n].pos.y,vertex[n].pos.z,1};
2872 normals[n] = (VuoPoint4d){vertex[n].normal.x,vertex[n].normal.y,vertex[n].normal.z,1};
2873 textureCoordinates[n] = (VuoPoint4d){vertex[n].uv.x,vertex[n].uv.y,vertex[n].uv.z,1};
2876 const int *index = &cm.indices[0];
2877 for (
unsigned int n = 0; n < elementCount; ++n)
2878 elements[n] = index[n];
2904 if (objectCount == 0)
2906 if (objectCount == 1)
2909 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.union", DISPATCH_QUEUE_CONCURRENT);
2911 csgjs_model *models =
new csgjs_model[objectCount];
2912 for (
unsigned long i = 0; i < objectCount; ++i)
2913 dispatch_async(queue, ^{
2917 dispatch_barrier_sync(queue, ^{});
2918 dispatch_release(queue);
2920 csgjs_model cu = models[0];
2921 for (
unsigned long i = 1; i < objectCount; ++i)
2922 cu = csgjs_union(cu, models[i], epsilon);
2934 dispatch_semaphore_t finished = dispatch_semaphore_create(0);
2936 __block csgjs_model ca;
2937 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
2939 dispatch_semaphore_signal(finished);
2944 dispatch_semaphore_wait(finished, DISPATCH_TIME_FOREVER);
2945 dispatch_release(finished);
2947 csgjs_model d = csgjs_difference(ca, cb, epsilon);
2959 if (objectCount == 0)
2961 if (objectCount == 1)
2964 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.intersect", DISPATCH_QUEUE_CONCURRENT);
2966 csgjs_model *models =
new csgjs_model[objectCount];
2967 for (
unsigned long i = 0; i < objectCount; ++i)
2968 dispatch_async(queue, ^{
2972 dispatch_barrier_sync(queue, ^{});
2973 dispatch_release(queue);
2975 csgjs_model ci = models[0];
2976 for (
unsigned long i = 1; i < objectCount; ++i)
2977 ci = csgjs_intersection(ci, models[i], epsilon);