13 #include <OpenGL/CGLMacro.h>
25 "title" :
"Scene Object",
26 "description" :
"A 3D Object: visible (mesh), or virtual (group, light, camera).",
42 "VuoList_VuoSceneObject"
69 bool preservePhysicalSize;
82 float confocalDistance;
83 float intraocularDistance;
85 float vignetteSharpness;
105 } VuoSceneObject_internal;
113 static uint64_t
id = 0;
114 return __sync_add_and_fetch(&
id, 1);
124 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
129 if (so->type == VuoSceneObjectSubType_Group)
131 else if (so->type == VuoSceneObjectSubType_Text)
145 VuoSceneObject_internal *so = (VuoSceneObject_internal *)calloc(1,
sizeof(VuoSceneObject_internal));
149 so->type = VuoSceneObjectSubType_Empty;
153 so->isRealSize =
false;
154 so->preservePhysicalSize =
false;
170 so->type = VuoSceneObjectSubType_Group;
174 so->transform = transform;
186 so->type = VuoSceneObjectSubType_Mesh;
195 so->transform = transform;
263 if (fixed == VuoOrientation_Horizontal)
266 height = image->pixelsHigh * size / image->pixelsWide;
270 width = image->pixelsWide * size / image->pixelsHigh;
296 if (fixed == VuoOrientation_Horizontal)
299 height = image->pixelsHigh * size / image->pixelsWide;
303 width = image->pixelsWide * size / image->pixelsHigh;
449 unsigned int _rows =
MAX(2,
MIN(512, rows));
450 unsigned int _columns =
MAX(2,
MIN(512, columns));
451 unsigned int _slices =
MAX(2,
MIN(512, slices));
525 so->type = VuoSceneObjectSubType_Text;
528 so->text.scaleWithScene = scaleWithScene;
529 so->text.wrapWidth = wrapWidth;
539 so->type = VuoSceneObjectSubType_PerspectiveCamera;
541 so->transform = transform;
542 so->camera.fieldOfView = fieldOfView;
543 so->camera.distanceMin = distanceMin;
544 so->camera.distanceMax = distanceMax;
554 so->type = VuoSceneObjectSubType_StereoCamera;
556 so->transform = transform;
557 so->camera.fieldOfView = fieldOfView;
558 so->camera.distanceMin = distanceMin;
559 so->camera.distanceMax = distanceMax;
560 so->camera.confocalDistance = confocalDistance;
561 so->camera.intraocularDistance = intraocularDistance;
571 so->type = VuoSceneObjectSubType_OrthographicCamera;
573 so->transform = transform;
574 so->camera.width = width;
575 so->camera.distanceMin = distanceMin;
576 so->camera.distanceMax = distanceMax;
586 so->type = VuoSceneObjectSubType_FisheyeCamera;
588 so->transform = transform;
589 so->camera.fieldOfView = fieldOfView;
592 so->camera.distanceMin = 0;
593 so->camera.distanceMax = 1000;
595 so->camera.vignetteWidth = vignetteWidth;
596 so->camera.vignetteSharpness = vignetteSharpness;
634 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
642 if (so->type == VuoSceneObjectSubType_Group)
647 for (
unsigned long i = 1; i <= childObjectCount; ++i)
675 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
677 if (so->id == idToMatch)
683 if (so->type == VuoSceneObjectSubType_Group)
688 for (
unsigned long i = 1; i <= childObjectCount; ++i)
716 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
718 if (so->type == typeToMatch)
724 if (so->type == VuoSceneObjectSubType_Group)
730 for (
unsigned long i = 1; i <= childObjectCount; ++i)
757 __block
bool didFindCamera =
false;
759 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
760 if ((co->type == VuoSceneObjectSubType_PerspectiveCamera
761 || co->type == VuoSceneObjectSubType_StereoCamera
762 || co->type == VuoSceneObjectSubType_OrthographicCamera
763 || co->type == VuoSceneObjectSubType_FisheyeCamera)
764 && (!nameToMatch || (co->name && nameToMatch && strstr(co->name, nameToMatch))))
766 *foundCamera = currentObject;
768 didFindCamera =
true;
774 return didFindCamera;
785 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
786 return so->type != VuoSceneObjectSubType_Empty;
794 if (strcmp(typeString,
"empty")==0)
795 return VuoSceneObjectSubType_Empty;
796 else if (strcmp(typeString,
"group")==0)
797 return VuoSceneObjectSubType_Group;
798 else if (strcmp(typeString,
"mesh")==0)
799 return VuoSceneObjectSubType_Mesh;
800 else if (strcmp(typeString,
"camera-perspective")==0)
801 return VuoSceneObjectSubType_PerspectiveCamera;
802 else if (strcmp(typeString,
"camera-stereo")==0)
803 return VuoSceneObjectSubType_StereoCamera;
804 else if (strcmp(typeString,
"camera-orthographic")==0)
805 return VuoSceneObjectSubType_OrthographicCamera;
806 else if (strcmp(typeString,
"camera-fisheye")==0)
807 return VuoSceneObjectSubType_FisheyeCamera;
808 else if (strcmp(typeString,
"light-ambient")==0)
809 return VuoSceneObjectSubType_AmbientLight;
810 else if (strcmp(typeString,
"light-point")==0)
811 return VuoSceneObjectSubType_PointLight;
812 else if (strcmp(typeString,
"light-spot")==0)
813 return VuoSceneObjectSubType_Spotlight;
814 else if (strcmp(typeString,
"text")==0)
815 return VuoSceneObjectSubType_Text;
817 return VuoSceneObjectSubType_Empty;
827 case VuoSceneObjectSubType_Group:
829 case VuoSceneObjectSubType_Mesh:
831 case VuoSceneObjectSubType_PerspectiveCamera:
832 return "camera-perspective";
833 case VuoSceneObjectSubType_StereoCamera:
834 return "camera-stereo";
835 case VuoSceneObjectSubType_OrthographicCamera:
836 return "camera-orthographic";
837 case VuoSceneObjectSubType_FisheyeCamera:
838 return "camera-fisheye";
839 case VuoSceneObjectSubType_AmbientLight:
840 return "light-ambient";
841 case VuoSceneObjectSubType_PointLight:
842 return "light-point";
843 case VuoSceneObjectSubType_Spotlight:
845 case VuoSceneObjectSubType_Text:
860 so->type = VuoSceneObjectSubType_AmbientLight;
862 so->light.color = color;
863 so->light.brightness = brightness;
880 so->type = VuoSceneObjectSubType_PointLight;
883 so->light.color = color;
884 so->light.brightness = brightness;
885 so->light.range = range;
886 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
905 so->type = VuoSceneObjectSubType_Spotlight;
907 so->light.color = color;
908 so->light.brightness = brightness;
909 so->light.cone = cone;
910 so->light.range = range;
911 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
912 so->transform = transform;
929 *ambientBrightness = 0;
934 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
935 if (co->type == VuoSceneObjectSubType_AmbientLight)
938 *ambientBrightness += co->light.brightness;
940 else if (co->type == VuoSceneObjectSubType_PointLight)
946 else if (co->type == VuoSceneObjectSubType_Spotlight)
960 *ambientBrightness = 0.05;
986 float modelviewMatrix[16];
1007 rootState.objectCount = 1;
1008 rootState.objects = &object;
1011 std::list<VuoSceneObject_treeState> objectsToVisit(1, rootState);
1012 while (!objectsToVisit.empty())
1015 objectsToVisit.pop_front();
1017 for (
long i = 0; i < currentState.objectCount; ++i)
1019 VuoSceneObject_internal *currentObject = (VuoSceneObject_internal *)currentState.objects[i];
1023 float localModelviewMatrix[16];
1025 float compositeModelviewMatrix[16];
1028 if (!
function((
VuoSceneObject)currentObject, compositeModelviewMatrix))
1031 if (currentObject->type == VuoSceneObjectSubType_Group)
1035 if (childObjectCount)
1038 childState.objectCount = childObjectCount;
1040 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
1041 objectsToVisit.push_front(childState);
1056 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1058 float localModelviewMatrix[16];
1060 float compositeModelviewMatrix[16];
1063 function(sceneObject, compositeModelviewMatrix);
1065 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
1068 for (
unsigned long i = 1; i <= childObjectCount; ++i)
1091 float localModelviewMatrix[16];
1107 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1121 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1122 so->transform.translation += translation;
1135 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1136 so->transform.scale *= scale;
1149 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1166 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1167 if (so->type != VuoSceneObjectSubType_Group)
1170 return so->childObjects;
1183 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1184 return so->blendMode;
1195 return VuoSceneObjectSubType_Empty;
1197 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1212 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1229 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1244 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1245 return so->isRealSize;
1260 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1261 return so->preservePhysicalSize;
1277 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1291 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1292 return so->text.text;
1305 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1306 return so->text.font;
1321 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1322 return so->text.scaleWithScene;
1335 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1336 return so->text.wrapWidth;
1349 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1350 return so->camera.fieldOfView;
1363 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1364 return so->camera.width;
1377 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1378 return so->camera.distanceMin;
1391 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1392 return so->camera.distanceMax;
1405 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1406 return so->camera.vignetteWidth;
1419 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1420 return so->camera.vignetteSharpness;
1433 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1434 return so->camera.intraocularDistance;
1447 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1448 return so->camera.confocalDistance;
1461 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1462 return so->light.color;
1475 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1476 return so->light.brightness;
1489 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1490 return so->light.range;
1503 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1504 return so->light.sharpness;
1517 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1518 return so->light.cone;
1531 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1532 return so->transform;
1543 return (VuoPoint3d){0,0,0};
1545 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1546 return so->transform.translation;
1559 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1574 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1588 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1604 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1605 if (so->type != VuoSceneObjectSubType_Group)
1610 so->childObjects = childObjects;
1623 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1639 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1640 so->transform = transform;
1653 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1654 so->transform.translation = translation;
1667 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1668 so->transform.scale = scale;
1681 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1684 so->shader = shader;
1720 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
1721 co->blendMode = blendMode;
1736 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1737 so->isRealSize = isRealSize;
1751 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1752 so->preservePhysicalSize = shouldPreservePhysicalSize;
1765 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1768 so->text.text = text;
1781 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1784 so->text.font = font;
1797 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1798 so->camera.fieldOfView = fieldOfView;
1811 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1812 so->camera.distanceMin = distanceMin;
1825 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1826 so->camera.distanceMax = distanceMax;
1844 VuoSceneObject_internal *o = (VuoSceneObject_internal *)
object;
1851 co->transform = o->transform;
1854 co->isRealSize = o->isRealSize;
1855 co->preservePhysicalSize = o->preservePhysicalSize;
1856 co->blendMode = o->blendMode;
1858 if (o->type == VuoSceneObjectSubType_Group && o->childObjects)
1863 VuoListAppendValue_VuoSceneObject(co->childObjects, VuoSceneObject_copy(object));
1868 if (o->type == VuoSceneObjectSubType_PerspectiveCamera
1869 || o->type == VuoSceneObjectSubType_StereoCamera
1870 || o->type == VuoSceneObjectSubType_OrthographicCamera
1871 || o->type == VuoSceneObjectSubType_FisheyeCamera)
1873 co->camera.fieldOfView = o->camera.fieldOfView;
1874 co->camera.width = o->camera.width;
1875 co->camera.distanceMin = o->camera.distanceMin;
1876 co->camera.distanceMax = o->camera.distanceMax;
1877 co->camera.confocalDistance = o->camera.confocalDistance;
1878 co->camera.intraocularDistance = o->camera.intraocularDistance;
1879 co->camera.vignetteWidth = o->camera.vignetteWidth;
1880 co->camera.vignetteSharpness = o->camera.vignetteSharpness;
1882 else if (o->type == VuoSceneObjectSubType_AmbientLight
1883 || o->type == VuoSceneObjectSubType_PointLight
1884 || o->type == VuoSceneObjectSubType_Spotlight)
1886 co->light.color = o->light.color;
1887 co->light.brightness = o->light.brightness;
1888 co->light.range = o->light.range;
1889 co->light.cone = o->light.cone;
1890 co->light.sharpness = o->light.sharpness;
1892 else if (o->type == VuoSceneObjectSubType_Text)
1896 co->text.scaleWithScene = o->text.scaleWithScene;
1897 co->text.wrapWidth = o->text.wrapWidth;
1909 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1911 __block
bool haveGlobalBounds =
false;
1912 __block
VuoBox globalBounds;
1920 haveGlobalBounds =
true;
1925 if (haveGlobalBounds)
1926 return globalBounds;
1928 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1942 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1944 || so->type == VuoSceneObjectSubType_Text)
1956 bounds->size.x *= so->shader->objectScale;
1957 bounds->size.y *= so->shader->objectScale;
1958 bounds->size.z *= so->shader->objectScale;
1973 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1975 so->transform.translation =
VuoPoint3d_subtract(so->transform.translation, bounds.center);
1987 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1990 float scale = fmax(fmax(bounds.size.x, bounds.size.y), bounds.size.z);
1991 if (fabs(scale) < 0.00001)
2028 if (json_object_object_get_ex(js,
"id", &o))
2029 id = json_object_get_int64(o);
2032 if (json_object_object_get_ex(js,
"type", &o))
2036 if (json_object_object_get_ex(js,
"mesh", &o))
2040 if (json_object_object_get_ex(js,
"shader", &o))
2043 bool isRealSize =
false;
2044 if (json_object_object_get_ex(js,
"isRealSize", &o))
2047 bool preservePhysicalSize =
false;
2048 if (json_object_object_get_ex(js,
"preservePhysicalSize", &o))
2052 if (json_object_object_get_ex(js,
"blendMode", &o))
2056 if (json_object_object_get_ex(js,
"childObjects", &o))
2059 float cameraFieldOfView;
2060 if (json_object_object_get_ex(js,
"cameraFieldOfView", &o))
2061 cameraFieldOfView = json_object_get_double(o);
2064 if (json_object_object_get_ex(js,
"cameraWidth", &o))
2065 cameraWidth = json_object_get_double(o);
2067 float cameraDistanceMin;
2068 if (json_object_object_get_ex(js,
"cameraDistanceMin", &o))
2069 cameraDistanceMin = json_object_get_double(o);
2071 float cameraDistanceMax;
2072 if (json_object_object_get_ex(js,
"cameraDistanceMax", &o))
2073 cameraDistanceMax = json_object_get_double(o);
2075 float cameraConfocalDistance;
2076 if (json_object_object_get_ex(js,
"cameraConfocalDistance", &o))
2077 cameraConfocalDistance = json_object_get_double(o);
2079 float cameraIntraocularDistance;
2080 if (json_object_object_get_ex(js,
"cameraIntraocularDistance", &o))
2081 cameraIntraocularDistance = json_object_get_double(o);
2083 float cameraVignetteWidth;
2084 if (json_object_object_get_ex(js,
"cameraVignetteWidth", &o))
2085 cameraVignetteWidth = json_object_get_double(o);
2087 float cameraVignetteSharpness;
2088 if (json_object_object_get_ex(js,
"cameraVignetteSharpness", &o))
2089 cameraVignetteSharpness = json_object_get_double(o);
2092 if (json_object_object_get_ex(js,
"lightColor", &o))
2095 float lightBrightness;
2096 if (json_object_object_get_ex(js,
"lightBrightness", &o))
2097 lightBrightness = json_object_get_double(o);
2100 if (json_object_object_get_ex(js,
"lightCone", &o))
2101 lightCone = json_object_get_double(o);
2104 if (json_object_object_get_ex(js,
"lightRange", &o))
2105 lightRange = json_object_get_double(o);
2107 float lightSharpness;
2108 if (json_object_object_get_ex(js,
"lightSharpness", &o))
2109 lightSharpness = json_object_get_double(o);
2112 if (json_object_object_get_ex(js,
"name", &o))
2115 json_object_object_get_ex(js,
"transform", &o);
2119 if (json_object_object_get_ex(js,
"text", &o))
2123 if (json_object_object_get_ex(js,
"textFont", &o))
2126 bool scaleWithScene =
false;
2127 if (json_object_object_get_ex(js,
"textScaleWithScene", &o))
2130 float wrapWidth = INFINITY;
2131 if (json_object_object_get_ex(js,
"textWrapWidth", &o))
2132 wrapWidth = json_object_get_double(o);
2137 case VuoSceneObjectSubType_Empty:
2140 case VuoSceneObjectSubType_Group:
2143 case VuoSceneObjectSubType_Mesh:
2146 VuoSceneObject_internal *so = (VuoSceneObject_internal *)obj;
2147 so->isRealSize = isRealSize;
2148 so->preservePhysicalSize = preservePhysicalSize;
2149 so->blendMode = blendMode;
2153 case VuoSceneObjectSubType_PerspectiveCamera:
2162 case VuoSceneObjectSubType_StereoCamera:
2169 cameraConfocalDistance,
2170 cameraIntraocularDistance
2173 case VuoSceneObjectSubType_OrthographicCamera:
2182 case VuoSceneObjectSubType_FisheyeCamera:
2187 cameraVignetteWidth,
2188 cameraVignetteSharpness
2191 case VuoSceneObjectSubType_AmbientLight:
2194 case VuoSceneObjectSubType_PointLight:
2197 case VuoSceneObjectSubType_Spotlight:
2200 case VuoSceneObjectSubType_Text:
2220 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2224 json_object_object_add(js,
"id", json_object_new_int64(so->id));
2229 case VuoSceneObjectSubType_Empty:
2232 case VuoSceneObjectSubType_Mesh:
2241 json_object_object_add(js,
"preservePhysicalSize",
VuoBoolean_getJson(so->preservePhysicalSize));
2247 case VuoSceneObjectSubType_Group:
2248 if (so->childObjects)
2252 case VuoSceneObjectSubType_PerspectiveCamera:
2253 case VuoSceneObjectSubType_StereoCamera:
2254 case VuoSceneObjectSubType_OrthographicCamera:
2255 case VuoSceneObjectSubType_FisheyeCamera:
2257 if (so->type != VuoSceneObjectSubType_FisheyeCamera)
2259 json_object_object_add(js,
"cameraDistanceMin", json_object_new_double(so->camera.distanceMin));
2260 json_object_object_add(js,
"cameraDistanceMax", json_object_new_double(so->camera.distanceMax));
2263 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2264 || so->type == VuoSceneObjectSubType_StereoCamera
2265 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2266 json_object_object_add(js,
"cameraFieldOfView", json_object_new_double(so->camera.fieldOfView));
2268 if (so->type == VuoSceneObjectSubType_StereoCamera)
2270 json_object_object_add(js,
"cameraConfocalDistance", json_object_new_double(so->camera.confocalDistance));
2271 json_object_object_add(js,
"cameraIntraocularDistance", json_object_new_double(so->camera.intraocularDistance));
2274 if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2275 json_object_object_add(js,
"cameraWidth", json_object_new_double(so->camera.width));
2277 if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2279 json_object_object_add(js,
"cameraVignetteWidth", json_object_new_double(so->camera.vignetteWidth));
2280 json_object_object_add(js,
"cameraVignetteSharpness", json_object_new_double(so->camera.vignetteSharpness));
2286 case VuoSceneObjectSubType_AmbientLight:
2287 case VuoSceneObjectSubType_PointLight:
2288 case VuoSceneObjectSubType_Spotlight:
2290 json_object_object_add(js,
"lightColor",
VuoColor_getJson(so->light.color));
2291 json_object_object_add(js,
"lightBrightness", json_object_new_double(so->light.brightness));
2293 if (so->type == VuoSceneObjectSubType_PointLight
2294 || so->type == VuoSceneObjectSubType_Spotlight)
2296 json_object_object_add(js,
"lightRange", json_object_new_double(so->light.range));
2297 json_object_object_add(js,
"lightSharpness", json_object_new_double(so->light.sharpness));
2299 if (so->type == VuoSceneObjectSubType_Spotlight)
2300 json_object_object_add(js,
"lightCone", json_object_new_double(so->light.cone));
2305 case VuoSceneObjectSubType_Text:
2310 json_object_object_add(js,
"textFont",
VuoFont_getJson(so->text.font));
2315 json_object_object_add(js,
"textScaleWithScene",
VuoBoolean_getJson(so->text.scaleWithScene));
2316 json_object_object_add(js,
"textWrapWidth",
VuoReal_getJson(so->text.wrapWidth));
2325 if (so->type != VuoSceneObjectSubType_AmbientLight)
2339 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2343 unsigned int vertexCount;
2344 VuoMesh_getCPUBuffers(so->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2356 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2360 unsigned int elementCount;
2361 VuoMesh_getCPUBuffers(so->mesh,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, &elementCount,
nullptr);
2362 return elementCount;
2375 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2376 unsigned long childObjectCount = 0;
2377 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2379 *descendantCount += childObjectCount;
2383 if (so->type == VuoSceneObjectSubType_Group)
2384 for (
unsigned long i = 1; i <= childObjectCount; ++i)
2397 __block
json_object *names = json_object_new_object();
2399 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2401 json_object_object_add(names, co->shader->name, NULL);
2406 json_object_object_foreach(names, key, val)
2408 json_object_put(names);
2418 return strdup(
"No object");
2420 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2422 if (so->type == VuoSceneObjectSubType_Text)
2425 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);
2430 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2431 || so->type == VuoSceneObjectSubType_StereoCamera
2432 || so->type == VuoSceneObjectSubType_OrthographicCamera
2433 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2436 type[0] = toupper(type[0]);
2438 float cameraViewValue = 0;
2439 const char *cameraViewString =
"";
2440 if (so->type == VuoSceneObjectSubType_PerspectiveCamera)
2442 cameraViewValue = so->camera.fieldOfView;
2443 cameraViewString =
"° field of view";
2445 else if (so->type == VuoSceneObjectSubType_StereoCamera)
2447 cameraViewValue = so->camera.fieldOfView;
2448 cameraViewString =
"° field of view (stereoscopic)";
2450 else if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2452 cameraViewValue = so->camera.width;
2453 cameraViewString =
" unit width";
2455 else if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2457 cameraViewValue = so->camera.fieldOfView;
2458 cameraViewString =
"° field of view (fisheye)";
2463 const char *rotationLabel;
2464 char *rotationString;
2465 if (so->transform.type == VuoTransformTypeEuler)
2467 rotationLabel =
"Rotated";
2472 rotationLabel =
"Target";
2476 char *valueAsString =
VuoText_format(
"<div>%s named \"%s\"</div>\n<div>At (%s)</div>\n<div>%s (%s)</div>\n<div>%g%s</div>\n<div>Shows objects between depth %g and %g</div>",
2477 type, so->name ? so->name :
"",
2479 rotationLabel, rotationString,
2480 cameraViewValue, cameraViewString,
2481 so->camera.distanceMin, so->camera.distanceMax);
2482 free(rotationString);
2483 free(translationString);
2485 return valueAsString;
2488 if (so->type == VuoSceneObjectSubType_AmbientLight
2489 || so->type == VuoSceneObjectSubType_PointLight
2490 || so->type == VuoSceneObjectSubType_Spotlight)
2493 type[0] = toupper(type[0]);
2497 char *positionRangeString;
2498 if (so->type == VuoSceneObjectSubType_PointLight
2499 || so->type == VuoSceneObjectSubType_Spotlight)
2503 positionRangeString =
VuoText_format(
"\n<div>Position (%s)</div>\n<div>Range %g units (%g sharpness)</div>",
2504 positionString, so->light.range, so->light.sharpness);
2506 free(positionString);
2509 positionRangeString = strdup(
"");
2511 char *directionConeString;
2512 if (so->type == VuoSceneObjectSubType_Spotlight)
2517 directionConeString =
VuoText_format(
"\n<div>Direction (%s)</div>\n<div>Cone %g°</div>",
2518 directionString, so->light.cone * 180./M_PI);
2520 free(directionString);
2523 directionConeString = strdup(
"");
2525 char *valueAsString =
VuoText_format(
"<div>%s</div>\n<div>Color %s</div>\n<div>Brightness %g</div>%s%s",
2526 type, colorString, so->light.brightness, positionRangeString, directionConeString);
2528 free(directionConeString);
2529 free(positionRangeString);
2533 return valueAsString;
2541 unsigned long childObjectCount = 0;
2542 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2544 const char *childObjectPlural = childObjectCount == 1 ?
"" :
"s";
2547 if (childObjectCount)
2549 unsigned long descendantCount = 0;
2550 unsigned long totalVertexCount = 0;
2551 unsigned long totalElementCount = 0;
2553 const char *descendantPlural = descendantCount == 1 ?
"" :
"s";
2555 descendants =
VuoText_format(
"\n<div>%ld descendant%s</div>\n<div>Total, including descendants:</div>\n<div>%ld vertices, %ld elements</div>",
2556 descendantCount, descendantPlural, totalVertexCount, totalElementCount);
2559 descendants = strdup(
"");
2563 char *shaderNamesSummary;
2567 const char *header =
"\n<div>Shaders:<ul>";
2569 VuoInteger shaderNameLength = strlen(header);
2570 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2572 shaderNameLength += strlen(
"</ul></div>");
2574 shaderNamesSummary = (
char *)malloc(shaderNameLength + 1);
2575 char *t = shaderNamesSummary;
2576 t = strcpy(t, header) + strlen(header);
2577 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2579 t = strcpy(t,
"\n<li>") + strlen(
"\n<li>");
2581 t = strcpy(t,
"</li>") + strlen(
"</li>");
2583 t = strcpy(t,
"</ul></div>");
2586 shaderNamesSummary = strdup(
"");
2591 name =
VuoText_format(
"<div>Object named \"%s\"</div>\n", so->name);
2593 char *valueAsString =
VuoText_format(
"%s<div>%ld vertices, %ld elements</div>\n<div>%s</div>\n<div>ID %lld</div>\n<div>%ld child object%s</div>%s%s",
2595 vertexCount, elementCount,
2598 childObjectCount, childObjectPlural,
2599 descendants, shaderNamesSummary);
2604 free(shaderNamesSummary);
2606 return valueAsString;
2614 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2616 for (
unsigned int i=0; i<level; ++i)
2617 fprintf(stderr,
"\t");
2621 fprintf(stderr,
"no object\n");
2626 if (so->type == VuoSceneObjectSubType_Mesh)
2628 fprintf(stderr,
"\n");
2630 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2633 for (
unsigned int i=1; i<=childObjectCount; ++i)
2663 __block
unsigned long triangleVertexCount = 0;
2664 __block
unsigned long trianglePrimitiveCount = 0;
2667 __block
unsigned long lineVertexCount = 0;
2668 __block
unsigned long linePrimitiveCount = 0;
2669 __block
double linePrimitiveSize = 0;
2671 __block
unsigned long pointVertexCount = 0;
2672 __block
unsigned long pointPrimitiveCount = 0;
2673 __block
double pointPrimitiveSize = 0;
2676 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2682 unsigned int vertexCount;
2683 VuoMesh_getCPUBuffers(co->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2689 triangleVertexCount += vertexCount;
2696 lineVertexCount += vertexCount;
2702 pointVertexCount += vertexCount;
2711 if (!trianglePrimitiveCount && !linePrimitiveCount && !pointPrimitiveCount)
2715 unsigned int *triangleElements =
nullptr;
2716 float *trianglePositions =
nullptr, *triangleNormals =
nullptr, *triangleTextureCoordinates =
nullptr;
2717 unsigned int *lineElements =
nullptr;
2718 float *linePositions =
nullptr, *lineNormals =
nullptr, *lineTextureCoordinates =
nullptr;
2719 unsigned int *pointElements =
nullptr;
2720 float *pointPositions =
nullptr, *pointNormals =
nullptr, *pointTextureCoordinates =
nullptr;
2721 if (trianglePrimitiveCount)
2722 VuoMesh_allocateCPUBuffers(triangleVertexCount, &trianglePositions, &triangleNormals, &triangleTextureCoordinates,
nullptr, trianglePrimitiveCount * 3, &triangleElements);
2723 if (linePrimitiveCount)
2724 VuoMesh_allocateCPUBuffers(lineVertexCount, &linePositions, &lineNormals, &lineTextureCoordinates,
nullptr, linePrimitiveCount * 2, &lineElements);
2725 if (pointPrimitiveCount)
2726 VuoMesh_allocateCPUBuffers(pointVertexCount, &pointPositions, &pointNormals, &pointTextureCoordinates,
nullptr, pointPrimitiveCount, &pointElements);
2729 __block
unsigned long triangleVertexIndex = 0;
2730 __block
unsigned long triangleElementIndex = 0;
2731 __block
unsigned long lineVertexIndex = 0;
2732 __block
unsigned long lineElementIndex = 0;
2733 __block
unsigned long pointVertexIndex = 0;
2734 __block
unsigned long pointElementIndex = 0;
2735 __block
bool anyTextureCoordinates =
false;
2737 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2743 unsigned int vertexCount, elementCount, *elements;
2744 float *positions, *normals, *textureCoordinates;
2745 VuoMesh_getCPUBuffers(co->mesh, &vertexCount, &positions, &normals, &textureCoordinates,
nullptr, &elementCount, &elements);
2747 if (textureCoordinates)
2748 anyTextureCoordinates =
true;
2754 unsigned long indexOffset = triangleVertexIndex;
2755 for (
unsigned int n = 0; n < vertexCount; ++n)
2768 if (textureCoordinates)
2771 ++triangleVertexIndex;
2777 for (
unsigned int n = 0; n < elementCount; ++n)
2778 triangleElements[triangleElementIndex++] = indexOffset + elements[n];
2780 for (
unsigned int n = 0; n < vertexCount; ++n)
2781 triangleElements[triangleElementIndex++] = indexOffset + n;
2787 for (
unsigned int n = 2; n < elementCount; ++n)
2790 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2791 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2792 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2796 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2797 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2798 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2801 for (
unsigned int n = 0; n < vertexCount; ++n)
2804 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2805 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2806 triangleElements[triangleElementIndex++] = indexOffset + n ;
2810 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2811 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2812 triangleElements[triangleElementIndex++] = indexOffset + n ;
2819 for (
unsigned int n = 2; n < elementCount; ++n)
2821 triangleElements[triangleElementIndex++] = indexOffset + elements[0 ];
2822 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2823 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2826 for (
unsigned int n = 2; n < vertexCount; ++n)
2828 triangleElements[triangleElementIndex++] = indexOffset + 0;
2829 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2830 triangleElements[triangleElementIndex++] = indexOffset + n;
2837 unsigned long indexOffset = lineVertexIndex;
2838 for (
unsigned int n = 0; n < vertexCount; ++n)
2851 if (textureCoordinates)
2860 for (
unsigned int n = 0; n < elementCount; ++n)
2861 lineElements[lineElementIndex++] = indexOffset + elements[n];
2863 for (
unsigned int n = 0; n < vertexCount; ++n)
2864 lineElements[lineElementIndex++] = indexOffset + n;
2870 for (
unsigned int n = 1; n < elementCount; ++n)
2872 lineElements[lineElementIndex++] = indexOffset + elements[n-1];
2873 lineElements[lineElementIndex++] = indexOffset + elements[n ];
2876 for (
unsigned int n = 1; n < vertexCount; ++n)
2878 lineElements[lineElementIndex++] = indexOffset + n-1;
2879 lineElements[lineElementIndex++] = indexOffset + n;
2885 unsigned long indexOffset = pointVertexIndex;
2886 for (
unsigned int n = 0; n < vertexCount; ++n)
2899 if (textureCoordinates)
2907 for (
unsigned int n = 0; n < elementCount; ++n)
2908 pointElements[pointElementIndex++] = indexOffset + elements[n];
2911 for (
unsigned int n = 0; n < vertexCount; ++n)
2912 pointElements[pointElementIndex++] = indexOffset + n;
2920 VuoMesh triangleMesh =
nullptr;
2923 if (trianglePrimitiveCount)
2925 if (!anyTextureCoordinates)
2927 free(triangleTextureCoordinates);
2928 triangleTextureCoordinates =
nullptr;
2933 if (linePrimitiveCount)
2935 if (!anyTextureCoordinates)
2937 free(lineTextureCoordinates);
2938 lineTextureCoordinates =
nullptr;
2943 if (pointPrimitiveCount)
2945 if (!anyTextureCoordinates)
2947 free(pointTextureCoordinates);
2948 pointTextureCoordinates =
nullptr;
2954 if (triangleMesh && !lineMesh && !pointMesh)
2956 else if (!triangleMesh && lineMesh && !pointMesh)
2958 else if (!triangleMesh && !lineMesh && pointMesh)
2975 #define CSGJS_HEADER_ONLY
2984 return csgjs_model();
2987 VuoSceneObject_internal *f = (VuoSceneObject_internal *)flat;
2989 return csgjs_model();
2994 return csgjs_model();
2996 unsigned int vertexCount, elementCount, *elements;
2997 float *positions, *normals, *textureCoordinates;
2998 VuoMesh_getCPUBuffers(f->mesh, &vertexCount, &positions, &normals, &textureCoordinates,
nullptr, &elementCount, &elements);
3001 for (
unsigned int n = 0; n < vertexCount; ++n)
3004 v.pos = csgjs_vector(positions[n * 3], positions[n * 3 + 1], positions[n * 3 + 2]);
3006 v.normal = csgjs_vector(normals[n * 3], normals[n * 3 + 1], normals[n * 3 + 2]);
3007 if (textureCoordinates)
3008 v.uv = csgjs_vector(textureCoordinates[n * 3], textureCoordinates[n * 3 + 1], 0);
3009 cm.vertices.push_back(v);
3011 for (
unsigned int n = 0; n < elementCount; ++n)
3012 cm.indices.push_back(elements[n]);
3022 unsigned int vertexCount = cm.vertices.size();
3023 unsigned int elementCount = cm.indices.size();
3024 unsigned int *elements;
3025 float *positions, *normals, *textureCoordinates;
3028 const csgjs_vertex *vertex = &cm.vertices[0];
3029 for (
unsigned int n = 0; n < vertexCount; ++n)
3031 positions[n * 3 ] = vertex[n].pos.x;
3032 positions[n * 3 + 1] = vertex[n].pos.y;
3033 positions[n * 3 + 2] = vertex[n].pos.z;
3034 normals[n * 3 ] = vertex[n].normal.x;
3035 normals[n * 3 + 1] = vertex[n].normal.y;
3036 normals[n * 3 + 2] = vertex[n].normal.z;
3037 textureCoordinates[n * 2 ] = vertex[n].uv.x;
3038 textureCoordinates[n * 2 + 1] = vertex[n].uv.y;
3041 const int *index = &cm.indices[0];
3042 for (
unsigned int n = 0; n < elementCount; ++n)
3043 elements[n] = index[n];
3067 if (objectCount == 0)
3069 if (objectCount == 1)
3072 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.union", DISPATCH_QUEUE_CONCURRENT);
3074 csgjs_model *models =
new csgjs_model[objectCount];
3075 for (
unsigned long i = 0; i < objectCount; ++i)
3076 dispatch_async(queue, ^{
3080 dispatch_barrier_sync(queue, ^{});
3081 dispatch_release(queue);
3083 csgjs_model cu = models[0];
3084 for (
unsigned long i = 1; i < objectCount; ++i)
3085 cu = csgjs_union(cu, models[i], epsilon);
3097 dispatch_semaphore_t finished = dispatch_semaphore_create(0);
3099 __block csgjs_model ca;
3100 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3102 dispatch_semaphore_signal(finished);
3107 dispatch_semaphore_wait(finished, DISPATCH_TIME_FOREVER);
3108 dispatch_release(finished);
3110 csgjs_model d = csgjs_difference(ca, cb, epsilon);
3122 if (objectCount == 0)
3124 if (objectCount == 1)
3127 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.intersect", DISPATCH_QUEUE_CONCURRENT);
3129 csgjs_model *models =
new csgjs_model[objectCount];
3130 for (
unsigned long i = 0; i < objectCount; ++i)
3131 dispatch_async(queue, ^{
3135 dispatch_barrier_sync(queue, ^{});
3136 dispatch_release(queue);
3138 csgjs_model ci = models[0];
3139 for (
unsigned long i = 1; i < objectCount; ++i)
3140 ci = csgjs_intersection(ci, models[i], epsilon);