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;
262 if (fixed == VuoOrientation_Horizontal)
265 height = image->pixelsHigh * size / image->pixelsWide;
269 width = image->pixelsWide * size / image->pixelsHigh;
295 if (fixed == VuoOrientation_Horizontal)
298 height = image->pixelsHigh * size / image->pixelsWide;
302 width = image->pixelsWide * size / image->pixelsHigh;
448 unsigned int _rows =
MAX(2,
MIN(512, rows));
449 unsigned int _columns =
MAX(2,
MIN(512, columns));
450 unsigned int _slices =
MAX(2,
MIN(512, slices));
524 so->type = VuoSceneObjectSubType_Text;
527 so->text.scaleWithScene = scaleWithScene;
528 so->text.wrapWidth = wrapWidth;
538 so->type = VuoSceneObjectSubType_PerspectiveCamera;
540 so->transform = transform;
541 so->camera.fieldOfView = fieldOfView;
542 so->camera.distanceMin = distanceMin;
543 so->camera.distanceMax = distanceMax;
553 so->type = VuoSceneObjectSubType_StereoCamera;
555 so->transform = transform;
556 so->camera.fieldOfView = fieldOfView;
557 so->camera.distanceMin = distanceMin;
558 so->camera.distanceMax = distanceMax;
559 so->camera.confocalDistance = confocalDistance;
560 so->camera.intraocularDistance = intraocularDistance;
570 so->type = VuoSceneObjectSubType_OrthographicCamera;
572 so->transform = transform;
573 so->camera.width = width;
574 so->camera.distanceMin = distanceMin;
575 so->camera.distanceMax = distanceMax;
585 so->type = VuoSceneObjectSubType_FisheyeCamera;
587 so->transform = transform;
588 so->camera.fieldOfView = fieldOfView;
591 so->camera.distanceMin = 0;
592 so->camera.distanceMax = 1000;
594 so->camera.vignetteWidth = vignetteWidth;
595 so->camera.vignetteSharpness = vignetteSharpness;
633 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
641 if (so->type == VuoSceneObjectSubType_Group)
646 for (
unsigned long i = 1; i <= childObjectCount; ++i)
674 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
676 if (so->id == idToMatch)
682 if (so->type == VuoSceneObjectSubType_Group)
687 for (
unsigned long i = 1; i <= childObjectCount; ++i)
715 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
717 if (so->type == typeToMatch)
723 if (so->type == VuoSceneObjectSubType_Group)
729 for (
unsigned long i = 1; i <= childObjectCount; ++i)
756 __block
bool didFindCamera =
false;
758 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
759 if ((co->type == VuoSceneObjectSubType_PerspectiveCamera
760 || co->type == VuoSceneObjectSubType_StereoCamera
761 || co->type == VuoSceneObjectSubType_OrthographicCamera
762 || co->type == VuoSceneObjectSubType_FisheyeCamera)
763 && (!nameToMatch || (co->name && nameToMatch && strstr(co->name, nameToMatch))))
765 *foundCamera = currentObject;
767 didFindCamera =
true;
773 return didFindCamera;
784 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
785 return so->type != VuoSceneObjectSubType_Empty;
793 if (strcmp(typeString,
"empty")==0)
794 return VuoSceneObjectSubType_Empty;
795 else if (strcmp(typeString,
"group")==0)
796 return VuoSceneObjectSubType_Group;
797 else if (strcmp(typeString,
"mesh")==0)
798 return VuoSceneObjectSubType_Mesh;
799 else if (strcmp(typeString,
"camera-perspective")==0)
800 return VuoSceneObjectSubType_PerspectiveCamera;
801 else if (strcmp(typeString,
"camera-stereo")==0)
802 return VuoSceneObjectSubType_StereoCamera;
803 else if (strcmp(typeString,
"camera-orthographic")==0)
804 return VuoSceneObjectSubType_OrthographicCamera;
805 else if (strcmp(typeString,
"camera-fisheye")==0)
806 return VuoSceneObjectSubType_FisheyeCamera;
807 else if (strcmp(typeString,
"light-ambient")==0)
808 return VuoSceneObjectSubType_AmbientLight;
809 else if (strcmp(typeString,
"light-point")==0)
810 return VuoSceneObjectSubType_PointLight;
811 else if (strcmp(typeString,
"light-spot")==0)
812 return VuoSceneObjectSubType_Spotlight;
813 else if (strcmp(typeString,
"text")==0)
814 return VuoSceneObjectSubType_Text;
816 return VuoSceneObjectSubType_Empty;
826 case VuoSceneObjectSubType_Group:
828 case VuoSceneObjectSubType_Mesh:
830 case VuoSceneObjectSubType_PerspectiveCamera:
831 return "camera-perspective";
832 case VuoSceneObjectSubType_StereoCamera:
833 return "camera-stereo";
834 case VuoSceneObjectSubType_OrthographicCamera:
835 return "camera-orthographic";
836 case VuoSceneObjectSubType_FisheyeCamera:
837 return "camera-fisheye";
838 case VuoSceneObjectSubType_AmbientLight:
839 return "light-ambient";
840 case VuoSceneObjectSubType_PointLight:
841 return "light-point";
842 case VuoSceneObjectSubType_Spotlight:
844 case VuoSceneObjectSubType_Text:
859 so->type = VuoSceneObjectSubType_AmbientLight;
861 so->light.color = color;
862 so->light.brightness = brightness;
879 so->type = VuoSceneObjectSubType_PointLight;
882 so->light.color = color;
883 so->light.brightness = brightness;
884 so->light.range = range;
885 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
904 so->type = VuoSceneObjectSubType_Spotlight;
906 so->light.color = color;
907 so->light.brightness = brightness;
908 so->light.cone = cone;
909 so->light.range = range;
910 so->light.sharpness =
MAX(
MIN(sharpness,1),0);
911 so->transform = transform;
928 *ambientBrightness = 0;
933 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
934 if (co->type == VuoSceneObjectSubType_AmbientLight)
937 *ambientBrightness += co->light.brightness;
939 else if (co->type == VuoSceneObjectSubType_PointLight)
945 else if (co->type == VuoSceneObjectSubType_Spotlight)
959 *ambientBrightness = 0.05;
985 float modelviewMatrix[16];
1006 rootState.objectCount = 1;
1007 rootState.objects = &object;
1010 std::list<VuoSceneObject_treeState> objectsToVisit(1, rootState);
1011 while (!objectsToVisit.empty())
1014 objectsToVisit.pop_front();
1016 for (
long i = 0; i < currentState.objectCount; ++i)
1018 VuoSceneObject_internal *currentObject = (VuoSceneObject_internal *)currentState.objects[i];
1022 float localModelviewMatrix[16];
1024 float compositeModelviewMatrix[16];
1027 if (!
function((
VuoSceneObject)currentObject, compositeModelviewMatrix))
1030 if (currentObject->type == VuoSceneObjectSubType_Group)
1034 if (childObjectCount)
1037 childState.objectCount = childObjectCount;
1039 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
1040 objectsToVisit.push_front(childState);
1055 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1057 float localModelviewMatrix[16];
1059 float compositeModelviewMatrix[16];
1062 function(sceneObject, compositeModelviewMatrix);
1064 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
1067 for (
unsigned long i = 1; i <= childObjectCount; ++i)
1090 float localModelviewMatrix[16];
1106 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1120 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1121 so->transform.translation += translation;
1134 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1135 so->transform.scale *= scale;
1148 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1165 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1166 if (so->type != VuoSceneObjectSubType_Group)
1169 return so->childObjects;
1182 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1183 return so->blendMode;
1194 return VuoSceneObjectSubType_Empty;
1196 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1211 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1228 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1243 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1244 return so->isRealSize;
1259 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1260 return so->preservePhysicalSize;
1276 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1290 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1291 return so->text.text;
1304 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1305 return so->text.font;
1320 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1321 return so->text.scaleWithScene;
1334 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1335 return so->text.wrapWidth;
1348 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1349 return so->camera.fieldOfView;
1362 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1363 return so->camera.width;
1376 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1377 return so->camera.distanceMin;
1390 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1391 return so->camera.distanceMax;
1404 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1405 return so->camera.vignetteWidth;
1418 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1419 return so->camera.vignetteSharpness;
1432 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1433 return so->camera.intraocularDistance;
1446 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1447 return so->camera.confocalDistance;
1460 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1461 return so->light.color;
1474 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1475 return so->light.brightness;
1488 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1489 return so->light.range;
1502 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1503 return so->light.sharpness;
1516 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1517 return so->light.cone;
1530 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1531 return so->transform;
1542 return (VuoPoint3d){0,0,0};
1544 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1545 return so->transform.translation;
1558 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1573 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1587 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1603 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1604 if (so->type != VuoSceneObjectSubType_Group)
1609 so->childObjects = childObjects;
1622 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1638 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1639 so->transform = transform;
1652 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1653 so->transform.translation = translation;
1666 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1667 so->transform.scale = scale;
1680 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1683 so->shader = shader;
1719 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
1720 co->blendMode = blendMode;
1735 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1736 so->isRealSize = isRealSize;
1750 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1751 so->preservePhysicalSize = shouldPreservePhysicalSize;
1764 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1767 so->text.text = text;
1780 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1783 so->text.font = font;
1796 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1797 so->camera.fieldOfView = fieldOfView;
1810 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1811 so->camera.distanceMin = distanceMin;
1824 VuoSceneObject_internal *so = (VuoSceneObject_internal *)
object;
1825 so->camera.distanceMax = distanceMax;
1843 VuoSceneObject_internal *o = (VuoSceneObject_internal *)
object;
1850 co->transform = o->transform;
1853 co->isRealSize = o->isRealSize;
1854 co->preservePhysicalSize = o->preservePhysicalSize;
1855 co->blendMode = o->blendMode;
1857 if (o->type == VuoSceneObjectSubType_Group && o->childObjects)
1862 VuoListAppendValue_VuoSceneObject(co->childObjects, VuoSceneObject_copy(object));
1867 if (o->type == VuoSceneObjectSubType_PerspectiveCamera
1868 || o->type == VuoSceneObjectSubType_StereoCamera
1869 || o->type == VuoSceneObjectSubType_OrthographicCamera
1870 || o->type == VuoSceneObjectSubType_FisheyeCamera)
1872 co->camera.fieldOfView = o->camera.fieldOfView;
1873 co->camera.width = o->camera.width;
1874 co->camera.distanceMin = o->camera.distanceMin;
1875 co->camera.distanceMax = o->camera.distanceMax;
1876 co->camera.confocalDistance = o->camera.confocalDistance;
1877 co->camera.intraocularDistance = o->camera.intraocularDistance;
1878 co->camera.vignetteWidth = o->camera.vignetteWidth;
1879 co->camera.vignetteSharpness = o->camera.vignetteSharpness;
1881 else if (o->type == VuoSceneObjectSubType_AmbientLight
1882 || o->type == VuoSceneObjectSubType_PointLight
1883 || o->type == VuoSceneObjectSubType_Spotlight)
1885 co->light.color = o->light.color;
1886 co->light.brightness = o->light.brightness;
1887 co->light.range = o->light.range;
1888 co->light.cone = o->light.cone;
1889 co->light.sharpness = o->light.sharpness;
1891 else if (o->type == VuoSceneObjectSubType_Text)
1895 co->text.scaleWithScene = o->text.scaleWithScene;
1896 co->text.wrapWidth = o->text.wrapWidth;
1908 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1910 __block
bool haveGlobalBounds =
false;
1911 __block
VuoBox globalBounds;
1919 haveGlobalBounds =
true;
1924 if (haveGlobalBounds)
1925 return globalBounds;
1927 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1941 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1943 || so->type == VuoSceneObjectSubType_Text)
1955 bounds->size.x *= so->shader->objectScale;
1956 bounds->size.y *= so->shader->objectScale;
1957 bounds->size.z *= so->shader->objectScale;
1972 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1974 so->transform.translation =
VuoPoint3d_subtract(so->transform.translation, bounds.center);
1986 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
1989 float scale = fmax(fmax(bounds.size.x, bounds.size.y), bounds.size.z);
1990 if (fabs(scale) < 0.00001)
2027 if (json_object_object_get_ex(js,
"id", &o))
2028 id = json_object_get_int64(o);
2031 if (json_object_object_get_ex(js,
"type", &o))
2035 if (json_object_object_get_ex(js,
"mesh", &o))
2039 if (json_object_object_get_ex(js,
"shader", &o))
2042 bool isRealSize =
false;
2043 if (json_object_object_get_ex(js,
"isRealSize", &o))
2046 bool preservePhysicalSize =
false;
2047 if (json_object_object_get_ex(js,
"preservePhysicalSize", &o))
2051 if (json_object_object_get_ex(js,
"blendMode", &o))
2055 if (json_object_object_get_ex(js,
"childObjects", &o))
2058 float cameraFieldOfView;
2059 if (json_object_object_get_ex(js,
"cameraFieldOfView", &o))
2060 cameraFieldOfView = json_object_get_double(o);
2063 if (json_object_object_get_ex(js,
"cameraWidth", &o))
2064 cameraWidth = json_object_get_double(o);
2066 float cameraDistanceMin;
2067 if (json_object_object_get_ex(js,
"cameraDistanceMin", &o))
2068 cameraDistanceMin = json_object_get_double(o);
2070 float cameraDistanceMax;
2071 if (json_object_object_get_ex(js,
"cameraDistanceMax", &o))
2072 cameraDistanceMax = json_object_get_double(o);
2074 float cameraConfocalDistance;
2075 if (json_object_object_get_ex(js,
"cameraConfocalDistance", &o))
2076 cameraConfocalDistance = json_object_get_double(o);
2078 float cameraIntraocularDistance;
2079 if (json_object_object_get_ex(js,
"cameraIntraocularDistance", &o))
2080 cameraIntraocularDistance = json_object_get_double(o);
2082 float cameraVignetteWidth;
2083 if (json_object_object_get_ex(js,
"cameraVignetteWidth", &o))
2084 cameraVignetteWidth = json_object_get_double(o);
2086 float cameraVignetteSharpness;
2087 if (json_object_object_get_ex(js,
"cameraVignetteSharpness", &o))
2088 cameraVignetteSharpness = json_object_get_double(o);
2091 if (json_object_object_get_ex(js,
"lightColor", &o))
2094 float lightBrightness;
2095 if (json_object_object_get_ex(js,
"lightBrightness", &o))
2096 lightBrightness = json_object_get_double(o);
2099 if (json_object_object_get_ex(js,
"lightCone", &o))
2100 lightCone = json_object_get_double(o);
2103 if (json_object_object_get_ex(js,
"lightRange", &o))
2104 lightRange = json_object_get_double(o);
2106 float lightSharpness;
2107 if (json_object_object_get_ex(js,
"lightSharpness", &o))
2108 lightSharpness = json_object_get_double(o);
2111 if (json_object_object_get_ex(js,
"name", &o))
2114 json_object_object_get_ex(js,
"transform", &o);
2118 if (json_object_object_get_ex(js,
"text", &o))
2122 if (json_object_object_get_ex(js,
"textFont", &o))
2125 bool scaleWithScene =
false;
2126 if (json_object_object_get_ex(js,
"textScaleWithScene", &o))
2129 float wrapWidth = INFINITY;
2130 if (json_object_object_get_ex(js,
"textWrapWidth", &o))
2131 wrapWidth = json_object_get_double(o);
2136 case VuoSceneObjectSubType_Empty:
2139 case VuoSceneObjectSubType_Group:
2142 case VuoSceneObjectSubType_Mesh:
2145 VuoSceneObject_internal *so = (VuoSceneObject_internal *)obj;
2146 so->isRealSize = isRealSize;
2147 so->preservePhysicalSize = preservePhysicalSize;
2148 so->blendMode = blendMode;
2152 case VuoSceneObjectSubType_PerspectiveCamera:
2161 case VuoSceneObjectSubType_StereoCamera:
2168 cameraConfocalDistance,
2169 cameraIntraocularDistance
2172 case VuoSceneObjectSubType_OrthographicCamera:
2181 case VuoSceneObjectSubType_FisheyeCamera:
2186 cameraVignetteWidth,
2187 cameraVignetteSharpness
2190 case VuoSceneObjectSubType_AmbientLight:
2193 case VuoSceneObjectSubType_PointLight:
2196 case VuoSceneObjectSubType_Spotlight:
2199 case VuoSceneObjectSubType_Text:
2219 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2223 json_object_object_add(js,
"id", json_object_new_int64(so->id));
2228 case VuoSceneObjectSubType_Empty:
2231 case VuoSceneObjectSubType_Mesh:
2240 json_object_object_add(js,
"preservePhysicalSize",
VuoBoolean_getJson(so->preservePhysicalSize));
2246 case VuoSceneObjectSubType_Group:
2247 if (so->childObjects)
2251 case VuoSceneObjectSubType_PerspectiveCamera:
2252 case VuoSceneObjectSubType_StereoCamera:
2253 case VuoSceneObjectSubType_OrthographicCamera:
2254 case VuoSceneObjectSubType_FisheyeCamera:
2256 if (so->type != VuoSceneObjectSubType_FisheyeCamera)
2258 json_object_object_add(js,
"cameraDistanceMin", json_object_new_double(so->camera.distanceMin));
2259 json_object_object_add(js,
"cameraDistanceMax", json_object_new_double(so->camera.distanceMax));
2262 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2263 || so->type == VuoSceneObjectSubType_StereoCamera
2264 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2265 json_object_object_add(js,
"cameraFieldOfView", json_object_new_double(so->camera.fieldOfView));
2267 if (so->type == VuoSceneObjectSubType_StereoCamera)
2269 json_object_object_add(js,
"cameraConfocalDistance", json_object_new_double(so->camera.confocalDistance));
2270 json_object_object_add(js,
"cameraIntraocularDistance", json_object_new_double(so->camera.intraocularDistance));
2273 if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2274 json_object_object_add(js,
"cameraWidth", json_object_new_double(so->camera.width));
2276 if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2278 json_object_object_add(js,
"cameraVignetteWidth", json_object_new_double(so->camera.vignetteWidth));
2279 json_object_object_add(js,
"cameraVignetteSharpness", json_object_new_double(so->camera.vignetteSharpness));
2285 case VuoSceneObjectSubType_AmbientLight:
2286 case VuoSceneObjectSubType_PointLight:
2287 case VuoSceneObjectSubType_Spotlight:
2289 json_object_object_add(js,
"lightColor",
VuoColor_getJson(so->light.color));
2290 json_object_object_add(js,
"lightBrightness", json_object_new_double(so->light.brightness));
2292 if (so->type == VuoSceneObjectSubType_PointLight
2293 || so->type == VuoSceneObjectSubType_Spotlight)
2295 json_object_object_add(js,
"lightRange", json_object_new_double(so->light.range));
2296 json_object_object_add(js,
"lightSharpness", json_object_new_double(so->light.sharpness));
2298 if (so->type == VuoSceneObjectSubType_Spotlight)
2299 json_object_object_add(js,
"lightCone", json_object_new_double(so->light.cone));
2304 case VuoSceneObjectSubType_Text:
2309 json_object_object_add(js,
"textFont",
VuoFont_getJson(so->text.font));
2314 json_object_object_add(js,
"textScaleWithScene",
VuoBoolean_getJson(so->text.scaleWithScene));
2315 json_object_object_add(js,
"textWrapWidth",
VuoReal_getJson(so->text.wrapWidth));
2324 if (so->type != VuoSceneObjectSubType_AmbientLight)
2338 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2342 unsigned int vertexCount;
2343 VuoMesh_getCPUBuffers(so->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2355 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2359 unsigned int elementCount;
2360 VuoMesh_getCPUBuffers(so->mesh,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, &elementCount,
nullptr);
2361 return elementCount;
2374 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2375 unsigned long childObjectCount = 0;
2376 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2378 *descendantCount += childObjectCount;
2382 if (so->type == VuoSceneObjectSubType_Group)
2383 for (
unsigned long i = 1; i <= childObjectCount; ++i)
2396 __block
json_object *names = json_object_new_object();
2398 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2400 json_object_object_add(names, co->shader->name, NULL);
2405 json_object_object_foreach(names, key, val)
2407 json_object_put(names);
2417 return strdup(
"No object");
2419 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2421 if (so->type == VuoSceneObjectSubType_Text)
2424 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);
2429 if (so->type == VuoSceneObjectSubType_PerspectiveCamera
2430 || so->type == VuoSceneObjectSubType_StereoCamera
2431 || so->type == VuoSceneObjectSubType_OrthographicCamera
2432 || so->type == VuoSceneObjectSubType_FisheyeCamera)
2435 type[0] = toupper(type[0]);
2437 float cameraViewValue = 0;
2438 const char *cameraViewString =
"";
2439 if (so->type == VuoSceneObjectSubType_PerspectiveCamera)
2441 cameraViewValue = so->camera.fieldOfView;
2442 cameraViewString =
"° field of view";
2444 else if (so->type == VuoSceneObjectSubType_StereoCamera)
2446 cameraViewValue = so->camera.fieldOfView;
2447 cameraViewString =
"° field of view (stereoscopic)";
2449 else if (so->type == VuoSceneObjectSubType_OrthographicCamera)
2451 cameraViewValue = so->camera.width;
2452 cameraViewString =
" unit width";
2454 else if (so->type == VuoSceneObjectSubType_FisheyeCamera)
2456 cameraViewValue = so->camera.fieldOfView;
2457 cameraViewString =
"° field of view (fisheye)";
2462 const char *rotationLabel;
2463 char *rotationString;
2464 if (so->transform.type == VuoTransformTypeEuler)
2466 rotationLabel =
"Rotated";
2471 rotationLabel =
"Target";
2475 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>",
2476 type, so->name ? so->name :
"",
2478 rotationLabel, rotationString,
2479 cameraViewValue, cameraViewString,
2480 so->camera.distanceMin, so->camera.distanceMax);
2481 free(rotationString);
2482 free(translationString);
2484 return valueAsString;
2487 if (so->type == VuoSceneObjectSubType_AmbientLight
2488 || so->type == VuoSceneObjectSubType_PointLight
2489 || so->type == VuoSceneObjectSubType_Spotlight)
2492 type[0] = toupper(type[0]);
2496 char *positionRangeString;
2497 if (so->type == VuoSceneObjectSubType_PointLight
2498 || so->type == VuoSceneObjectSubType_Spotlight)
2502 positionRangeString =
VuoText_format(
"<div>Position (%s)</div><div>Range %g units (%g sharpness)</div>",
2503 positionString, so->light.range, so->light.sharpness);
2505 free(positionString);
2508 positionRangeString = strdup(
"");
2510 char *directionConeString;
2511 if (so->type == VuoSceneObjectSubType_Spotlight)
2516 directionConeString =
VuoText_format(
"<div>Direction (%s)</div><div>Cone %g°</div>",
2517 directionString, so->light.cone * 180./M_PI);
2519 free(directionString);
2522 directionConeString = strdup(
"");
2524 char *valueAsString =
VuoText_format(
"<div>%s</div><div>Color %s</div><div>Brightness %g</div>%s%s",
2525 type, colorString, so->light.brightness, positionRangeString, directionConeString);
2527 free(directionConeString);
2528 free(positionRangeString);
2532 return valueAsString;
2540 unsigned long childObjectCount = 0;
2541 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2543 const char *childObjectPlural = childObjectCount == 1 ?
"" :
"s";
2546 if (childObjectCount)
2548 unsigned long descendantCount = 0;
2549 unsigned long totalVertexCount = 0;
2550 unsigned long totalElementCount = 0;
2552 const char *descendantPlural = descendantCount == 1 ?
"" :
"s";
2554 descendants =
VuoText_format(
"<div>%ld descendant%s</div><div>Total, including descendants:</div><div>%ld vertices, %ld elements</div>",
2555 descendantCount, descendantPlural, totalVertexCount, totalElementCount);
2558 descendants = strdup(
"");
2562 char *shaderNamesSummary;
2566 const char *header =
"<div>Shaders:<ul>";
2567 VuoInteger shaderNameLength = strlen(header);
2568 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2570 shaderNameLength += strlen(
"</ul></div>");
2572 shaderNamesSummary = (
char *)malloc(shaderNameLength + 1);
2573 char *t = shaderNamesSummary;
2574 t = strcpy(t, header) + strlen(header);
2575 for (
VuoInteger i = 1; i <= shaderNameCount; ++i)
2577 t = strcpy(t,
"<li>") + strlen(
"<li>");
2579 t = strcpy(t,
"</li>") + strlen(
"</li>");
2581 t = strcpy(t,
"</ul></div>");
2584 shaderNamesSummary = strdup(
"");
2589 name =
VuoText_format(
"<div>Object named \"%s\"</div>", so->name);
2591 char *valueAsString =
VuoText_format(
"%s<div>%ld vertices, %ld elements</div><div>%s</div><div>ID %lld</div><div>%ld child object%s</div>%s%s",
2593 vertexCount, elementCount,
2596 childObjectCount, childObjectPlural,
2597 descendants, shaderNamesSummary);
2601 free(shaderNamesSummary);
2603 return valueAsString;
2611 VuoSceneObject_internal *so = (VuoSceneObject_internal *)sceneObject;
2613 for (
unsigned int i=0; i<level; ++i)
2614 fprintf(stderr,
"\t");
2618 fprintf(stderr,
"no object\n");
2623 if (so->type == VuoSceneObjectSubType_Mesh)
2625 fprintf(stderr,
"\n");
2627 if (so->type == VuoSceneObjectSubType_Group && so->childObjects)
2630 for (
unsigned int i=1; i<=childObjectCount; ++i)
2660 __block
unsigned long triangleVertexCount = 0;
2661 __block
unsigned long trianglePrimitiveCount = 0;
2664 __block
unsigned long lineVertexCount = 0;
2665 __block
unsigned long linePrimitiveCount = 0;
2666 __block
double linePrimitiveSize = 0;
2668 __block
unsigned long pointVertexCount = 0;
2669 __block
unsigned long pointPrimitiveCount = 0;
2670 __block
double pointPrimitiveSize = 0;
2673 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2679 unsigned int vertexCount;
2680 VuoMesh_getCPUBuffers(co->mesh, &vertexCount,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
2686 triangleVertexCount += vertexCount;
2693 lineVertexCount += vertexCount;
2699 pointVertexCount += vertexCount;
2708 if (!trianglePrimitiveCount && !linePrimitiveCount && !pointPrimitiveCount)
2712 unsigned int *triangleElements =
nullptr;
2713 float *trianglePositions =
nullptr, *triangleNormals =
nullptr, *triangleTextureCoordinates =
nullptr;
2714 unsigned int *lineElements =
nullptr;
2715 float *linePositions =
nullptr, *lineNormals =
nullptr, *lineTextureCoordinates =
nullptr;
2716 unsigned int *pointElements =
nullptr;
2717 float *pointPositions =
nullptr, *pointNormals =
nullptr, *pointTextureCoordinates =
nullptr;
2718 if (trianglePrimitiveCount)
2719 VuoMesh_allocateCPUBuffers(triangleVertexCount, &trianglePositions, &triangleNormals, &triangleTextureCoordinates,
nullptr, trianglePrimitiveCount * 3, &triangleElements);
2720 if (linePrimitiveCount)
2721 VuoMesh_allocateCPUBuffers(lineVertexCount, &linePositions, &lineNormals, &lineTextureCoordinates,
nullptr, linePrimitiveCount * 2, &lineElements);
2722 if (pointPrimitiveCount)
2723 VuoMesh_allocateCPUBuffers(pointVertexCount, &pointPositions, &pointNormals, &pointTextureCoordinates,
nullptr, pointPrimitiveCount, &pointElements);
2726 __block
unsigned long triangleVertexIndex = 0;
2727 __block
unsigned long triangleElementIndex = 0;
2728 __block
unsigned long lineVertexIndex = 0;
2729 __block
unsigned long lineElementIndex = 0;
2730 __block
unsigned long pointVertexIndex = 0;
2731 __block
unsigned long pointElementIndex = 0;
2732 __block
bool anyTextureCoordinates =
false;
2734 VuoSceneObject_internal *co = (VuoSceneObject_internal *)currentObject;
2740 unsigned int vertexCount, elementCount, *elements;
2741 float *positions, *normals, *textureCoordinates;
2742 VuoMesh_getCPUBuffers(co->mesh, &vertexCount, &positions, &normals, &textureCoordinates,
nullptr, &elementCount, &elements);
2744 if (textureCoordinates)
2745 anyTextureCoordinates =
true;
2751 unsigned long indexOffset = triangleVertexIndex;
2752 for (
unsigned int n = 0; n < vertexCount; ++n)
2765 if (textureCoordinates)
2768 ++triangleVertexIndex;
2774 for (
unsigned int n = 0; n < elementCount; ++n)
2775 triangleElements[triangleElementIndex++] = indexOffset + elements[n];
2777 for (
unsigned int n = 0; n < vertexCount; ++n)
2778 triangleElements[triangleElementIndex++] = indexOffset + n;
2784 for (
unsigned int n = 2; n < elementCount; ++n)
2787 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2788 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2789 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2793 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2794 triangleElements[triangleElementIndex++] = indexOffset + elements[n-2];
2795 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2798 for (
unsigned int n = 0; n < vertexCount; ++n)
2801 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2802 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2803 triangleElements[triangleElementIndex++] = indexOffset + n ;
2807 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2808 triangleElements[triangleElementIndex++] = indexOffset + n-2;
2809 triangleElements[triangleElementIndex++] = indexOffset + n ;
2816 for (
unsigned int n = 2; n < elementCount; ++n)
2818 triangleElements[triangleElementIndex++] = indexOffset + elements[0 ];
2819 triangleElements[triangleElementIndex++] = indexOffset + elements[n-1];
2820 triangleElements[triangleElementIndex++] = indexOffset + elements[n ];
2823 for (
unsigned int n = 2; n < vertexCount; ++n)
2825 triangleElements[triangleElementIndex++] = indexOffset + 0;
2826 triangleElements[triangleElementIndex++] = indexOffset + n-1;
2827 triangleElements[triangleElementIndex++] = indexOffset + n;
2834 unsigned long indexOffset = lineVertexIndex;
2835 for (
unsigned int n = 0; n < vertexCount; ++n)
2848 if (textureCoordinates)
2857 for (
unsigned int n = 0; n < elementCount; ++n)
2858 lineElements[lineElementIndex++] = indexOffset + elements[n];
2860 for (
unsigned int n = 0; n < vertexCount; ++n)
2861 lineElements[lineElementIndex++] = indexOffset + n;
2867 for (
unsigned int n = 1; n < elementCount; ++n)
2869 lineElements[lineElementIndex++] = indexOffset + elements[n-1];
2870 lineElements[lineElementIndex++] = indexOffset + elements[n ];
2873 for (
unsigned int n = 1; n < vertexCount; ++n)
2875 lineElements[lineElementIndex++] = indexOffset + n-1;
2876 lineElements[lineElementIndex++] = indexOffset + n;
2882 unsigned long indexOffset = pointVertexIndex;
2883 for (
unsigned int n = 0; n < vertexCount; ++n)
2896 if (textureCoordinates)
2904 for (
unsigned int n = 0; n < elementCount; ++n)
2905 pointElements[pointElementIndex++] = indexOffset + elements[n];
2908 for (
unsigned int n = 0; n < vertexCount; ++n)
2909 pointElements[pointElementIndex++] = indexOffset + n;
2917 VuoMesh triangleMesh =
nullptr;
2920 if (trianglePrimitiveCount)
2922 if (!anyTextureCoordinates)
2924 free(triangleTextureCoordinates);
2925 triangleTextureCoordinates =
nullptr;
2930 if (linePrimitiveCount)
2932 if (!anyTextureCoordinates)
2934 free(lineTextureCoordinates);
2935 lineTextureCoordinates =
nullptr;
2940 if (pointPrimitiveCount)
2942 if (!anyTextureCoordinates)
2944 free(pointTextureCoordinates);
2945 pointTextureCoordinates =
nullptr;
2951 if (triangleMesh && !lineMesh && !pointMesh)
2953 else if (!triangleMesh && lineMesh && !pointMesh)
2955 else if (!triangleMesh && !lineMesh && pointMesh)
2972 #define CSGJS_HEADER_ONLY
2981 return csgjs_model();
2984 VuoSceneObject_internal *f = (VuoSceneObject_internal *)flat;
2986 return csgjs_model();
2991 return csgjs_model();
2993 unsigned int vertexCount, elementCount, *elements;
2994 float *positions, *normals, *textureCoordinates;
2995 VuoMesh_getCPUBuffers(f->mesh, &vertexCount, &positions, &normals, &textureCoordinates,
nullptr, &elementCount, &elements);
2998 for (
unsigned int n = 0; n < vertexCount; ++n)
3001 v.pos = csgjs_vector(positions[n * 3], positions[n * 3 + 1], positions[n * 3 + 2]);
3003 v.normal = csgjs_vector(normals[n * 3], normals[n * 3 + 1], normals[n * 3 + 2]);
3004 if (textureCoordinates)
3005 v.uv = csgjs_vector(textureCoordinates[n * 3], textureCoordinates[n * 3 + 1], 0);
3006 cm.vertices.push_back(v);
3008 for (
unsigned int n = 0; n < elementCount; ++n)
3009 cm.indices.push_back(elements[n]);
3019 unsigned int vertexCount = cm.vertices.size();
3020 unsigned int elementCount = cm.indices.size();
3021 unsigned int *elements;
3022 float *positions, *normals, *textureCoordinates;
3025 const csgjs_vertex *vertex = &cm.vertices[0];
3026 for (
unsigned int n = 0; n < vertexCount; ++n)
3028 positions[n * 3 ] = vertex[n].pos.x;
3029 positions[n * 3 + 1] = vertex[n].pos.y;
3030 positions[n * 3 + 2] = vertex[n].pos.z;
3031 normals[n * 3 ] = vertex[n].normal.x;
3032 normals[n * 3 + 1] = vertex[n].normal.y;
3033 normals[n * 3 + 2] = vertex[n].normal.z;
3034 textureCoordinates[n * 2 ] = vertex[n].uv.x;
3035 textureCoordinates[n * 2 + 1] = vertex[n].uv.y;
3038 const int *index = &cm.indices[0];
3039 for (
unsigned int n = 0; n < elementCount; ++n)
3040 elements[n] = index[n];
3064 if (objectCount == 0)
3066 if (objectCount == 1)
3069 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.union", DISPATCH_QUEUE_CONCURRENT);
3071 csgjs_model *models =
new csgjs_model[objectCount];
3072 for (
unsigned long i = 0; i < objectCount; ++i)
3073 dispatch_async(queue, ^{
3077 dispatch_barrier_sync(queue, ^{});
3078 dispatch_release(queue);
3080 csgjs_model cu = models[0];
3081 for (
unsigned long i = 1; i < objectCount; ++i)
3082 cu = csgjs_union(cu, models[i], epsilon);
3094 dispatch_semaphore_t finished = dispatch_semaphore_create(0);
3096 __block csgjs_model ca;
3097 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3099 dispatch_semaphore_signal(finished);
3104 dispatch_semaphore_wait(finished, DISPATCH_TIME_FOREVER);
3105 dispatch_release(finished);
3107 csgjs_model d = csgjs_difference(ca, cb, epsilon);
3119 if (objectCount == 0)
3121 if (objectCount == 1)
3124 dispatch_queue_t queue = dispatch_queue_create(
"org.vuo.sceneobject.intersect", DISPATCH_QUEUE_CONCURRENT);
3126 csgjs_model *models =
new csgjs_model[objectCount];
3127 for (
unsigned long i = 0; i < objectCount; ++i)
3128 dispatch_async(queue, ^{
3132 dispatch_barrier_sync(queue, ^{});
3133 dispatch_release(queue);
3135 csgjs_model ci = models[0];
3136 for (
unsigned long i = 1; i < objectCount; ++i)
3137 ci = csgjs_intersection(ci, models[i], epsilon);