12 #include <OpenGL/CGLMacro.h>
24 "title" :
"Scene Object",
25 "description" :
"A 3D Object: visible (mesh), or virtual (group, light, camera).",
41 "VuoList_VuoSceneObject"
68 bool preservePhysicalSize;
81 float confocalDistance;
82 float intraocularDistance;
84 float vignetteSharpness;
104 } VuoSceneObject_internal;
112 static uint64_t
id = 0;
113 return __sync_add_and_fetch(&
id, 1);
123 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
128 if (so->type == VuoSceneObjectSubType_Group)
130 else if (so->type == VuoSceneObjectSubType_Text)
144 VuoSceneObject_internal *so = (VuoSceneObject_internal *)calloc(1,
sizeof(VuoSceneObject_internal));
148 so->type = VuoSceneObjectSubType_Empty;
152 so->isRealSize =
false;
153 so->preservePhysicalSize =
false;
169 so->type = VuoSceneObjectSubType_Group;
173 so->transform = transform;
185 so->type = VuoSceneObjectSubType_Mesh;
194 so->transform = transform;
424 unsigned int _rows =
MAX(2,
MIN(512, rows));
425 unsigned int _columns =
MAX(2,
MIN(512, columns));
426 unsigned int _slices =
MAX(2,
MIN(512, slices));
500 so->type = VuoSceneObjectSubType_Text;
503 so->text.scaleWithScene = scaleWithScene;
504 so->text.wrapWidth = wrapWidth;
514 so->type = VuoSceneObjectSubType_PerspectiveCamera;
516 so->transform = transform;
517 so->camera.fieldOfView = fieldOfView;
518 so->camera.distanceMin = distanceMin;
519 so->camera.distanceMax = distanceMax;
529 so->type = VuoSceneObjectSubType_StereoCamera;
531 so->transform = transform;
532 so->camera.fieldOfView = fieldOfView;
533 so->camera.distanceMin = distanceMin;
534 so->camera.distanceMax = distanceMax;
535 so->camera.confocalDistance = confocalDistance;
536 so->camera.intraocularDistance = intraocularDistance;
546 so->type = VuoSceneObjectSubType_OrthographicCamera;
548 so->transform = transform;
549 so->camera.width = width;
550 so->camera.distanceMin = distanceMin;
551 so->camera.distanceMax = distanceMax;
561 so->type = VuoSceneObjectSubType_FisheyeCamera;
563 so->transform = transform;
564 so->camera.fieldOfView = fieldOfView;
567 so->camera.distanceMin = 0;
568 so->camera.distanceMax = 1000;
570 so->camera.vignetteWidth = vignetteWidth;
571 so->camera.vignetteSharpness = vignetteSharpness;
609 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
617 if (so->type == VuoSceneObjectSubType_Group)
622 for (
unsigned long i = 1; i <= childObjectCount; ++i)
650 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
652 if (so->id == idToMatch)
658 if (so->type == VuoSceneObjectSubType_Group)
663 for (
unsigned long i = 1; i <= childObjectCount; ++i)
691 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
693 if (so->type == typeToMatch)
699 if (so->type == VuoSceneObjectSubType_Group)
705 for (
unsigned long i = 1; i <= childObjectCount; ++i)
732 __block
bool didFindCamera =
false;
734 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
735 if ((co->type == VuoSceneObjectSubType_PerspectiveCamera
736 || co->type == VuoSceneObjectSubType_StereoCamera
737 || co->type == VuoSceneObjectSubType_OrthographicCamera
738 || co->type == VuoSceneObjectSubType_FisheyeCamera)
739 && (!nameToMatch || (co->name && nameToMatch && strstr(co->name, nameToMatch))))
741 *foundCamera = currentObject;
743 didFindCamera =
true;
749 return didFindCamera;
760 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
761 return so->type != VuoSceneObjectSubType_Empty;
769 if (strcmp(typeString,
"empty")==0)
770 return VuoSceneObjectSubType_Empty;
771 else if (strcmp(typeString,
"group")==0)
772 return VuoSceneObjectSubType_Group;
773 else if (strcmp(typeString,
"mesh")==0)
774 return VuoSceneObjectSubType_Mesh;
775 else if (strcmp(typeString,
"camera-perspective")==0)
776 return VuoSceneObjectSubType_PerspectiveCamera;
777 else if (strcmp(typeString,
"camera-stereo")==0)
778 return VuoSceneObjectSubType_StereoCamera;
779 else if (strcmp(typeString,
"camera-orthographic")==0)
780 return VuoSceneObjectSubType_OrthographicCamera;
781 else if (strcmp(typeString,
"camera-fisheye")==0)
782 return VuoSceneObjectSubType_FisheyeCamera;
783 else if (strcmp(typeString,
"light-ambient")==0)
784 return VuoSceneObjectSubType_AmbientLight;
785 else if (strcmp(typeString,
"light-point")==0)
786 return VuoSceneObjectSubType_PointLight;
787 else if (strcmp(typeString,
"light-spot")==0)
788 return VuoSceneObjectSubType_Spotlight;
789 else if (strcmp(typeString,
"text")==0)
790 return VuoSceneObjectSubType_Text;
792 return VuoSceneObjectSubType_Empty;
802 case VuoSceneObjectSubType_Group:
804 case VuoSceneObjectSubType_Mesh:
806 case VuoSceneObjectSubType_PerspectiveCamera:
807 return "camera-perspective";
808 case VuoSceneObjectSubType_StereoCamera:
809 return "camera-stereo";
810 case VuoSceneObjectSubType_OrthographicCamera:
811 return "camera-orthographic";
812 case VuoSceneObjectSubType_FisheyeCamera:
813 return "camera-fisheye";
814 case VuoSceneObjectSubType_AmbientLight:
815 return "light-ambient";
816 case VuoSceneObjectSubType_PointLight:
817 return "light-point";
818 case VuoSceneObjectSubType_Spotlight:
820 case VuoSceneObjectSubType_Text:
835 so->type = VuoSceneObjectSubType_AmbientLight;
837 so->light.color = color;
838 so->light.brightness = brightness;
855 so->type = VuoSceneObjectSubType_PointLight;
858 so->light.color = color;
859 so->light.brightness = brightness;
860 so->light.range = range;
861 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
880 so->type = VuoSceneObjectSubType_Spotlight;
882 so->light.color = color;
883 so->light.brightness = brightness;
884 so->light.cone = cone;
885 so->light.range = range;
886 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
887 so->transform = transform;
904 *ambientBrightness = 0;
909 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
910 if (co->type == VuoSceneObjectSubType_AmbientLight)
913 *ambientBrightness += co->light.brightness;
915 else if (co->type == VuoSceneObjectSubType_PointLight)
921 else if (co->type == VuoSceneObjectSubType_Spotlight)
935 *ambientBrightness = 0.05;
961 float modelviewMatrix[16];
982 rootState.objectCount = 1;
983 rootState.objects = &object;
986 std::list<VuoSceneObject_treeState> objectsToVisit(1, rootState);
987 while (!objectsToVisit.empty())
990 objectsToVisit.pop_front();
992 for (
long i = 0; i < currentState.objectCount; ++i)
994 VuoSceneObject_internal *currentObject = (VuoSceneObject_internal *)currentState.objects[i];
998 float localModelviewMatrix[16];
1000 float compositeModelviewMatrix[16];
1003 if (!
function((
VuoSceneObject)currentObject, compositeModelviewMatrix))
1006 if (currentObject->type == VuoSceneObjectSubType_Group)
1010 if (childObjectCount)
1013 childState.objectCount = childObjectCount;
1015 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
1016 objectsToVisit.push_front(childState);
1031 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1033 float localModelviewMatrix[16];
1035 float compositeModelviewMatrix[16];
1038 function(sceneObject, compositeModelviewMatrix);
1040 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
1043 for (
unsigned long i = 1; i <= childObjectCount; ++i)
1066 float localModelviewMatrix[16];
1082 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1096 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1097 so->transform.translation += translation;
1110 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1111 so->transform.scale *= scale;
1124 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1141 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1142 if (so->type != VuoSceneObjectSubType_Group)
1145 return so->childObjects;
1158 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1159 return so->blendMode;
1170 return VuoSceneObjectSubType_Empty;
1172 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1187 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1204 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1219 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1220 return so->isRealSize;
1235 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1236 return so->preservePhysicalSize;
1252 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1266 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1267 return so->text.text;
1280 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1281 return so->text.font;
1296 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1297 return so->text.scaleWithScene;
1310 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1311 return so->text.wrapWidth;
1324 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1325 return so->camera.fieldOfView;
1338 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1339 return so->camera.width;
1352 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1353 return so->camera.distanceMin;
1366 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1367 return so->camera.distanceMax;
1380 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1381 return so->camera.vignetteWidth;
1394 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1395 return so->camera.vignetteSharpness;
1408 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1409 return so->camera.intraocularDistance;
1422 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1423 return so->camera.confocalDistance;
1436 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1437 return so->light.color;
1450 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1451 return so->light.brightness;
1464 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1465 return so->light.range;
1478 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1479 return so->light.sharpness;
1492 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1493 return so->light.cone;
1506 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1507 return so->transform;
1518 return (VuoPoint3d){0,0,0};
1520 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1521 return so->transform.translation;
1534 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1549 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1563 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1579 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1580 if (so->type != VuoSceneObjectSubType_Group)
1585 so->childObjects = childObjects;
1598 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1614 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1615 so->transform = transform;
1628 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1629 so->transform.translation = translation;
1642 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1643 so->transform.scale = scale;
1656 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1659 so->shader = shader;
1695 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
1696 co->blendMode = blendMode;
1711 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1712 so->isRealSize = isRealSize;
1726 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1727 so->preservePhysicalSize = shouldPreservePhysicalSize;
1740 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1743 so->text.text = text;
1756 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1759 so->text.font = font;
1772 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1773 so->camera.fieldOfView = fieldOfView;
1786 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1787 so->camera.distanceMin = distanceMin;
1800 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1801 so->camera.distanceMax = distanceMax;
1819 VuoSceneObject_internal *o = (VuoSceneObject_internal *)
object;
1826 co->transform = o->transform;
1829 co->isRealSize = o->isRealSize;
1830 co->preservePhysicalSize = o->preservePhysicalSize;
1831 co->blendMode = o->blendMode;
1833 if (o->type == VuoSceneObjectSubType_Group && o->childObjects)
1838 VuoListAppendValue_VuoSceneObject(co->childObjects, VuoSceneObject_copy(object));
1843 if (o->type == VuoSceneObjectSubType_PerspectiveCamera
1844 || o->type == VuoSceneObjectSubType_StereoCamera
1845 || o->type == VuoSceneObjectSubType_OrthographicCamera
1846 || o->type == VuoSceneObjectSubType_FisheyeCamera)
1848 co->camera.fieldOfView = o->camera.fieldOfView;
1849 co->camera.width = o->camera.width;
1850 co->camera.distanceMin = o->camera.distanceMin;
1851 co->camera.distanceMax = o->camera.distanceMax;
1852 co->camera.confocalDistance = o->camera.confocalDistance;
1853 co->camera.intraocularDistance = o->camera.intraocularDistance;
1854 co->camera.vignetteWidth = o->camera.vignetteWidth;
1855 co->camera.vignetteSharpness = o->camera.vignetteSharpness;
1857 else if (o->type == VuoSceneObjectSubType_AmbientLight
1858 || o->type == VuoSceneObjectSubType_PointLight
1859 || o->type == VuoSceneObjectSubType_Spotlight)
1861 co->light.color = o->light.color;
1862 co->light.brightness = o->light.brightness;
1863 co->light.range = o->light.range;
1864 co->light.cone = o->light.cone;
1865 co->light.sharpness = o->light.sharpness;
1867 else if (o->type == VuoSceneObjectSubType_Text)
1871 co->text.scaleWithScene = o->text.scaleWithScene;
1872 co->text.wrapWidth = o->text.wrapWidth;
1884 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1886 __block
bool haveGlobalBounds =
false;
1887 __block
VuoBox globalBounds;
1895 haveGlobalBounds =
true;
1900 if (haveGlobalBounds)
1901 return globalBounds;
1903 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1917 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1919 || so->type == VuoSceneObjectSubType_Text)
1931 bounds->size.x *= so->shader->objectScale;
1932 bounds->size.y *= so->shader->objectScale;
1933 bounds->size.z *= so->shader->objectScale;
1948 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1950 so->transform.translation =
VuoPoint3d_subtract(so->transform.translation, bounds.center);
1962 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1965 float scale = fmax(fmax(bounds.size.x, bounds.size.y), bounds.size.z);
1966 if (fabs(scale) < 0.00001)
2003 if (json_object_object_get_ex(js,
"id", &o))
2004 id = json_object_get_int64(o);
2007 if (json_object_object_get_ex(js,
"type", &o))
2011 if (json_object_object_get_ex(js,
"mesh", &o))
2015 if (json_object_object_get_ex(js,
"shader", &o))
2018 bool isRealSize =
false;
2019 if (json_object_object_get_ex(js,
"isRealSize", &o))
2022 bool preservePhysicalSize =
false;
2023 if (json_object_object_get_ex(js,
"preservePhysicalSize", &o))
2027 if (json_object_object_get_ex(js,
"blendMode", &o))
2031 if (json_object_object_get_ex(js,
"childObjects", &o))
2034 float cameraFieldOfView;
2035 if (json_object_object_get_ex(js,
"cameraFieldOfView", &o))
2036 cameraFieldOfView = json_object_get_double(o);
2039 if (json_object_object_get_ex(js,
"cameraWidth", &o))
2040 cameraWidth = json_object_get_double(o);
2042 float cameraDistanceMin;
2043 if (json_object_object_get_ex(js,
"cameraDistanceMin", &o))
2044 cameraDistanceMin = json_object_get_double(o);
2046 float cameraDistanceMax;
2047 if (json_object_object_get_ex(js,
"cameraDistanceMax", &o))
2048 cameraDistanceMax = json_object_get_double(o);
2050 float cameraConfocalDistance;
2051 if (json_object_object_get_ex(js,
"cameraConfocalDistance", &o))
2052 cameraConfocalDistance = json_object_get_double(o);
2054 float cameraIntraocularDistance;
2055 if (json_object_object_get_ex(js,
"cameraIntraocularDistance", &o))
2056 cameraIntraocularDistance = json_object_get_double(o);
2058 float cameraVignetteWidth;
2059 if (json_object_object_get_ex(js,
"cameraVignetteWidth", &o))
2060 cameraVignetteWidth = json_object_get_double(o);
2062 float cameraVignetteSharpness;
2063 if (json_object_object_get_ex(js,
"cameraVignetteSharpness", &o))
2064 cameraVignetteSharpness = json_object_get_double(o);
2067 if (json_object_object_get_ex(js,
"lightColor", &o))
2070 float lightBrightness;
2071 if (json_object_object_get_ex(js,
"lightBrightness", &o))
2072 lightBrightness = json_object_get_double(o);
2075 if (json_object_object_get_ex(js,
"lightCone", &o))
2076 lightCone = json_object_get_double(o);
2079 if (json_object_object_get_ex(js,
"lightRange", &o))
2080 lightRange = json_object_get_double(o);
2082 float lightSharpness;
2083 if (json_object_object_get_ex(js,
"lightSharpness", &o))
2084 lightSharpness = json_object_get_double(o);
2087 if (json_object_object_get_ex(js,
"name", &o))
2090 json_object_object_get_ex(js,
"transform", &o);
2094 if (json_object_object_get_ex(js,
"text", &o))
2098 if (json_object_object_get_ex(js,
"textFont", &o))
2101 bool scaleWithScene =
false;
2102 if (json_object_object_get_ex(js,
"textScaleWithScene", &o))
2105 float wrapWidth = INFINITY;
2106 if (json_object_object_get_ex(js,
"textWrapWidth", &o))
2107 wrapWidth = json_object_get_double(o);
2112 case VuoSceneObjectSubType_Empty:
2115 case VuoSceneObjectSubType_Group:
2118 case VuoSceneObjectSubType_Mesh:
2121 VuoSceneObject_internal *so = (VuoSceneObject_internal *)obj;
2122 so->isRealSize = isRealSize;
2123 so->preservePhysicalSize = preservePhysicalSize;
2124 so->blendMode = blendMode;
2128 case VuoSceneObjectSubType_PerspectiveCamera:
2137 case VuoSceneObjectSubType_StereoCamera:
2144 cameraConfocalDistance,
2145 cameraIntraocularDistance
2148 case VuoSceneObjectSubType_OrthographicCamera:
2157 case VuoSceneObjectSubType_FisheyeCamera:
2162 cameraVignetteWidth,
2163 cameraVignetteSharpness
2166 case VuoSceneObjectSubType_AmbientLight:
2169 case VuoSceneObjectSubType_PointLight:
2172 case VuoSceneObjectSubType_Spotlight:
2175 case VuoSceneObjectSubType_Text:
2195 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2199 json_object_object_add(js,
"id", json_object_new_int64(so->id));
2204 case VuoSceneObjectSubType_Empty:
2207 case VuoSceneObjectSubType_Mesh:
2216 json_object_object_add(js,
"preservePhysicalSize",
VuoBoolean_getJson(so->preservePhysicalSize));
2222 case VuoSceneObjectSubType_Group:
2223 if (so->childObjects)
2227 case VuoSceneObjectSubType_PerspectiveCamera:
2228 case VuoSceneObjectSubType_StereoCamera:
2229 case VuoSceneObjectSubType_OrthographicCamera:
2230 case VuoSceneObjectSubType_FisheyeCamera:
2232 if (so->type != VuoSceneObjectSubType_FisheyeCamera)
2234 json_object_object_add(js,
"cameraDistanceMin", json_object_new_double(so->camera.distanceMin));
2235 json_object_object_add(js,
"cameraDistanceMax", json_object_new_double(so->camera.distanceMax));
2238 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2239 || so->type == VuoSceneObjectSubType_StereoCamera
2240 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2241 json_object_object_add(js,
"cameraFieldOfView", json_object_new_double(so->camera.fieldOfView));
2243 if (so->type == VuoSceneObjectSubType_StereoCamera)
2245 json_object_object_add(js,
"cameraConfocalDistance", json_object_new_double(so->camera.confocalDistance));
2246 json_object_object_add(js,
"cameraIntraocularDistance", json_object_new_double(so->camera.intraocularDistance));
2249 if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2250 json_object_object_add(js,
"cameraWidth", json_object_new_double(so->camera.width));
2252 if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2254 json_object_object_add(js,
"cameraVignetteWidth", json_object_new_double(so->camera.vignetteWidth));
2255 json_object_object_add(js,
"cameraVignetteSharpness", json_object_new_double(so->camera.vignetteSharpness));
2261 case VuoSceneObjectSubType_AmbientLight:
2262 case VuoSceneObjectSubType_PointLight:
2263 case VuoSceneObjectSubType_Spotlight:
2265 json_object_object_add(js,
"lightColor",
VuoColor_getJson(so->light.color));
2266 json_object_object_add(js,
"lightBrightness", json_object_new_double(so->light.brightness));
2268 if (so->type == VuoSceneObjectSubType_PointLight
2269 || so->type == VuoSceneObjectSubType_Spotlight)
2271 json_object_object_add(js,
"lightRange", json_object_new_double(so->light.range));
2272 json_object_object_add(js,
"lightSharpness", json_object_new_double(so->light.sharpness));
2274 if (so->type == VuoSceneObjectSubType_Spotlight)
2275 json_object_object_add(js,
"lightCone", json_object_new_double(so->light.cone));
2280 case VuoSceneObjectSubType_Text:
2285 json_object_object_add(js,
"textFont",
VuoFont_getJson(so->text.font));
2290 json_object_object_add(js,
"textScaleWithScene",
VuoBoolean_getJson(so->text.scaleWithScene));
2291 json_object_object_add(js,
"textWrapWidth",
VuoReal_getJson(so->text.wrapWidth));
2300 if (so->type != VuoSceneObjectSubType_AmbientLight)
2314 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2318 unsigned int vertexCount;
2319 VuoMesh_getCPUBuffers(so->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2331 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2335 unsigned int elementCount;
2336 VuoMesh_getCPUBuffers(so->mesh,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, &elementCount,
nullptr);
2337 return elementCount;
2350 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2351 unsigned long childObjectCount = 0;
2352 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2354 *descendantCount += childObjectCount;
2358 if (so->type == VuoSceneObjectSubType_Group)
2359 for (
unsigned long i = 1; i <= childObjectCount; ++i)
2372 __block
json_object *names = json_object_new_object();
2374 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2376 json_object_object_add(names, co->shader->name, NULL);
2381 json_object_object_foreach(names, key, val)
2383 json_object_put(names);
2393 return strdup(
"no object");
2395 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2397 if (so->type == VuoSceneObjectSubType_Text)
2400 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);
2405 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2406 || so->type == VuoSceneObjectSubType_StereoCamera
2407 || so->type == VuoSceneObjectSubType_OrthographicCamera
2408 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2412 float cameraViewValue = 0;
2413 const char *cameraViewString =
"";
2414 if (so->type == VuoSceneObjectSubType_PerspectiveCamera)
2416 cameraViewValue = so->camera.fieldOfView;
2417 cameraViewString =
"° field of view";
2419 else if (so->type == VuoSceneObjectSubType_StereoCamera)
2421 cameraViewValue = so->camera.fieldOfView;
2422 cameraViewString =
"° field of view (stereoscopic)";
2424 else if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2426 cameraViewValue = so->camera.width;
2427 cameraViewString =
" unit width";
2429 else if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2431 cameraViewValue = so->camera.fieldOfView;
2432 cameraViewString =
"° field of view (fisheye)";
2437 const char *rotationLabel;
2438 char *rotationString;
2439 if (so->transform.type == VuoTransformTypeEuler)
2441 rotationLabel =
"rotated";
2446 rotationLabel =
"target";
2450 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>",
2451 type, so->name ? so->name :
"",
2453 rotationLabel, rotationString,
2454 cameraViewValue, cameraViewString,
2455 so->camera.distanceMin, so->camera.distanceMax);
2456 free(rotationString);
2457 free(translationString);
2458 return valueAsString;
2461 if (so->type == VuoSceneObjectSubType_AmbientLight
2462 || so->type == VuoSceneObjectSubType_PointLight
2463 || so->type == VuoSceneObjectSubType_Spotlight)
2468 char *positionRangeString;
2469 if (so->type == VuoSceneObjectSubType_PointLight
2470 || so->type == VuoSceneObjectSubType_Spotlight)
2474 positionRangeString =
VuoText_format(
"<div>position (%s)</div><div>range %g units (%g sharpness)</div>",
2475 positionString, so->light.range, so->light.sharpness);
2477 free(positionString);
2480 positionRangeString = strdup(
"");
2482 char *directionConeString;
2483 if (so->type == VuoSceneObjectSubType_Spotlight)
2488 directionConeString =
VuoText_format(
"<div>direction (%s)</div><div>cone %g°</div>",
2489 directionString, so->light.cone * 180./M_PI);
2491 free(directionString);
2494 directionConeString = strdup(
"");
2496 char *valueAsString =
VuoText_format(
"<div>%s</div><div>color %s</div><div>brightness %g</div>%s%s",
2497 type, colorString, so->light.brightness, positionRangeString, directionConeString);
2499 free(directionConeString);
2500 free(positionRangeString);
2503 return valueAsString;
2511 unsigned long childObjectCount = 0;
2512 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2514 const char *childObjectPlural = childObjectCount == 1 ?
"" :
"s";
2517 if (childObjectCount)
2519 unsigned long descendantCount = 0;
2520 unsigned long totalVertexCount = 0;
2521 unsigned long totalElementCount = 0;
2523 const char *descendantPlural = descendantCount == 1 ?
"" :
"s";
2525 descendants =
VuoText_format(
"<div>%ld descendant%s</div><div>total, including descendants:</div><div>%ld vertices, %ld elements</div>",
2526 descendantCount, descendantPlural, totalVertexCount, totalElementCount);
2529 descendants = strdup(
"");
2533 char *shaderNamesSummary;
2537 const char *header =
"<div>shaders:<ul>";
2538 VuoInteger shaderNameLength = strlen(header);
2539 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2541 shaderNameLength += strlen(
"</ul></div>");
2543 shaderNamesSummary = (
char *)malloc(shaderNameLength + 1);
2544 char *t = shaderNamesSummary;
2545 t = strcpy(t, header) + strlen(header);
2546 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2548 t = strcpy(t,
"<li>") + strlen(
"<li>");
2550 t = strcpy(t,
"</li>") + strlen(
"</li>");
2552 t = strcpy(t,
"</ul></div>");
2555 shaderNamesSummary = strdup(
"");
2558 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",
2559 so->name ? so->name :
"",
2560 vertexCount, elementCount,
2563 childObjectCount, childObjectPlural,
2564 descendants, shaderNamesSummary);
2568 free(shaderNamesSummary);
2570 return valueAsString;
2578 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2580 for (
unsigned int i=0; i<level; ++i)
2581 fprintf(stderr,
"\t");
2585 fprintf(stderr,
"no object\n");
2590 if (so->type == VuoSceneObjectSubType_Mesh)
2592 fprintf(stderr,
"\n");
2594 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2597 for (
unsigned int i=1; i<=childObjectCount; ++i)
2627 __block
unsigned long triangleVertexCount = 0;
2628 __block
unsigned long trianglePrimitiveCount = 0;
2631 __block
unsigned long lineVertexCount = 0;
2632 __block
unsigned long linePrimitiveCount = 0;
2633 __block
double linePrimitiveSize = 0;
2635 __block
unsigned long pointVertexCount = 0;
2636 __block
unsigned long pointPrimitiveCount = 0;
2637 __block
double pointPrimitiveSize = 0;
2640 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2646 unsigned int vertexCount;
2647 VuoMesh_getCPUBuffers(co->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2653 triangleVertexCount += vertexCount;
2660 lineVertexCount += vertexCount;
2666 pointVertexCount += vertexCount;
2675 if (!trianglePrimitiveCount && !linePrimitiveCount && !pointPrimitiveCount)
2679 unsigned int *triangleElements =
nullptr;
2680 float *trianglePositions =
nullptr, *triangleNormals =
nullptr, *triangleTextureCoordinates =
nullptr;
2681 unsigned int *lineElements =
nullptr;
2682 float *linePositions =
nullptr, *lineNormals =
nullptr, *lineTextureCoordinates =
nullptr;
2683 unsigned int *pointElements =
nullptr;
2684 float *pointPositions =
nullptr, *pointNormals =
nullptr, *pointTextureCoordinates =
nullptr;
2685 if (trianglePrimitiveCount)
2686 VuoMesh_allocateCPUBuffers(triangleVertexCount, &trianglePositions, &triangleNormals, &triangleTextureCoordinates,
nullptr, trianglePrimitiveCount * 3, &triangleElements);
2687 if (linePrimitiveCount)
2688 VuoMesh_allocateCPUBuffers(lineVertexCount, &linePositions, &lineNormals, &lineTextureCoordinates,
nullptr, linePrimitiveCount * 2, &lineElements);
2689 if (pointPrimitiveCount)
2690 VuoMesh_allocateCPUBuffers(pointVertexCount, &pointPositions, &pointNormals, &pointTextureCoordinates,
nullptr, pointPrimitiveCount, &pointElements);
2693 __block
unsigned long triangleVertexIndex = 0;
2694 __block
unsigned long triangleElementIndex = 0;
2695 __block
unsigned long lineVertexIndex = 0;
2696 __block
unsigned long lineElementIndex = 0;
2697 __block
unsigned long pointVertexIndex = 0;
2698 __block
unsigned long pointElementIndex = 0;
2699 __block
bool anyTextureCoordinates =
false;
2701 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2707 unsigned int vertexCount, elementCount, *elements;
2708 float *positions, *normals, *textureCoordinates;
2709 VuoMesh_getCPUBuffers(co->mesh, &vertexCount, &positions, &normals, &textureCoordinates,
nullptr, &elementCount, &elements);
2711 if (textureCoordinates)
2712 anyTextureCoordinates =
true;
2718 unsigned long indexOffset = triangleVertexIndex;
2719 for (
unsigned int n = 0; n < vertexCount; ++n)
2732 if (textureCoordinates)
2735 ++triangleVertexIndex;
2741 for (
unsigned int n = 0; n < elementCount; ++n)
2742 triangleElements[triangleElementIndex++] = indexOffset + elements[n];
2744 for (
unsigned int n = 0; n < vertexCount; ++n)
2745 triangleElements[triangleElementIndex++] = indexOffset + n;
2751 for (
unsigned int n = 2; n < elementCount; ++n)
2754 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2755 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2756 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2760 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2761 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2762 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2765 for (
unsigned int n = 0; n < vertexCount; ++n)
2768 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2769 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2770 triangleElements[triangleElementIndex++] = indexOffset + n ;
2774 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2775 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2776 triangleElements[triangleElementIndex++] = indexOffset + n ;
2783 for (
unsigned int n = 2; n < elementCount; ++n)
2785 triangleElements[triangleElementIndex++] = indexOffset + elements[0 ];
2786 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2787 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2790 for (
unsigned int n = 2; n < vertexCount; ++n)
2792 triangleElements[triangleElementIndex++] = indexOffset + 0;
2793 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2794 triangleElements[triangleElementIndex++] = indexOffset + n;
2801 unsigned long indexOffset = lineVertexIndex;
2802 for (
unsigned int n = 0; n < vertexCount; ++n)
2815 if (textureCoordinates)
2824 for (
unsigned int n = 0; n < elementCount; ++n)
2825 lineElements[lineElementIndex++] = indexOffset + elements[n];
2827 for (
unsigned int n = 0; n < vertexCount; ++n)
2828 lineElements[lineElementIndex++] = indexOffset + n;
2834 for (
unsigned int n = 1; n < elementCount; ++n)
2836 lineElements[lineElementIndex++] = indexOffset + elements[n-1];
2837 lineElements[lineElementIndex++] = indexOffset + elements[n ];
2840 for (
unsigned int n = 1; n < vertexCount; ++n)
2842 lineElements[lineElementIndex++] = indexOffset + n-1;
2843 lineElements[lineElementIndex++] = indexOffset + n;
2849 unsigned long indexOffset = pointVertexIndex;
2850 for (
unsigned int n = 0; n < vertexCount; ++n)
2863 if (textureCoordinates)
2871 for (
unsigned int n = 0; n < elementCount; ++n)
2872 pointElements[pointElementIndex++] = indexOffset + elements[n];
2875 for (
unsigned int n = 0; n < vertexCount; ++n)
2876 pointElements[pointElementIndex++] = indexOffset + n;
2884 VuoMesh triangleMesh =
nullptr;
2887 if (trianglePrimitiveCount)
2889 if (!anyTextureCoordinates)
2891 free(triangleTextureCoordinates);
2892 triangleTextureCoordinates =
nullptr;
2897 if (linePrimitiveCount)
2899 if (!anyTextureCoordinates)
2901 free(lineTextureCoordinates);
2902 lineTextureCoordinates =
nullptr;
2907 if (pointPrimitiveCount)
2909 if (!anyTextureCoordinates)
2911 free(pointTextureCoordinates);
2912 pointTextureCoordinates =
nullptr;
2918 if (triangleMesh && !lineMesh && !pointMesh)
2920 else if (!triangleMesh && lineMesh && !pointMesh)
2922 else if (!triangleMesh && !lineMesh && pointMesh)
2939 #define CSGJS_HEADER_ONLY
2948 return csgjs_model();
2951 VuoSceneObject_internal *f = (VuoSceneObject_internal *)flat;
2953 return csgjs_model();
2958 return csgjs_model();
2960 unsigned int vertexCount, elementCount, *elements;
2961 float *positions, *normals, *textureCoordinates;
2962 VuoMesh_getCPUBuffers(f->mesh, &vertexCount, &positions, &normals, &textureCoordinates,
nullptr, &elementCount, &elements);
2965 for (
unsigned int n = 0; n < vertexCount; ++n)
2968 v.pos = csgjs_vector(positions[n * 3], positions[n * 3 + 1], positions[n * 3 + 2]);
2970 v.normal = csgjs_vector(normals[n * 3], normals[n * 3 + 1], normals[n * 3 + 2]);
2971 if (textureCoordinates)
2972 v.uv = csgjs_vector(textureCoordinates[n * 3], textureCoordinates[n * 3 + 1], 0);
2973 cm.vertices.push_back(v);
2975 for (
unsigned int n = 0; n < elementCount; ++n)
2976 cm.indices.push_back(elements[n]);
2986 unsigned int vertexCount = cm.vertices.size();
2987 unsigned int elementCount = cm.indices.size();
2988 unsigned int *elements;
2989 float *positions, *normals, *textureCoordinates;
2992 const csgjs_vertex *vertex = &cm.vertices[0];
2993 for (
unsigned int n = 0; n < vertexCount; ++n)
2995 positions[n * 3 ] = vertex[n].pos.x;
2996 positions[n * 3 + 1] = vertex[n].pos.y;
2997 positions[n * 3 + 2] = vertex[n].pos.z;
2998 normals[n * 3 ] = vertex[n].normal.x;
2999 normals[n * 3 + 1] = vertex[n].normal.y;
3000 normals[n * 3 + 2] = vertex[n].normal.z;
3001 textureCoordinates[n * 2 ] = vertex[n].uv.x;
3002 textureCoordinates[n * 2 + 1] = vertex[n].uv.y;
3005 const int *index = &cm.indices[0];
3006 for (
unsigned int n = 0; n < elementCount; ++n)
3007 elements[n] = index[n];
3031 if (objectCount == 0)
3033 if (objectCount == 1)
3036 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.union", DISPATCH_QUEUE_CONCURRENT);
3038 csgjs_model *models =
new csgjs_model[objectCount];
3039 for (
unsigned long i = 0; i < objectCount; ++i)
3040 dispatch_async(queue, ^{
3044 dispatch_barrier_sync(queue, ^{});
3045 dispatch_release(queue);
3047 csgjs_model cu = models[0];
3048 for (
unsigned long i = 1; i < objectCount; ++i)
3049 cu = csgjs_union(cu, models[i], epsilon);
3061 dispatch_semaphore_t finished = dispatch_semaphore_create(0);
3063 __block csgjs_model ca;
3064 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3066 dispatch_semaphore_signal(finished);
3071 dispatch_semaphore_wait(finished, DISPATCH_TIME_FOREVER);
3072 dispatch_release(finished);
3074 csgjs_model d = csgjs_difference(ca, cb, epsilon);
3086 if (objectCount == 0)
3088 if (objectCount == 1)
3091 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.intersect", DISPATCH_QUEUE_CONCURRENT);
3093 csgjs_model *models =
new csgjs_model[objectCount];
3094 for (
unsigned long i = 0; i < objectCount; ++i)
3095 dispatch_async(queue, ^{
3099 dispatch_barrier_sync(queue, ^{});
3100 dispatch_release(queue);
3102 csgjs_model ci = models[0];
3103 for (
unsigned long i = 1; i < objectCount; ++i)
3104 ci = csgjs_intersection(ci, models[i], epsilon);