diff --git a/apps/typegpu-docs/public/assets/triplanar-mapping/suzanne.obj b/apps/typegpu-docs/public/assets/triplanar-mapping/suzanne.obj new file mode 100644 index 0000000000..43630bf2cb --- /dev/null +++ b/apps/typegpu-docs/public/assets/triplanar-mapping/suzanne.obj @@ -0,0 +1,2065 @@ +# Blender 5.1.1 +# www.blender.org +o Suzanne +v -0.437500 0.164062 -0.765625 +v 0.437500 0.164062 -0.765625 +v -0.500000 0.093750 -0.687500 +v 0.500000 0.093750 -0.687500 +v -0.546875 0.054688 -0.578125 +v 0.546875 0.054688 -0.578125 +v -0.351562 -0.023438 -0.617188 +v 0.351562 -0.023438 -0.617188 +v -0.351562 0.031250 -0.718750 +v 0.351562 0.031250 -0.718750 +v -0.351562 0.132812 -0.781250 +v 0.351562 0.132812 -0.781250 +v -0.273438 0.164062 -0.796875 +v 0.273438 0.164062 -0.796875 +v -0.203125 0.093750 -0.742188 +v 0.203125 0.093750 -0.742188 +v -0.156250 0.054688 -0.648438 +v 0.156250 0.054688 -0.648438 +v -0.078125 0.242188 -0.656250 +v 0.078125 0.242188 -0.656250 +v -0.140625 0.242188 -0.742188 +v 0.140625 0.242188 -0.742188 +v -0.242188 0.242188 -0.796875 +v 0.242188 0.242188 -0.796875 +v -0.273438 0.328125 -0.796875 +v 0.273438 0.328125 -0.796875 +v -0.203125 0.390625 -0.742188 +v 0.203125 0.390625 -0.742188 +v -0.156250 0.437500 -0.648438 +v 0.156250 0.437500 -0.648438 +v -0.351562 0.515625 -0.617188 +v 0.351562 0.515625 -0.617188 +v -0.351562 0.453125 -0.718750 +v 0.351562 0.453125 -0.718750 +v -0.351562 0.359375 -0.781250 +v 0.351562 0.359375 -0.781250 +v -0.437500 0.328125 -0.765625 +v 0.437500 0.328125 -0.765625 +v -0.500000 0.390625 -0.687500 +v 0.500000 0.390625 -0.687500 +v -0.546875 0.437500 -0.578125 +v 0.546875 0.437500 -0.578125 +v -0.625000 0.242188 -0.562500 +v 0.625000 0.242188 -0.562500 +v -0.562500 0.242188 -0.671875 +v 0.562500 0.242188 -0.671875 +v -0.468750 0.242188 -0.757812 +v 0.468750 0.242188 -0.757812 +v -0.476562 0.242188 -0.773438 +v 0.476562 0.242188 -0.773438 +v -0.445312 0.335938 -0.781250 +v 0.445312 0.335938 -0.781250 +v -0.351562 0.375000 -0.804688 +v 0.351562 0.375000 -0.804688 +v -0.265625 0.335938 -0.820312 +v 0.265625 0.335938 -0.820312 +v -0.226562 0.242188 -0.820312 +v 0.226562 0.242188 -0.820312 +v -0.265625 0.156250 -0.820312 +v 0.265625 0.156250 -0.820312 +v -0.351562 0.242188 -0.828125 +v 0.351562 0.242188 -0.828125 +v -0.351562 0.117188 -0.804688 +v 0.351562 0.117188 -0.804688 +v -0.445312 0.156250 -0.781250 +v 0.445312 0.156250 -0.781250 +v 0.000000 0.429688 -0.742188 +v 0.000000 0.351562 -0.820312 +v 0.000000 -0.679688 -0.734375 +v 0.000000 -0.320312 -0.781250 +v 0.000000 -0.187500 -0.796875 +v 0.000000 -0.773438 -0.718750 +v 0.000000 0.406250 -0.601562 +v 0.000000 0.570312 -0.570312 +v 0.000000 0.898438 0.546875 +v 0.000000 0.562500 0.851562 +v 0.000000 0.070312 0.828125 +v 0.000000 -0.382812 0.351562 +v -0.203125 -0.187500 -0.562500 +v 0.203125 -0.187500 -0.562500 +v -0.312500 -0.437500 -0.570312 +v 0.312500 -0.437500 -0.570312 +v -0.351562 -0.695312 -0.570312 +v 0.351562 -0.695312 -0.570312 +v -0.367188 -0.890625 -0.531250 +v 0.367188 -0.890625 -0.531250 +v -0.328125 -0.945312 -0.523438 +v 0.328125 -0.945312 -0.523438 +v -0.179688 -0.968750 -0.554688 +v 0.179688 -0.968750 -0.554688 +v 0.000000 -0.984375 -0.578125 +v -0.437500 -0.140625 -0.531250 +v 0.437500 -0.140625 -0.531250 +v -0.632812 -0.039062 -0.539062 +v 0.632812 -0.039062 -0.539062 +v -0.828125 0.148438 -0.445312 +v 0.828125 0.148438 -0.445312 +v -0.859375 0.429688 -0.593750 +v 0.859375 0.429688 -0.593750 +v -0.710938 0.484375 -0.625000 +v 0.710938 0.484375 -0.625000 +v -0.492188 0.601562 -0.687500 +v 0.492188 0.601562 -0.687500 +v -0.320312 0.757812 -0.734375 +v 0.320312 0.757812 -0.734375 +v -0.156250 0.718750 -0.757812 +v 0.156250 0.718750 -0.757812 +v -0.062500 0.492188 -0.750000 +v 0.062500 0.492188 -0.750000 +v -0.164062 0.414062 -0.773438 +v 0.164062 0.414062 -0.773438 +v -0.125000 0.304688 -0.765625 +v 0.125000 0.304688 -0.765625 +v -0.203125 0.093750 -0.742188 +v 0.203125 0.093750 -0.742188 +v -0.375000 0.015625 -0.703125 +v 0.375000 0.015625 -0.703125 +v -0.492188 0.062500 -0.671875 +v 0.492188 0.062500 -0.671875 +v -0.625000 0.187500 -0.648438 +v 0.625000 0.187500 -0.648438 +v -0.640625 0.296875 -0.648438 +v 0.640625 0.296875 -0.648438 +v -0.601562 0.375000 -0.664062 +v 0.601562 0.375000 -0.664062 +v -0.429688 0.437500 -0.718750 +v 0.429688 0.437500 -0.718750 +v -0.250000 0.468750 -0.757812 +v 0.250000 0.468750 -0.757812 +v 0.000000 -0.765625 -0.734375 +v -0.109375 -0.718750 -0.734375 +v 0.109375 -0.718750 -0.734375 +v -0.117188 -0.835938 -0.710938 +v 0.117188 -0.835938 -0.710938 +v -0.062500 -0.882812 -0.695312 +v 0.062500 -0.882812 -0.695312 +v 0.000000 -0.890625 -0.687500 +v 0.000000 -0.195312 -0.750000 +v 0.000000 -0.140625 -0.742188 +v -0.101562 -0.148438 -0.742188 +v 0.101562 -0.148438 -0.742188 +v -0.125000 -0.226562 -0.750000 +v 0.125000 -0.226562 -0.750000 +v -0.085938 -0.289062 -0.742188 +v 0.085938 -0.289062 -0.742188 +v -0.398438 -0.046875 -0.671875 +v 0.398438 -0.046875 -0.671875 +v -0.617188 0.054688 -0.625000 +v 0.617188 0.054688 -0.625000 +v -0.726562 0.203125 -0.601562 +v 0.726562 0.203125 -0.601562 +v -0.742188 0.375000 -0.656250 +v 0.742188 0.375000 -0.656250 +v -0.687500 0.414062 -0.726562 +v 0.687500 0.414062 -0.726562 +v -0.437500 0.546875 -0.796875 +v 0.437500 0.546875 -0.796875 +v -0.312500 0.640625 -0.835938 +v 0.312500 0.640625 -0.835938 +v -0.203125 0.617188 -0.851562 +v 0.203125 0.617188 -0.851562 +v -0.101562 0.429688 -0.843750 +v 0.101562 0.429688 -0.843750 +v -0.125000 -0.101562 -0.812500 +v 0.125000 -0.101562 -0.812500 +v -0.210938 -0.445312 -0.710938 +v 0.210938 -0.445312 -0.710938 +v -0.250000 -0.703125 -0.687500 +v 0.250000 -0.703125 -0.687500 +v -0.265625 -0.820312 -0.664062 +v 0.265625 -0.820312 -0.664062 +v -0.234375 -0.914062 -0.632812 +v 0.234375 -0.914062 -0.632812 +v -0.164062 -0.929688 -0.632812 +v 0.164062 -0.929688 -0.632812 +v 0.000000 -0.945312 -0.640625 +v 0.000000 0.046875 -0.726562 +v 0.000000 0.210938 -0.765625 +v -0.328125 0.476562 -0.742188 +v 0.328125 0.476562 -0.742188 +v -0.164062 0.140625 -0.750000 +v 0.164062 0.140625 -0.750000 +v -0.132812 0.210938 -0.757812 +v 0.132812 0.210938 -0.757812 +v -0.117188 -0.687500 -0.734375 +v 0.117188 -0.687500 -0.734375 +v -0.078125 -0.445312 -0.750000 +v 0.078125 -0.445312 -0.750000 +v 0.000000 -0.445312 -0.750000 +v 0.000000 -0.328125 -0.742188 +v -0.093750 -0.273438 -0.781250 +v 0.093750 -0.273438 -0.781250 +v -0.132812 -0.226562 -0.796875 +v 0.132812 -0.226562 -0.796875 +v -0.109375 -0.132812 -0.781250 +v 0.109375 -0.132812 -0.781250 +v -0.039062 -0.125000 -0.781250 +v 0.039062 -0.125000 -0.781250 +v 0.000000 -0.203125 -0.828125 +v -0.046875 -0.148438 -0.812500 +v 0.046875 -0.148438 -0.812500 +v -0.093750 -0.156250 -0.812500 +v 0.093750 -0.156250 -0.812500 +v -0.109375 -0.226562 -0.828125 +v 0.109375 -0.226562 -0.828125 +v -0.078125 -0.250000 -0.804688 +v 0.078125 -0.250000 -0.804688 +v 0.000000 -0.289062 -0.804688 +v -0.257812 -0.312500 -0.554688 +v 0.257812 -0.312500 -0.554688 +v -0.164062 -0.242188 -0.710938 +v 0.164062 -0.242188 -0.710938 +v -0.179688 -0.312500 -0.710938 +v 0.179688 -0.312500 -0.710938 +v -0.234375 -0.250000 -0.554688 +v 0.234375 -0.250000 -0.554688 +v 0.000000 -0.875000 -0.687500 +v -0.046875 -0.867188 -0.687500 +v 0.046875 -0.867188 -0.687500 +v -0.093750 -0.820312 -0.710938 +v 0.093750 -0.820312 -0.710938 +v -0.093750 -0.742188 -0.726562 +v 0.093750 -0.742188 -0.726562 +v 0.000000 -0.781250 -0.656250 +v -0.093750 -0.750000 -0.664062 +v 0.093750 -0.750000 -0.664062 +v -0.093750 -0.812500 -0.640625 +v 0.093750 -0.812500 -0.640625 +v -0.046875 -0.851562 -0.632812 +v 0.046875 -0.851562 -0.632812 +v 0.000000 -0.859375 -0.632812 +v -0.171875 0.218750 -0.781250 +v 0.171875 0.218750 -0.781250 +v -0.187500 0.156250 -0.773438 +v 0.187500 0.156250 -0.773438 +v -0.335938 0.429688 -0.757812 +v 0.335938 0.429688 -0.757812 +v -0.273438 0.421875 -0.773438 +v 0.273438 0.421875 -0.773438 +v -0.421875 0.398438 -0.773438 +v 0.421875 0.398438 -0.773438 +v -0.562500 0.351562 -0.695312 +v 0.562500 0.351562 -0.695312 +v -0.585938 0.289062 -0.687500 +v 0.585938 0.289062 -0.687500 +v -0.578125 0.195312 -0.679688 +v 0.578125 0.195312 -0.679688 +v -0.476562 0.101562 -0.718750 +v 0.476562 0.101562 -0.718750 +v -0.375000 0.062500 -0.742188 +v 0.375000 0.062500 -0.742188 +v -0.226562 0.109375 -0.781250 +v 0.226562 0.109375 -0.781250 +v -0.179688 0.296875 -0.781250 +v 0.179688 0.296875 -0.781250 +v -0.210938 0.375000 -0.781250 +v 0.210938 0.375000 -0.781250 +v -0.234375 0.359375 -0.757812 +v 0.234375 0.359375 -0.757812 +v -0.195312 0.296875 -0.757812 +v 0.195312 0.296875 -0.757812 +v -0.242188 0.125000 -0.757812 +v 0.242188 0.125000 -0.757812 +v -0.375000 0.085938 -0.726562 +v 0.375000 0.085938 -0.726562 +v -0.460938 0.117188 -0.703125 +v 0.460938 0.117188 -0.703125 +v -0.546875 0.210938 -0.671875 +v 0.546875 0.210938 -0.671875 +v -0.554688 0.281250 -0.671875 +v 0.554688 0.281250 -0.671875 +v -0.531250 0.335938 -0.679688 +v 0.531250 0.335938 -0.679688 +v -0.414062 0.390625 -0.750000 +v 0.414062 0.390625 -0.750000 +v -0.281250 0.398438 -0.765625 +v 0.281250 0.398438 -0.765625 +v -0.335938 0.406250 -0.750000 +v 0.335938 0.406250 -0.750000 +v -0.203125 0.171875 -0.750000 +v 0.203125 0.171875 -0.750000 +v -0.195312 0.226562 -0.750000 +v 0.195312 0.226562 -0.750000 +v -0.109375 0.460938 -0.609375 +v 0.109375 0.460938 -0.609375 +v -0.195312 0.664062 -0.617188 +v 0.195312 0.664062 -0.617188 +v -0.335938 0.687500 -0.593750 +v 0.335938 0.687500 -0.593750 +v -0.484375 0.554688 -0.554688 +v 0.484375 0.554688 -0.554688 +v -0.679688 0.453125 -0.492188 +v 0.679688 0.453125 -0.492188 +v -0.796875 0.406250 -0.460938 +v 0.796875 0.406250 -0.460938 +v -0.773438 0.164062 -0.375000 +v 0.773438 0.164062 -0.375000 +v -0.601562 0.000000 -0.414062 +v 0.601562 0.000000 -0.414062 +v -0.437500 -0.093750 -0.468750 +v 0.437500 -0.093750 -0.468750 +v 0.000000 0.898438 -0.289062 +v 0.000000 0.984375 0.078125 +v 0.000000 -0.195312 0.671875 +v 0.000000 -0.460938 -0.187500 +v 0.000000 -0.976562 -0.460938 +v 0.000000 -0.804688 -0.343750 +v 0.000000 -0.570312 -0.320312 +v 0.000000 -0.484375 -0.281250 +v -0.851562 0.234375 -0.054688 +v 0.851562 0.234375 -0.054688 +v -0.859375 0.320312 0.046875 +v 0.859375 0.320312 0.046875 +v -0.773438 0.265625 0.437500 +v 0.773438 0.265625 0.437500 +v -0.460938 0.437500 0.703125 +v 0.460938 0.437500 0.703125 +v -0.734375 -0.046875 -0.070312 +v 0.734375 -0.046875 -0.070312 +v -0.593750 -0.125000 0.164062 +v 0.593750 -0.125000 0.164062 +v -0.640625 -0.007812 0.429688 +v 0.640625 -0.007812 0.429688 +v -0.335938 0.054688 0.664062 +v 0.335938 0.054688 0.664062 +v -0.234375 -0.351562 -0.406250 +v 0.234375 -0.351562 -0.406250 +v -0.179688 -0.414062 -0.257812 +v 0.179688 -0.414062 -0.257812 +v -0.289062 -0.710938 -0.382812 +v 0.289062 -0.710938 -0.382812 +v -0.250000 -0.500000 -0.390625 +v 0.250000 -0.500000 -0.390625 +v -0.328125 -0.914062 -0.398438 +v 0.328125 -0.914062 -0.398438 +v -0.140625 -0.757812 -0.367188 +v 0.140625 -0.757812 -0.367188 +v -0.125000 -0.539062 -0.359375 +v 0.125000 -0.539062 -0.359375 +v -0.164062 -0.945312 -0.437500 +v 0.164062 -0.945312 -0.437500 +v -0.218750 -0.281250 -0.429688 +v 0.218750 -0.281250 -0.429688 +v -0.210938 -0.226562 -0.468750 +v 0.210938 -0.226562 -0.468750 +v -0.203125 -0.171875 -0.500000 +v 0.203125 -0.171875 -0.500000 +v -0.210938 -0.390625 -0.164062 +v 0.210938 -0.390625 -0.164062 +v -0.296875 -0.312500 0.265625 +v 0.296875 -0.312500 0.265625 +v -0.343750 -0.148438 0.539062 +v 0.343750 -0.148438 0.539062 +v -0.453125 0.867188 0.382812 +v 0.453125 0.867188 0.382812 +v -0.453125 0.929688 0.070312 +v 0.453125 0.929688 0.070312 +v -0.453125 0.851562 -0.234375 +v 0.453125 0.851562 -0.234375 +v -0.460938 0.523438 -0.429688 +v 0.460938 0.523438 -0.429688 +v -0.726562 0.406250 -0.335938 +v 0.726562 0.406250 -0.335938 +v -0.632812 0.453125 -0.281250 +v 0.632812 0.453125 -0.281250 +v -0.640625 0.703125 -0.054688 +v 0.640625 0.703125 -0.054688 +v -0.796875 0.562500 -0.125000 +v 0.796875 0.562500 -0.125000 +v -0.796875 0.617188 0.117188 +v 0.796875 0.617188 0.117188 +v -0.640625 0.750000 0.195312 +v 0.640625 0.750000 0.195312 +v -0.640625 0.679688 0.445312 +v 0.640625 0.679688 0.445312 +v -0.796875 0.539062 0.359375 +v 0.796875 0.539062 0.359375 +v -0.617188 0.328125 0.585938 +v 0.617188 0.328125 0.585938 +v -0.484375 0.023438 0.546875 +v 0.484375 0.023438 0.546875 +v -0.820312 0.328125 0.203125 +v 0.820312 0.328125 0.203125 +v -0.406250 -0.171875 -0.148438 +v 0.406250 -0.171875 -0.148438 +v -0.429688 -0.195312 0.210938 +v 0.429688 -0.195312 0.210938 +v -0.890625 0.406250 0.234375 +v 0.890625 0.406250 0.234375 +v -0.773438 -0.140625 0.125000 +v 0.773438 -0.140625 0.125000 +v -1.039062 -0.101562 0.328125 +v 1.039062 -0.101562 0.328125 +v -1.281250 0.054688 0.429688 +v 1.281250 0.054688 0.429688 +v -1.351562 0.320312 0.421875 +v 1.351562 0.320312 0.421875 +v -1.234375 0.507812 0.421875 +v 1.234375 0.507812 0.421875 +v -1.023438 0.476562 0.312500 +v 1.023438 0.476562 0.312500 +v -1.015625 0.414062 0.289062 +v 1.015625 0.414062 0.289062 +v -1.187500 0.437500 0.390625 +v 1.187500 0.437500 0.390625 +v -1.265625 0.289062 0.406250 +v 1.265625 0.289062 0.406250 +v -1.210938 0.078125 0.406250 +v 1.210938 0.078125 0.406250 +v -1.031250 -0.039062 0.304688 +v 1.031250 -0.039062 0.304688 +v -0.828125 -0.070312 0.132812 +v 0.828125 -0.070312 0.132812 +v -0.921875 0.359375 0.218750 +v 0.921875 0.359375 0.218750 +v -0.945312 0.304688 0.289062 +v 0.945312 0.304688 0.289062 +v -0.882812 -0.023438 0.210938 +v 0.882812 -0.023438 0.210938 +v -1.039062 0.000000 0.367188 +v 1.039062 0.000000 0.367188 +v -1.187500 0.093750 0.445312 +v 1.187500 0.093750 0.445312 +v -1.234375 0.250000 0.445312 +v 1.234375 0.250000 0.445312 +v -1.171875 0.359375 0.437500 +v 1.171875 0.359375 0.437500 +v -1.023438 0.343750 0.359375 +v 1.023438 0.343750 0.359375 +v -0.843750 0.289062 0.210938 +v 0.843750 0.289062 0.210938 +v -0.835938 0.171875 0.273438 +v 0.835938 0.171875 0.273438 +v -0.757812 0.093750 0.273438 +v 0.757812 0.093750 0.273438 +v -0.820312 0.085938 0.273438 +v 0.820312 0.085938 0.273438 +v -0.843750 0.015625 0.273438 +v 0.843750 0.015625 0.273438 +v -0.812500 -0.015625 0.273438 +v 0.812500 -0.015625 0.273438 +v -0.726562 0.000000 0.070312 +v 0.726562 0.000000 0.070312 +v -0.718750 -0.023438 0.171875 +v 0.718750 -0.023438 0.171875 +v -0.718750 0.039062 0.187500 +v 0.718750 0.039062 0.187500 +v -0.796875 0.203125 0.210938 +v 0.796875 0.203125 0.210938 +v -0.890625 0.242188 0.265625 +v 0.890625 0.242188 0.265625 +v -0.890625 0.234375 0.320312 +v 0.890625 0.234375 0.320312 +v -0.812500 -0.015625 0.320312 +v 0.812500 -0.015625 0.320312 +v -0.851562 0.015625 0.320312 +v 0.851562 0.015625 0.320312 +v -0.828125 0.078125 0.320312 +v 0.828125 0.078125 0.320312 +v -0.765625 0.093750 0.320312 +v 0.765625 0.093750 0.320312 +v -0.843750 0.171875 0.320312 +v 0.843750 0.171875 0.320312 +v -1.039062 0.328125 0.414062 +v 1.039062 0.328125 0.414062 +v -1.187500 0.343750 0.484375 +v 1.187500 0.343750 0.484375 +v -1.257812 0.242188 0.492188 +v 1.257812 0.242188 0.492188 +v -1.210938 0.085938 0.484375 +v 1.210938 0.085938 0.484375 +v -1.046875 0.000000 0.421875 +v 1.046875 0.000000 0.421875 +v -0.882812 -0.015625 0.265625 +v 0.882812 -0.015625 0.265625 +v -0.953125 0.289062 0.343750 +v 0.953125 0.289062 0.343750 +v -0.890625 0.109375 0.328125 +v 0.890625 0.109375 0.328125 +v -0.937500 0.062500 0.335938 +v 0.937500 0.062500 0.335938 +v -1.000000 0.125000 0.367188 +v 1.000000 0.125000 0.367188 +v -0.960938 0.171875 0.351562 +v 0.960938 0.171875 0.351562 +v -1.015625 0.234375 0.375000 +v 1.015625 0.234375 0.375000 +v -1.054688 0.187500 0.382812 +v 1.054688 0.187500 0.382812 +v -1.109375 0.210938 0.390625 +v 1.109375 0.210938 0.390625 +v -1.085938 0.273438 0.390625 +v 1.085938 0.273438 0.390625 +v -1.023438 0.437500 0.484375 +v 1.023438 0.437500 0.484375 +v -1.250000 0.468750 0.546875 +v 1.250000 0.468750 0.546875 +v -1.367188 0.296875 0.500000 +v 1.367188 0.296875 0.500000 +v -1.312500 0.054688 0.531250 +v 1.312500 0.054688 0.531250 +v -1.039062 -0.085938 0.492188 +v 1.039062 -0.085938 0.492188 +v -0.789062 -0.125000 0.328125 +v 0.789062 -0.125000 0.328125 +v -0.859375 0.382812 0.382812 +v 0.859375 0.382812 0.382812 +vn -0.6650 -0.2008 -0.7194 +vn 0.6650 -0.2008 -0.7194 +vn -0.8294 -0.3036 -0.4689 +vn 0.8294 -0.3036 -0.4689 +vn -0.4155 -0.7933 -0.4449 +vn 0.4155 -0.7933 -0.4449 +vn -0.3600 -0.5089 -0.7820 +vn 0.3600 -0.5089 -0.7820 +vn 0.0787 -0.5394 -0.8384 +vn -0.0787 -0.5394 -0.8384 +vn 0.2696 -0.8413 -0.4685 +vn -0.2696 -0.8413 -0.4685 +vn 0.7707 -0.3352 -0.5420 +vn -0.7707 -0.3352 -0.5420 +vn 0.4689 -0.1940 -0.8617 +vn -0.4689 -0.1940 -0.8617 +vn 0.4767 0.1907 -0.8581 +vn -0.4767 0.1907 -0.8581 +vn 0.7672 0.3264 -0.5521 +vn -0.7672 0.3264 -0.5521 +vn 0.2519 0.8173 -0.5182 +vn -0.2519 0.8173 -0.5182 +vn 0.0949 0.5696 -0.8164 +vn -0.0949 0.5696 -0.8164 +vn -0.3667 0.5370 -0.7597 +vn 0.3667 0.5370 -0.7597 +vn -0.4141 0.7672 -0.4898 +vn 0.4141 0.7672 -0.4898 +vn -0.8277 0.2952 -0.4771 +vn 0.8277 0.2952 -0.4771 +vn -0.6713 0.1971 -0.7145 +vn 0.6713 0.1971 -0.7145 +vn -0.8111 0.3244 0.4867 +vn 0.8111 0.3244 0.4867 +vn -0.2052 0.8206 0.5334 +vn 0.2052 0.8206 0.5334 +vn 0.4223 0.7806 0.4607 +vn -0.4223 0.7806 0.4607 +vn 0.8241 0.3225 0.4658 +vn -0.8241 0.3225 0.4658 +vn 0.8137 -0.3487 0.4650 +vn -0.8137 -0.3487 0.4650 +vn 0.4223 -0.7806 0.4607 +vn -0.4223 -0.7806 0.4607 +vn -0.2052 -0.8206 0.5334 +vn 0.2052 -0.8206 0.5334 +vn -0.7995 -0.3510 0.4875 +vn 0.7995 -0.3510 0.4875 +vn -0.4000 -0.0623 -0.9144 +vn 0.4000 -0.0623 -0.9144 +vn -0.3069 -0.1754 -0.9354 +vn 0.3069 -0.1754 -0.9354 +vn -0.0945 -0.1835 -0.9785 +vn 0.0945 -0.1835 -0.9785 +vn 0.0624 -0.0283 -0.9977 +vn -0.0624 -0.0283 -0.9977 +vn 0.0624 0.0260 -0.9977 +vn -0.0624 0.0260 -0.9977 +vn -0.0996 0.1729 -0.9799 +vn 0.0996 0.1729 -0.9799 +vn -0.3036 0.1656 -0.9383 +vn 0.3036 0.1656 -0.9383 +vn -0.4002 0.0572 -0.9147 +vn 0.4002 0.0572 -0.9147 +vn -0.1231 -0.8616 -0.4924 +vn 0.1231 -0.8616 -0.4924 +vn -0.2190 -0.8647 -0.4520 +vn 0.2190 -0.8647 -0.4520 +vn -0.5902 -0.4550 -0.6668 +vn 0.5902 -0.4550 -0.6668 +vn -0.7689 -0.0506 -0.6374 +vn 0.7689 -0.0506 -0.6374 +vn -0.7796 0.0900 -0.6197 +vn 0.7796 0.0900 -0.6197 +vn -0.3241 -0.8188 -0.4739 +vn 0.3241 -0.8188 -0.4739 +vn -0.3857 -0.6629 -0.6417 +vn 0.3857 -0.6629 -0.6417 +vn -0.6895 -0.4193 -0.5906 +vn 0.6895 -0.4193 -0.5906 +vn -0.6588 -0.3634 -0.6588 +vn 0.6588 -0.3634 -0.6588 +vn -0.5465 0.3707 -0.7509 +vn 0.5465 0.3707 -0.7509 +vn -0.5064 0.6464 -0.5706 +vn 0.5064 0.6464 -0.5706 +vn -0.6092 0.5167 -0.6015 +vn 0.6092 0.5167 -0.6015 +vn 0.0441 0.6610 -0.7491 +vn -0.0441 0.6610 -0.7491 +vn 0.7246 0.3187 -0.6110 +vn -0.7246 0.3187 -0.6110 +vn 0.5880 0.5554 -0.5880 +vn -0.5880 0.5554 -0.5880 +vn -0.5361 -0.3909 -0.7482 +vn 0.5361 -0.3909 -0.7482 +vn -0.2207 -0.4690 -0.8552 +vn 0.2207 -0.4690 -0.8552 +vn 0.0794 -0.5321 -0.8429 +vn -0.0794 -0.5321 -0.8429 +vn 0.0825 -0.6575 -0.7490 +vn -0.0825 -0.6575 -0.7490 +vn -0.0457 -0.5667 -0.8226 +vn 0.0457 -0.5667 -0.8226 +vn -0.2784 -0.2130 -0.9365 +vn 0.2784 -0.2130 -0.9365 +vn -0.3813 -0.1824 -0.9063 +vn 0.3813 -0.1824 -0.9063 +vn -0.3357 -0.2878 -0.8969 +vn 0.3357 -0.2878 -0.8969 +vn -0.3762 0.0603 -0.9246 +vn 0.3762 0.0603 -0.9246 +vn 0.1352 0.2680 -0.9539 +vn -0.1352 0.2680 -0.9539 +vn -0.3961 -0.4321 -0.8102 +vn 0.3961 -0.4321 -0.8102 +vn -0.1856 -0.2474 -0.9510 +vn 0.1856 -0.2474 -0.9510 +vn -0.0099 -0.1948 -0.9808 +vn 0.0099 -0.1948 -0.9808 +vn -0.0721 -0.6966 -0.7138 +vn 0.0721 -0.6966 -0.7138 +vn -0.1863 -0.5723 -0.7986 +vn 0.1863 -0.5723 -0.7986 +vn -0.3157 -0.2708 -0.9094 +vn 0.3157 -0.2708 -0.9094 +vn -0.3063 -0.0265 -0.9516 +vn 0.3063 -0.0265 -0.9516 +vn -0.3266 -0.1306 -0.9361 +vn 0.3266 -0.1306 -0.9361 +vn 0.0137 0.0574 -0.9983 +vn -0.0137 0.0574 -0.9983 +vn 0.0026 -0.0656 -0.9978 +vn -0.0026 -0.0656 -0.9978 +vn -0.0000 -0.0000 -1.0000 +vn -0.8174 -0.5744 0.0442 +vn 0.8174 -0.5744 0.0442 +vn -0.9494 0.2297 0.2144 +vn 0.9494 0.2297 0.2144 +vn -0.0825 0.9073 0.4124 +vn 0.0825 0.9073 0.4124 +vn 0.8836 0.3555 -0.3047 +vn -0.8836 0.3555 -0.3047 +vn -0.4207 -0.8797 -0.2218 +vn 0.4207 -0.8797 -0.2218 +vn -0.2873 -0.5747 -0.7663 +vn 0.2873 -0.5747 -0.7663 +vn 0.6542 0.6019 -0.4580 +vn -0.6542 0.6019 -0.4580 +vn -0.1052 0.7892 -0.6051 +vn 0.1052 0.7892 -0.6051 +vn -0.7582 0.2916 -0.5832 +vn 0.7582 0.2916 -0.5832 +vn -0.3889 -0.7130 -0.5834 +vn 0.3889 -0.7130 -0.5834 +vn -0.0463 0.2314 -0.9718 +vn 0.0463 0.2314 -0.9718 +vn -0.0335 -0.4018 -0.9151 +vn 0.0335 -0.4018 -0.9151 +vn 0.4452 -0.1610 -0.8809 +vn -0.4452 -0.1610 -0.8809 +vn 0.2182 -0.4364 -0.8729 +vn -0.2182 -0.4364 -0.8729 +vn -0.4341 -0.1290 -0.8916 +vn 0.4341 -0.1290 -0.8916 +vn -0.3008 0.0501 -0.9524 +vn 0.3008 0.0501 -0.9524 +vn -0.8123 0.3010 -0.4996 +vn 0.8123 0.3010 -0.4996 +vn -0.8753 0.2574 -0.4093 +vn 0.8753 0.2574 -0.4093 +vn -0.9385 0.1601 -0.3060 +vn 0.9385 0.1601 -0.3060 +vn -0.2237 -0.6539 -0.7227 +vn 0.2237 -0.6539 -0.7227 +vn 0.1536 -0.1997 -0.9677 +vn -0.1536 -0.1997 -0.9677 +vn 0.2733 -0.1025 -0.9565 +vn -0.2733 -0.1025 -0.9565 +vn 0.0976 0.1952 -0.9759 +vn -0.0976 0.1952 -0.9759 +vn 0.1582 0.9494 -0.2713 +vn -0.1582 0.9494 -0.2713 +vn 0.6934 0.7082 -0.1328 +vn -0.6934 0.7082 -0.1328 +vn 1.0000 -0.0000 -0.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.3051 -0.9450 -0.1181 +vn 0.3051 -0.9450 -0.1181 +vn -0.0298 -0.2981 -0.9541 +vn 0.0298 -0.2981 -0.9541 +vn -0.1353 -0.3479 -0.9277 +vn 0.1353 -0.3479 -0.9277 +vn 0.5085 -0.2755 -0.8158 +vn -0.5085 -0.2755 -0.8158 +vn 0.3843 -0.0419 -0.9223 +vn -0.3843 -0.0419 -0.9223 +vn 0.2083 0.0374 -0.9774 +vn -0.2083 0.0374 -0.9774 +vn 0.5721 -0.4767 -0.6674 +vn -0.5721 -0.4767 -0.6674 +vn 0.1369 -0.7531 -0.6435 +vn -0.1369 -0.7531 -0.6435 +vn -0.4088 -0.6071 -0.6814 +vn 0.4088 -0.6071 -0.6814 +vn -0.5740 -0.4130 -0.7070 +vn 0.5740 -0.4130 -0.7070 +vn -0.5665 -0.0968 -0.8183 +vn 0.5665 -0.0968 -0.8183 +vn -0.5703 0.1180 -0.8129 +vn 0.5703 0.1180 -0.8129 +vn -0.4823 0.5621 -0.6719 +vn 0.4823 0.5621 -0.6719 +vn -0.2604 0.6114 -0.7473 +vn 0.2604 0.6114 -0.7473 +vn -0.1640 0.3607 -0.9182 +vn 0.1640 0.3607 -0.9182 +vn 0.0178 0.2495 -0.9682 +vn -0.0178 0.2495 -0.9682 +vn -0.3273 -0.4166 -0.8481 +vn 0.3273 -0.4166 -0.8481 +vn -0.2811 -0.2610 -0.9235 +vn 0.2811 -0.2610 -0.9235 +vn 0.2542 -0.6514 -0.7149 +vn -0.2542 -0.6514 -0.7149 +vn 0.0260 -0.8455 -0.5333 +vn -0.0260 -0.8455 -0.5333 +vn 0.3518 -0.2606 -0.8991 +vn -0.3518 -0.2606 -0.8991 +vn 0.3523 -0.0110 -0.9358 +vn -0.3523 -0.0110 -0.9358 +vn 0.1317 0.4608 -0.8777 +vn -0.1317 0.4608 -0.8777 +vn 0.0342 0.6159 -0.7870 +vn -0.0342 0.6159 -0.7870 +vn -0.3603 0.5836 -0.7277 +vn 0.3603 0.5836 -0.7277 +vn -0.4988 0.5300 -0.6858 +vn 0.4988 0.5300 -0.6858 +vn -0.6667 -0.3333 -0.6667 +vn 0.6667 -0.3333 -0.6667 +vn -0.8165 -0.0731 -0.5727 +vn 0.8165 -0.0731 -0.5727 +vn -0.7840 0.1161 -0.6098 +vn 0.7840 0.1161 -0.6098 +vn 0.5306 0.8111 0.2461 +vn -0.5306 0.8111 0.2461 +vn 0.8511 0.3695 0.3730 +vn -0.8511 0.3695 0.3730 +vn 0.2446 0.8675 0.4331 +vn -0.2446 0.8675 0.4331 +vn -0.5924 0.7465 0.3030 +vn 0.5924 0.7465 0.3030 +vn -0.3685 0.8758 0.3118 +vn 0.3685 0.8758 0.3118 +vn -0.2821 0.9151 0.2880 +vn 0.2821 0.9151 0.2880 +vn -0.8561 0.1340 0.4991 +vn 0.8561 0.1340 0.4991 +vn -0.5342 -0.7233 0.4376 +vn 0.5342 -0.7233 0.4376 +vn -0.3849 -0.8131 0.4368 +vn 0.3849 -0.8131 0.4368 +vn -0.2335 -0.5806 0.7800 +vn 0.2335 -0.5806 0.7800 +vn -0.2449 -0.0583 0.9678 +vn 0.2449 -0.0583 0.9678 +vn -0.1163 -0.4535 0.8837 +vn 0.1163 -0.4535 0.8837 +vn -0.1152 -0.9836 0.1388 +vn 0.1152 -0.9836 0.1388 +vn -0.1184 -0.9669 0.2260 +vn 0.1184 -0.9669 0.2260 +vn -0.9597 -0.0085 0.2808 +vn 0.9597 -0.0085 0.2808 +vn -0.9319 0.1629 0.3242 +vn 0.9319 0.1629 0.3242 +vn -0.1626 0.0207 0.9865 +vn 0.1626 0.0207 0.9865 +vn 0.0188 -0.2177 0.9758 +vn -0.0188 -0.2177 0.9758 +vn -0.7538 -0.2926 0.5884 +vn 0.7538 -0.2926 0.5884 +vn -0.9196 0.1379 0.3678 +vn 0.9196 0.1379 0.3678 +vn -0.9297 0.3127 0.1944 +vn 0.9297 0.3127 0.1944 +vn -0.9120 0.3376 0.2329 +vn 0.9120 0.3376 0.2329 +vn -0.9407 0.3338 0.0607 +vn 0.9407 0.3338 0.0607 +vn -0.1761 -0.8805 0.4402 +vn 0.1761 -0.8805 0.4402 +vn -0.3708 -0.4733 0.7991 +vn 0.3708 -0.4733 0.7991 +vn -0.3107 -0.8284 0.4660 +vn 0.3107 -0.8284 0.4660 +vn -0.2793 -0.9515 0.1287 +vn 0.2793 -0.9515 0.1287 +vn -0.3139 -0.9321 0.1807 +vn 0.3139 -0.9321 0.1807 +vn -0.9762 -0.2083 0.0609 +vn 0.9762 -0.2083 0.0609 +vn -0.8267 -0.5066 -0.2447 +vn 0.8267 -0.5066 -0.2447 +vn -0.3449 -0.1158 0.9315 +vn 0.3449 -0.1158 0.9315 +vn -0.1203 0.9644 -0.2355 +vn 0.1203 0.9644 -0.2355 +vn -0.1275 0.9744 0.1851 +vn 0.1275 0.9744 0.1851 +vn -0.3492 0.5947 0.7241 +vn 0.3492 0.5947 0.7241 +vn -0.4153 0.8981 0.1449 +vn 0.4153 0.8981 0.1449 +vn -0.1845 0.7036 -0.6863 +vn 0.1845 0.7036 -0.6863 +vn -0.6056 0.7794 -0.1608 +vn 0.6056 0.7794 -0.1608 +vn -0.7033 0.6806 0.2053 +vn 0.7033 0.6806 0.2053 +vn -0.6679 0.2007 0.7166 +vn 0.6679 0.2007 0.7166 +vn -0.4948 0.4342 0.7528 +vn 0.4948 0.4342 0.7528 +vn -0.6423 0.7459 0.1761 +vn 0.6423 0.7459 0.1761 +vn -0.7182 0.6788 -0.1530 +vn 0.7182 0.6788 -0.1530 +vn -0.7388 0.3972 -0.5444 +vn 0.7388 0.3972 -0.5444 +vn -0.3428 0.9261 0.1579 +vn 0.3428 0.9261 0.1579 +vn -0.2270 0.5740 -0.7867 +vn 0.2270 0.5740 -0.7867 +vn 0.1722 0.1046 0.9795 +vn -0.1722 0.1046 0.9795 +vn -0.0425 0.9150 -0.4013 +vn 0.0425 0.9150 -0.4013 +vn 0.1616 0.1847 -0.9694 +vn -0.1616 0.1847 -0.9694 +vn -0.9791 0.1973 -0.0483 +vn 0.9791 0.1973 -0.0483 +vn -0.9470 0.0918 -0.3079 +vn 0.9470 0.0918 -0.3079 +vn -0.9794 0.1905 0.0661 +vn 0.9794 0.1905 0.0661 +vn -0.9938 0.0312 0.1070 +vn 0.9938 0.0312 0.1070 +vn -0.7116 -0.7008 -0.0501 +vn 0.7116 -0.7008 -0.0501 +vn -0.3722 -0.9243 -0.0847 +vn 0.3722 -0.9243 -0.0847 +vn -0.4465 -0.8644 -0.2310 +vn 0.4465 -0.8644 -0.2310 +vn -0.6066 -0.7578 -0.2405 +vn 0.6066 -0.7578 -0.2405 +vn -0.7325 -0.6368 -0.2407 +vn 0.7325 -0.6368 -0.2407 +vn -0.2637 -0.4499 -0.8533 +vn 0.2637 -0.4499 -0.8533 +vn -0.5568 -0.3181 0.7673 +vn 0.5568 -0.3181 0.7673 +vn -0.5004 -0.2807 0.8190 +vn 0.5004 -0.2807 0.8190 +vn -0.3190 -0.8494 0.4205 +vn 0.3190 -0.8494 0.4205 +vn -0.7198 -0.6356 0.2793 +vn 0.7198 -0.6356 0.2793 +vn -0.4972 -0.4408 0.7473 +vn 0.4972 -0.4408 0.7473 +vn -0.3506 0.3807 -0.8557 +vn 0.3506 0.3807 -0.8557 +vn -0.4566 0.1715 -0.8730 +vn 0.4566 0.1715 -0.8730 +vn -0.2583 0.1055 -0.9603 +vn 0.2583 0.1055 -0.9603 +vn -0.2455 -0.0802 -0.9661 +vn 0.2455 -0.0802 -0.9661 +vn -0.4643 -0.0599 -0.8837 +vn 0.4643 -0.0599 -0.8837 +vn -0.6225 -0.3045 -0.7210 +vn 0.6225 -0.3045 -0.7210 +vn -0.4500 0.6590 -0.6027 +vn 0.4500 0.6590 -0.6027 +vn 0.2667 0.8309 -0.4884 +vn -0.2667 0.8309 -0.4884 +vn 0.8284 0.2291 -0.5111 +vn -0.8284 0.2291 -0.5111 +vn 0.5251 -0.3566 -0.7727 +vn -0.5251 -0.3566 -0.7727 +vn -0.4546 -0.5665 -0.6873 +vn 0.4546 -0.5665 -0.6873 +vn -0.6996 -0.4497 -0.5552 +vn 0.6996 -0.4497 -0.5552 +vn -0.7220 -0.6827 0.1126 +vn 0.7220 -0.6827 0.1126 +vn 0.1919 0.2860 -0.9388 +vn -0.1919 0.2860 -0.9388 +vn -0.9048 -0.3734 0.2047 +vn 0.9048 -0.3734 0.2047 +vn -0.1034 0.1551 -0.9825 +vn 0.1034 0.1551 -0.9825 +vn -0.0841 0.9318 -0.3530 +vn 0.0841 0.9318 -0.3530 +vn -0.6446 -0.0883 -0.7594 +vn 0.6446 -0.0883 -0.7594 +vn -0.4309 0.4740 -0.7678 +vn 0.4309 0.4740 -0.7678 +vn -0.8032 -0.4847 -0.3462 +vn 0.8032 -0.4847 -0.3462 +vn -0.5811 -0.4128 -0.7014 +vn 0.5811 -0.4128 -0.7014 +vn -0.5910 -0.4305 -0.6822 +vn 0.5910 -0.4305 -0.6822 +vn -0.9818 -0.1804 0.0591 +vn 0.9818 -0.1804 0.0591 +vn -0.9105 -0.3965 0.1175 +vn 0.9105 -0.3965 0.1175 +vn -0.9972 -0.0181 0.0725 +vn 0.9972 -0.0181 0.0725 +vn -0.7313 -0.6543 -0.1925 +vn 0.7313 -0.6543 -0.1925 +vn -0.7867 -0.6079 -0.1073 +vn 0.7867 -0.6079 -0.1073 +vn -0.7022 -0.7022 -0.1170 +vn 0.7022 -0.7022 -0.1170 +vn -0.1840 0.9816 0.0511 +vn 0.1840 0.9816 0.0511 +vn -0.9352 0.3301 -0.1284 +vn 0.9352 0.3301 -0.1284 +vn -0.6633 -0.7463 -0.0553 +vn 0.6633 -0.7463 -0.0553 +vn 0.0085 0.9970 -0.0767 +vn -0.0085 0.9970 -0.0767 +vn -0.6237 -0.7061 -0.3354 +vn 0.6237 -0.7061 -0.3354 +vn -0.2733 -0.8925 -0.3587 +vn 0.2733 -0.8925 -0.3587 +vn 0.8328 -0.5080 0.2200 +vn -0.8328 -0.5080 0.2200 +vn 0.8339 0.2377 0.4981 +vn -0.8339 0.2377 0.4981 +vn 0.5655 0.7847 0.2539 +vn -0.5655 0.7847 0.2539 +vn 0.0560 0.9962 -0.0672 +vn -0.0560 0.9962 -0.0672 +vn -0.1445 0.0222 -0.9893 +vn 0.1445 0.0222 -0.9893 +vn -0.3275 0.0645 -0.9427 +vn 0.3275 0.0645 -0.9427 +vn -0.3127 0.0232 -0.9496 +vn 0.3127 0.0232 -0.9496 +vn -0.1710 0.0274 -0.9849 +vn 0.1710 0.0274 -0.9849 +vn -0.3487 0.2849 -0.8929 +vn 0.3487 0.2849 -0.8929 +vn -0.4006 -0.0343 -0.9156 +vn 0.4006 -0.0343 -0.9156 +vn -0.2572 -0.0603 -0.9645 +vn 0.2572 -0.0603 -0.9645 +vn -0.0637 -0.0106 -0.9979 +vn 0.0637 -0.0106 -0.9979 +vn 0.3637 0.7039 -0.6101 +vn -0.3637 0.7039 -0.6101 +vn -0.6299 0.0355 -0.7759 +vn 0.6299 0.0355 -0.7759 +vn -0.4472 -0.2002 -0.8717 +vn 0.4472 -0.2002 -0.8717 +vn -0.5072 -0.2141 -0.8348 +vn 0.5072 -0.2141 -0.8348 +vn -0.5258 0.2619 -0.8093 +vn 0.5258 0.2619 -0.8093 +vn -0.2980 0.5802 -0.7580 +vn 0.2980 0.5802 -0.7580 +vn -0.0930 -0.9924 0.0805 +vn 0.0930 -0.9924 0.0805 +vn -0.5006 -0.8657 -0.0080 +vn 0.5006 -0.8657 -0.0080 +vn -0.9285 -0.2497 -0.2748 +vn 0.9285 -0.2497 -0.2748 +vn -0.8393 0.5424 0.0378 +vn 0.8393 0.5424 0.0378 +vn 0.2355 0.9367 0.2589 +vn -0.2355 0.9367 0.2589 +vn 0.4499 0.8838 0.1285 +vn -0.4499 0.8838 0.1285 +vn 0.5384 -0.0098 0.8427 +vn -0.5384 -0.0098 0.8427 +vn 0.1910 -0.0241 0.9813 +vn -0.1910 -0.0241 0.9813 +vn -0.4046 0.0266 0.9141 +vn 0.4046 0.0266 0.9141 +vn 0.7819 0.6231 -0.0197 +vn -0.7819 0.6231 -0.0197 +vn -0.5428 -0.2063 0.8142 +vn 0.5428 -0.2063 0.8142 +vn 0.2474 -0.9231 0.2945 +vn -0.2474 -0.9231 0.2945 +vt 0.843250 0.588863 +vt 0.833697 0.611927 +vt 0.794218 0.611927 +vt 0.815334 0.560948 +vt 0.866314 0.937441 +vt 0.866314 0.897962 +vt 0.889378 0.888409 +vt 0.917293 0.916324 +vt 0.746541 0.611927 +vt 0.781622 0.527235 +vt 0.866314 0.985118 +vt 0.951006 0.950037 +vt 0.815334 0.662907 +vt 0.781622 0.696619 +vt 0.781622 0.950037 +vt 0.815334 0.916325 +vt 0.843250 0.634991 +vt 0.843250 0.888409 +vt 0.866314 0.644544 +vt 0.866314 0.684023 +vt 0.794218 0.865345 +vt 0.833697 0.865345 +vt 0.866314 0.731700 +vt 0.746541 0.865345 +vt 0.917293 0.662907 +vt 0.951006 0.696619 +vt 0.781622 0.780653 +vt 0.815334 0.814366 +vt 0.889378 0.634991 +vt 0.843250 0.842281 +vt 0.898931 0.611927 +vt 0.938410 0.611927 +vt 0.866314 0.793249 +vt 0.866314 0.832728 +vt 0.986087 0.611927 +vt 0.866314 0.745572 +vt 0.917294 0.560947 +vt 0.951006 0.527235 +vt 0.951006 0.780653 +vt 0.917294 0.814365 +vt 0.889378 0.588863 +vt 0.889378 0.842281 +vt 0.866314 0.579310 +vt 0.866314 0.539831 +vt 0.938410 0.865345 +vt 0.898931 0.865345 +vt 0.866314 0.492154 +vt 0.986087 0.865345 +vt 0.866314 0.585461 +vt 0.847600 0.593213 +vt 0.892780 0.865345 +vt 0.885028 0.884059 +vt 0.885028 0.593213 +vt 0.885028 0.846631 +vt 0.892780 0.611927 +vt 0.866314 0.838879 +vt 0.885028 0.630641 +vt 0.847600 0.846631 +vt 0.866314 0.638393 +vt 0.839848 0.865345 +vt 0.847600 0.630641 +vt 0.847600 0.884059 +vt 0.839848 0.611927 +vt 0.866314 0.891811 +vt 0.866314 0.611927 +vt 0.866314 0.865345 +vt 0.520711 0.060503 +vt 0.517028 0.068490 +vt 0.500000 0.064527 +vt 0.500000 0.054411 +vt 0.482972 0.068490 +vt 0.479289 0.060503 +vt 0.530457 0.065062 +vt 0.522612 0.070678 +vt 0.477388 0.070678 +vt 0.469543 0.065062 +vt 0.532878 0.067822 +vt 0.526301 0.079422 +vt 0.473699 0.079422 +vt 0.467122 0.067822 +vt 0.544695 0.083023 +vt 0.529228 0.091098 +vt 0.470772 0.091098 +vt 0.455305 0.083023 +vt 0.565647 0.115495 +vt 0.537536 0.127779 +vt 0.462464 0.127779 +vt 0.434353 0.115495 +vt 0.586916 0.172042 +vt 0.626605 0.208159 +vt 0.600470 0.238288 +vt 0.535885 0.215568 +vt 0.399530 0.238288 +vt 0.373395 0.208159 +vt 0.413084 0.172042 +vt 0.464115 0.215568 +vt 0.650908 0.240294 +vt 0.636962 0.261221 +vt 0.363038 0.261221 +vt 0.349092 0.240294 +vt 0.689501 0.268805 +vt 0.655896 0.284413 +vt 0.344104 0.284413 +vt 0.310499 0.268805 +vt 0.684517 0.317795 +vt 0.659507 0.313152 +vt 0.340493 0.313152 +vt 0.315483 0.317795 +vt 0.671357 0.334694 +vt 0.649107 0.322437 +vt 0.350893 0.322437 +vt 0.328643 0.334694 +vt 0.636775 0.370732 +vt 0.613636 0.353108 +vt 0.386364 0.353108 +vt 0.363225 0.370732 +vt 0.602261 0.395588 +vt 0.594178 0.371277 +vt 0.405822 0.371277 +vt 0.397739 0.395588 +vt 0.581044 0.398468 +vt 0.577351 0.373341 +vt 0.422649 0.373341 +vt 0.418956 0.398468 +vt 0.532016 0.387365 +vt 0.539817 0.354339 +vt 0.460183 0.354339 +vt 0.467984 0.387365 +vt 0.500000 0.382860 +vt 0.500000 0.340417 +vt 0.559135 0.334326 +vt 0.579057 0.335646 +vt 0.420943 0.335646 +vt 0.440865 0.334326 +vt 0.592090 0.332885 +vt 0.407910 0.332885 +vt 0.606163 0.325516 +vt 0.393837 0.325516 +vt 0.628251 0.311636 +vt 0.371749 0.311636 +vt 0.635551 0.300507 +vt 0.364449 0.300507 +vt 0.631484 0.283889 +vt 0.368516 0.283889 +vt 0.611331 0.264411 +vt 0.388669 0.264411 +vt 0.592372 0.254897 +vt 0.407628 0.254897 +vt 0.559669 0.267717 +vt 0.440331 0.267717 +vt 0.550878 0.277832 +vt 0.500000 0.252445 +vt 0.449122 0.277832 +vt 0.544001 0.314523 +vt 0.455999 0.314523 +vt 0.500000 0.295691 +vt 0.543637 0.293371 +vt 0.456363 0.293371 +vt 0.506819 0.075382 +vt 0.500000 0.073497 +vt 0.493181 0.075382 +vt 0.511782 0.080633 +vt 0.488218 0.080633 +vt 0.512172 0.093457 +vt 0.487828 0.093457 +vt 0.514257 0.133422 +vt 0.513874 0.097191 +vt 0.486126 0.097191 +vt 0.485743 0.133422 +vt 0.520226 0.164615 +vt 0.500000 0.157864 +vt 0.500000 0.134352 +vt 0.479774 0.164615 +vt 0.500000 0.100063 +vt 0.500000 0.091346 +vt 0.530258 0.180239 +vt 0.521901 0.181560 +vt 0.517666 0.172353 +vt 0.482334 0.172353 +vt 0.478099 0.181560 +vt 0.469742 0.180239 +vt 0.523673 0.198817 +vt 0.518957 0.194728 +vt 0.481043 0.194728 +vt 0.476327 0.198817 +vt 0.500000 0.203867 +vt 0.508211 0.197295 +vt 0.491789 0.197295 +vt 0.500000 0.197278 +vt 0.500000 0.192167 +vt 0.500000 0.165170 +vt 0.513538 0.176949 +vt 0.500000 0.171718 +vt 0.486462 0.176949 +vt 0.500000 0.186182 +vt 0.508818 0.192407 +vt 0.491182 0.192407 +vt 0.515232 0.190709 +vt 0.484768 0.190709 +vt 0.516908 0.181873 +vt 0.483092 0.181873 +vt 0.544209 0.172814 +vt 0.455791 0.172814 +vt 0.541327 0.154899 +vt 0.458673 0.154899 +vt 0.578661 0.139176 +vt 0.421339 0.139176 +vt 0.583245 0.154155 +vt 0.416755 0.154155 +vt 0.500000 0.089977 +vt 0.509911 0.090724 +vt 0.490089 0.090724 +vt 0.509713 0.082236 +vt 0.490287 0.082236 +vt 0.505196 0.077083 +vt 0.494804 0.077083 +vt 0.500000 0.075473 +vt 0.503445 0.080840 +vt 0.500000 0.080320 +vt 0.496555 0.080840 +vt 0.506660 0.083289 +vt 0.493340 0.083289 +vt 0.506822 0.086791 +vt 0.493178 0.086791 +vt 0.500000 0.085637 +vt 0.562361 0.284338 +vt 0.559190 0.294882 +vt 0.437639 0.284338 +vt 0.440810 0.294882 +vt 0.563180 0.307151 +vt 0.436820 0.307151 +vt 0.570458 0.318697 +vt 0.429542 0.318697 +vt 0.569243 0.278245 +vt 0.430757 0.278245 +vt 0.589914 0.271772 +vt 0.410086 0.271772 +vt 0.602190 0.277180 +vt 0.397810 0.277180 +vt 0.617110 0.287175 +vt 0.382890 0.287175 +vt 0.618074 0.299197 +vt 0.381926 0.299197 +vt 0.615871 0.307438 +vt 0.384129 0.307438 +vt 0.598424 0.313725 +vt 0.401576 0.313725 +vt 0.590828 0.319797 +vt 0.409172 0.319797 +vt 0.582130 0.320991 +vt 0.417870 0.320991 +vt 0.578615 0.309394 +vt 0.583998 0.312892 +vt 0.421385 0.309394 +vt 0.416002 0.312892 +vt 0.589656 0.312336 +vt 0.410344 0.312336 +vt 0.596347 0.309249 +vt 0.403653 0.309249 +vt 0.606014 0.302517 +vt 0.393986 0.302517 +vt 0.607735 0.297520 +vt 0.392265 0.297520 +vt 0.606985 0.291216 +vt 0.393015 0.291216 +vt 0.598275 0.283083 +vt 0.401725 0.283083 +vt 0.589866 0.280167 +vt 0.410134 0.280167 +vt 0.576352 0.284624 +vt 0.423648 0.284624 +vt 0.572831 0.289915 +vt 0.427169 0.289915 +vt 0.573307 0.303342 +vt 0.426693 0.303342 +vt 0.572447 0.295716 +vt 0.427553 0.295716 +vt 0.529647 0.428636 +vt 0.500000 0.428636 +vt 0.470353 0.428636 +vt 0.584616 0.428636 +vt 0.415384 0.428636 +vt 0.622301 0.417889 +vt 0.377699 0.417889 +vt 0.666214 0.388954 +vt 0.333786 0.388954 +vt 0.701481 0.344467 +vt 0.298519 0.344467 +vt 0.712163 0.315527 +vt 0.287837 0.315527 +vt 0.704305 0.260225 +vt 0.295695 0.260225 +vt 0.672947 0.224880 +vt 0.327053 0.224880 +vt 0.640497 0.198841 +vt 0.359503 0.198841 +vt 0.603553 0.023452 +vt 0.625128 0.029461 +vt 0.635753 0.082198 +vt 0.598617 0.056841 +vt 0.364247 0.082198 +vt 0.374872 0.029461 +vt 0.396447 0.023452 +vt 0.401383 0.056841 +vt 0.546781 0.009442 +vt 0.556354 0.040906 +vt 0.453219 0.009442 +vt 0.443646 0.040906 +vt 0.500000 0.033223 +vt 0.527159 0.049514 +vt 0.472841 0.049514 +vt 0.537222 0.060794 +vt 0.462778 0.060794 +vt 0.558499 0.065137 +vt 0.441501 0.065137 +vt 0.588127 0.085177 +vt 0.411873 0.085177 +vt 0.607239 0.113940 +vt 0.392761 0.113940 +vt 0.612663 0.133675 +vt 0.605467 0.151503 +vt 0.394533 0.151503 +vt 0.387337 0.133675 +vt 0.600708 0.162985 +vt 0.399292 0.162985 +vt 0.922374 0.064228 +vt 0.859647 0.117994 +vt 0.823287 0.101559 +vt 0.861342 0.027230 +vt 0.176713 0.101559 +vt 0.140353 0.117994 +vt 0.077626 0.064228 +vt 0.138658 0.027230 +vt 0.765863 0.087001 +vt 0.774604 0.010837 +vt 0.234137 0.087001 +vt 0.225396 0.010837 +vt 0.661952 0.087561 +vt 0.647010 0.028716 +vt 0.338048 0.087561 +vt 0.352990 0.028716 +vt 0.743592 0.198572 +vt 0.766410 0.233065 +vt 0.256408 0.198572 +vt 0.233590 0.233065 +vt 0.987633 0.154243 +vt 0.889478 0.177602 +vt 0.110522 0.177602 +vt 0.012367 0.154243 +vt 0.899807 0.420886 +vt 0.844317 0.347370 +vt 0.881169 0.309153 +vt 0.958963 0.357385 +vt 0.118831 0.309153 +vt 0.155683 0.347370 +vt 0.100193 0.420886 +vt 0.041037 0.357385 +vt 0.903302 0.261367 +vt 0.999860 0.253531 +vt 0.096698 0.261367 +vt 0.000140 0.253531 +vt 0.724763 0.340212 +vt 0.744725 0.304629 +vt 0.766113 0.319494 +vt 0.255275 0.304629 +vt 0.275237 0.340212 +vt 0.233887 0.319494 +vt 0.793427 0.280495 +vt 0.826663 0.297810 +vt 0.206573 0.280495 +vt 0.173337 0.297810 +vt 0.823620 0.254612 +vt 0.855331 0.267956 +vt 0.176380 0.254612 +vt 0.144669 0.267956 +vt 0.835860 0.225225 +vt 0.868309 0.233525 +vt 0.164140 0.225225 +vt 0.131691 0.233525 +vt 0.813499 0.190705 +vt 0.851288 0.181145 +vt 0.148712 0.181145 +vt 0.186501 0.190705 +vt 0.772263 0.374010 +vt 0.227737 0.374010 +vt 0.744519 0.390057 +vt 0.255481 0.390057 +vt 0.824765 0.470987 +vt 0.175235 0.470987 +vt 0.792141 0.464714 +vt 0.742181 0.461543 +vt 0.726855 0.432574 +vt 0.273145 0.432574 +vt 0.257819 0.461543 +vt 0.207859 0.464714 +vt 0.795638 0.489991 +vt 0.204362 0.489991 +vt 0.786137 0.227788 +vt 0.213863 0.227788 +vt 0.802950 0.203415 +vt 0.197050 0.203415 +vt 0.769334 0.128771 +vt 0.691484 0.146686 +vt 0.230666 0.128771 +vt 0.308516 0.146686 +vt 0.780113 0.169386 +vt 0.219887 0.169386 +vt 0.803789 0.171181 +vt 0.830917 0.139518 +vt 0.169083 0.139518 +vt 0.196211 0.171181 +vt 0.574628 0.959188 +vt 0.464516 0.959188 +vt 0.477326 0.891852 +vt 0.545439 0.884582 +vt 0.272900 0.891852 +vt 0.285710 0.959188 +vt 0.175598 0.959188 +vt 0.204787 0.884582 +vt 0.605134 0.846978 +vt 0.715894 0.897069 +vt 0.145092 0.846978 +vt 0.034332 0.897069 +vt 0.605360 0.784410 +vt 0.683874 0.757011 +vt 0.144866 0.784410 +vt 0.066352 0.757011 +vt 0.574835 0.744212 +vt 0.617867 0.719156 +vt 0.175391 0.744212 +vt 0.132359 0.719156 +vt 0.534996 0.712528 +vt 0.568728 0.682132 +vt 0.215230 0.712528 +vt 0.181498 0.682132 +vt 0.483006 0.686791 +vt 0.508539 0.641024 +vt 0.267220 0.686791 +vt 0.241687 0.641024 +vt 0.513415 0.736977 +vt 0.478880 0.719593 +vt 0.271346 0.719593 +vt 0.236811 0.736977 +vt 0.541117 0.760754 +vt 0.209109 0.760754 +vt 0.557599 0.789442 +vt 0.192627 0.789442 +vt 0.553841 0.821849 +vt 0.196385 0.821849 +vt 0.524671 0.842380 +vt 0.225555 0.842380 +vt 0.485193 0.845321 +vt 0.265033 0.845321 +vt 0.786150 0.181127 +vt 0.770208 0.191225 +vt 0.213850 0.181127 +vt 0.229792 0.191225 +vt 0.408153 0.587507 +vt 0.409610 0.674022 +vt 0.342073 0.587507 +vt 0.340616 0.674022 +vt 0.400301 0.910556 +vt 0.414155 0.878318 +vt 0.336071 0.878318 +vt 0.349925 0.910556 +vt 0.443630 0.713731 +vt 0.306596 0.713731 +vt 0.429725 0.728622 +vt 0.392812 0.710774 +vt 0.357414 0.710774 +vt 0.320501 0.728622 +vt 0.422979 0.754609 +vt 0.432640 0.746527 +vt 0.327247 0.754609 +vt 0.317586 0.746527 +vt 0.427719 0.796173 +vt 0.391578 0.815187 +vt 0.358648 0.815187 +vt 0.322507 0.796173 +vt 0.448277 0.830976 +vt 0.301949 0.830976 +vt 0.797710 0.195652 +vt 0.802580 0.199758 +vt 0.197420 0.199758 +vt 0.202290 0.195652 +vt 0.789609 0.184671 +vt 0.210391 0.184671 +vt 0.466042 0.804091 +vt 0.490498 0.816075 +vt 0.284184 0.804091 +vt 0.259728 0.816075 +vt 0.448042 0.783921 +vt 0.302184 0.783921 +vt 0.438745 0.764960 +vt 0.311481 0.764960 +vt 0.445216 0.756351 +vt 0.305010 0.756351 +vt 0.449819 0.743458 +vt 0.300407 0.743458 +vt 0.456307 0.732687 +vt 0.293919 0.732687 +vt 0.475471 0.740871 +vt 0.274755 0.740871 +vt 0.514211 0.817769 +vt 0.236015 0.817769 +vt 0.527961 0.808598 +vt 0.222265 0.808598 +vt 0.530079 0.790754 +vt 0.220147 0.790754 +vt 0.518620 0.772385 +vt 0.231606 0.772385 +vt 0.498668 0.755033 +vt 0.251558 0.755033 +vt 0.468029 0.756171 +vt 0.459660 0.770459 +vt 0.282197 0.756171 +vt 0.290566 0.770459 +vt 0.487167 0.769899 +vt 0.477354 0.785393 +vt 0.263059 0.769899 +vt 0.272872 0.785393 +vt 0.504617 0.782999 +vt 0.496545 0.797122 +vt 0.245609 0.782999 +vt 0.253681 0.797122 +vt 0.516137 0.792591 +vt 0.513713 0.804019 +vt 0.234089 0.792591 +vt 0.236513 0.804019 +vt 0.574269 0.607668 +vt 0.613510 0.655816 +vt 0.175957 0.607668 +vt 0.136716 0.655816 +vt 0.644031 0.693270 +vt 0.106195 0.693270 +vt 0.668163 0.712097 +vt 0.082063 0.712097 +vt 0.727131 0.698475 +vt 0.676584 0.686010 +vt 0.023095 0.698475 +vt 0.073642 0.686010 +vt 0.729804 0.624370 +vt 0.667013 0.640198 +vt 0.020422 0.624370 +vt 0.083213 0.640198 +vt 0.721292 0.572934 +vt 0.648152 0.594596 +vt 0.028934 0.572934 +vt 0.102074 0.594596 +vt 0.630034 0.557583 +vt 0.717709 0.538143 +vt 0.032517 0.538143 +vt 0.120192 0.557583 +vt 0.526877 0.539235 +vt 0.223349 0.539235 +s 0 +f 47/1/1 1/2/1 3/3/1 45/4/1 +f 4/5/2 2/6/2 48/7/2 46/8/2 +f 45/4/3 3/3/3 5/9/3 43/10/3 +f 6/11/4 4/5/4 46/8/4 44/12/4 +f 3/3/5 9/13/5 7/14/5 5/9/5 +f 8/15/6 10/16/6 4/5/6 6/11/6 +f 1/2/7 11/17/7 9/13/7 3/3/7 +f 10/16/8 12/18/8 2/6/8 4/5/8 +f 11/17/9 13/19/9 15/20/9 9/13/9 +f 16/21/10 14/22/10 12/18/10 10/16/10 +f 9/13/11 15/20/11 17/23/11 7/14/11 +f 18/24/12 16/21/12 10/16/12 8/15/12 +f 15/20/13 21/25/13 19/26/13 17/23/13 +f 20/27/14 22/28/14 16/21/14 18/24/14 +f 13/19/15 23/29/15 21/25/15 15/20/15 +f 22/28/16 24/30/16 14/22/16 16/21/16 +f 23/29/17 25/31/17 27/32/17 21/25/17 +f 28/33/18 26/34/18 24/30/18 22/28/18 +f 21/25/19 27/32/19 29/35/19 19/26/19 +f 30/36/20 28/33/20 22/28/20 20/27/20 +f 27/32/21 33/37/21 31/38/21 29/35/21 +f 32/39/22 34/40/22 28/33/22 30/36/22 +f 25/31/23 35/41/23 33/37/23 27/32/23 +f 34/40/24 36/42/24 26/34/24 28/33/24 +f 35/41/25 37/43/25 39/44/25 33/37/25 +f 40/45/26 38/46/26 36/42/26 34/40/26 +f 33/37/27 39/44/27 41/47/27 31/38/27 +f 42/48/28 40/45/28 34/40/28 32/39/28 +f 39/44/29 45/4/29 43/10/29 41/47/29 +f 44/12/30 46/8/30 40/45/30 42/48/30 +f 37/43/31 47/1/31 45/4/31 39/44/31 +f 46/8/32 48/7/32 38/46/32 40/45/32 +f 47/1/33 37/43/33 51/49/33 49/50/33 +f 52/51/34 38/46/34 48/7/34 50/52/34 +f 37/43/35 35/41/35 53/53/35 51/49/35 +f 54/54/36 36/42/36 38/46/36 52/51/36 +f 35/41/37 25/31/37 55/55/37 53/53/37 +f 56/56/38 26/34/38 36/42/38 54/54/38 +f 25/31/39 23/29/39 57/57/39 55/55/39 +f 58/58/40 24/30/40 26/34/40 56/56/40 +f 23/29/41 13/19/41 59/59/41 57/57/41 +f 60/60/42 14/22/42 24/30/42 58/58/42 +f 13/19/43 11/17/43 63/61/43 59/59/43 +f 64/62/44 12/18/44 14/22/44 60/60/44 +f 11/17/45 1/2/45 65/63/45 63/61/45 +f 66/64/46 2/6/46 12/18/46 64/62/46 +f 1/2/47 47/1/47 49/50/47 65/63/47 +f 50/52/48 48/7/48 2/6/48 66/64/48 +f 61/65/49 65/63/49 49/50/49 +f 50/52/50 66/64/50 62/66/50 +f 63/61/51 65/63/51 61/65/51 +f 62/66/52 66/64/52 64/62/52 +f 61/65/53 59/59/53 63/61/53 +f 64/62/54 60/60/54 62/66/54 +f 61/65/55 57/57/55 59/59/55 +f 60/60/56 58/58/56 62/66/56 +f 61/65/57 55/55/57 57/57/57 +f 58/58/58 56/56/58 62/66/58 +f 61/65/59 53/53/59 55/55/59 +f 56/56/60 54/54/60 62/66/60 +f 61/65/61 51/49/61 53/53/61 +f 54/54/62 52/51/62 62/66/62 +f 61/65/63 49/50/63 51/49/63 +f 52/51/64 50/52/64 62/66/64 +f 89/67/65 174/68/65 176/69/65 91/70/65 +f 176/69/66 175/71/66 90/72/66 91/70/66 +f 87/73/67 172/74/67 174/68/67 89/67/67 +f 175/71/68 173/75/68 88/76/68 90/72/68 +f 85/77/69 170/78/69 172/74/69 87/73/69 +f 173/75/70 171/79/70 86/80/70 88/76/70 +f 83/81/71 168/82/71 170/78/71 85/77/71 +f 171/79/72 169/83/72 84/84/72 86/80/72 +f 81/85/73 166/86/73 168/82/73 83/81/73 +f 169/83/74 167/87/74 82/88/74 84/84/74 +f 79/89/75 92/90/75 146/91/75 164/92/75 +f 147/93/76 93/94/76 80/95/76 165/96/76 +f 92/90/77 94/97/77 148/98/77 146/91/77 +f 149/99/78 95/100/78 93/94/78 147/93/78 +f 94/97/79 96/101/79 150/102/79 148/98/79 +f 151/103/80 97/104/80 95/100/80 149/99/80 +f 96/101/81 98/105/81 152/106/81 150/102/81 +f 153/107/82 99/108/82 97/104/82 151/103/82 +f 98/105/83 100/109/83 154/110/83 152/106/83 +f 155/111/84 101/112/84 99/108/84 153/107/84 +f 100/109/85 102/113/85 156/114/85 154/110/85 +f 157/115/86 103/116/86 101/112/86 155/111/86 +f 102/113/87 104/117/87 158/118/87 156/114/87 +f 159/119/88 105/120/88 103/116/88 157/115/88 +f 104/117/89 106/121/89 160/122/89 158/118/89 +f 161/123/90 107/124/90 105/120/90 159/119/90 +f 106/121/91 108/125/91 162/126/91 160/122/91 +f 163/127/92 109/128/92 107/124/92 161/123/92 +f 108/125/93 67/129/93 68/130/93 162/126/93 +f 68/130/94 67/129/94 109/128/94 163/127/94 +f 110/131/95 128/132/95 160/122/95 162/126/95 +f 161/123/96 129/133/96 111/134/96 163/127/96 +f 128/132/97 179/135/97 158/118/97 160/122/97 +f 159/119/98 180/136/98 129/133/98 161/123/98 +f 126/137/99 156/114/99 158/118/99 179/135/99 +f 159/119/100 157/115/100 127/138/100 180/136/100 +f 124/139/101 154/110/101 156/114/101 126/137/101 +f 157/115/102 155/111/102 125/140/102 127/138/102 +f 122/141/103 152/106/103 154/110/103 124/139/103 +f 155/111/104 153/107/104 123/142/104 125/140/104 +f 120/143/105 150/102/105 152/106/105 122/141/105 +f 153/107/106 151/103/106 121/144/106 123/142/106 +f 118/145/107 148/98/107 150/102/107 120/143/107 +f 151/103/108 149/99/108 119/146/108 121/144/108 +f 116/147/109 146/91/109 148/98/109 118/145/109 +f 149/99/110 147/93/110 117/148/110 119/146/110 +f 114/149/111 164/92/111 146/91/111 116/147/111 +f 147/93/112 165/96/112 115/150/112 117/148/112 +f 114/149/113 181/151/113 177/152/113 164/92/113 +f 177/152/114 182/153/114 115/150/114 165/96/114 +f 110/131/115 162/126/115 68/130/115 112/154/115 +f 68/130/116 163/127/116 111/134/116 113/155/116 +f 112/154/117 68/130/117 178/156/117 183/157/117 +f 178/156/118 68/130/118 113/155/118 184/158/118 +f 177/152/119 181/151/119 183/157/119 178/156/119 +f 184/158/120 182/153/120 177/152/120 178/156/120 +f 135/159/121 137/160/121 176/69/121 174/68/121 +f 176/69/122 137/160/122 136/161/122 175/71/122 +f 133/162/123 135/159/123 174/68/123 172/74/123 +f 175/71/124 136/161/124 134/163/124 173/75/124 +f 131/164/125 133/162/125 172/74/125 170/78/125 +f 173/75/126 134/163/126 132/165/126 171/79/126 +f 166/86/127 187/166/127 185/167/127 168/82/127 +f 186/168/128 188/169/128 167/87/128 169/83/128 +f 131/164/129 170/78/129 168/82/129 185/167/129 +f 169/83/130 171/79/130 132/165/130 186/168/130 +f 144/170/131 190/171/131 189/172/131 187/166/131 +f 189/172/132 190/171/132 145/173/132 188/169/132 +f 185/167/133 187/166/133 189/172/133 69/174/133 +f 189/172/134 188/169/134 186/168/134 69/174/134 +f 130/175/135 131/164/135 185/167/135 69/174/135 +f 186/168/135 132/165/135 130/175/135 69/174/135 +f 142/176/136 193/177/136 191/178/136 144/170/136 +f 192/179/137 194/180/137 143/181/137 145/173/137 +f 140/182/138 195/183/138 193/177/138 142/176/138 +f 194/180/139 196/184/139 141/185/139 143/181/139 +f 139/186/140 197/187/140 195/183/140 140/182/140 +f 196/184/141 198/188/141 139/186/141 141/185/141 +f 138/189/142 71/190/142 197/187/142 139/186/142 +f 198/188/143 71/190/143 138/189/143 139/186/143 +f 190/171/144 144/170/144 191/178/144 70/191/144 +f 192/179/145 145/173/145 190/171/145 70/191/145 +f 70/191/146 191/178/146 206/192/146 208/193/146 +f 207/194/147 192/179/147 70/191/147 208/193/147 +f 71/190/148 199/195/148 200/196/148 197/187/148 +f 201/197/149 199/195/149 71/190/149 198/188/149 +f 197/187/150 200/196/150 202/198/150 195/183/150 +f 203/199/151 201/197/151 198/188/151 196/184/151 +f 195/183/152 202/198/152 204/200/152 193/177/152 +f 205/201/153 203/199/153 196/184/153 194/180/153 +f 193/177/154 204/200/154 206/192/154 191/178/154 +f 207/194/155 205/201/155 194/180/155 192/179/155 +f 199/195/156 204/200/156 202/198/156 200/196/156 +f 203/199/157 205/201/157 199/195/157 201/197/157 +f 199/195/158 208/193/158 206/192/158 204/200/158 +f 207/194/159 208/193/159 199/195/159 205/201/159 +f 139/186/160 140/182/160 164/92/160 177/152/160 +f 165/96/161 141/185/161 139/186/161 177/152/161 +f 140/182/162 142/176/162 211/202/162 164/92/162 +f 212/203/163 143/181/163 141/185/163 165/96/163 +f 142/176/164 144/170/164 213/204/164 211/202/164 +f 214/205/165 145/173/165 143/181/165 212/203/165 +f 144/170/166 187/166/166 166/86/166 213/204/166 +f 167/87/167 188/169/167 145/173/167 214/205/167 +f 81/85/168 209/206/168 213/204/168 166/86/168 +f 214/205/169 210/207/169 82/88/169 167/87/169 +f 209/206/170 215/208/170 211/202/170 213/204/170 +f 212/203/171 216/209/171 210/207/171 214/205/171 +f 79/89/172 164/92/172 211/202/172 215/208/172 +f 212/203/173 165/96/173 80/95/173 216/209/173 +f 131/164/174 130/175/174 72/210/174 222/211/174 +f 72/210/175 130/175/175 132/165/175 223/212/175 +f 133/162/176 131/164/176 222/211/176 220/213/176 +f 223/212/177 132/165/177 134/163/177 221/214/177 +f 135/159/178 133/162/178 220/213/178 218/215/178 +f 221/214/179 134/163/179 136/161/179 219/216/179 +f 137/160/180 135/159/180 218/215/180 217/217/180 +f 219/216/181 136/161/181 137/160/181 217/217/181 +f 217/217/182 218/215/182 229/218/182 231/219/182 +f 230/220/183 219/216/183 217/217/183 231/219/183 +f 218/215/184 220/213/184 227/221/184 229/218/184 +f 228/222/185 221/214/185 219/216/185 230/220/185 +f 220/213/186 222/211/186 225/223/186 227/221/186 +f 226/224/187 223/212/187 221/214/187 228/222/187 +f 222/211/188 72/210/188 224/225/188 225/223/188 +f 224/225/189 72/210/189 223/212/189 226/224/189 +f 224/225/190 231/219/190 229/218/190 225/223/190 +f 230/220/191 231/219/191 224/225/191 226/224/191 +f 225/223/192 229/218/192 227/221/192 +f 228/222/193 230/220/193 226/224/193 +f 183/157/194 181/151/194 234/226/194 232/227/194 +f 235/228/195 182/153/195 184/158/195 233/229/195 +f 112/154/196 183/157/196 232/227/196 254/230/196 +f 233/229/197 184/158/197 113/155/197 255/231/197 +f 110/131/198 112/154/198 254/230/198 256/232/198 +f 255/231/199 113/155/199 111/134/199 257/233/199 +f 181/151/200 114/149/200 252/234/200 234/226/200 +f 253/235/201 115/150/201 182/153/201 235/228/201 +f 114/149/202 116/147/202 250/236/202 252/234/202 +f 251/237/203 117/148/203 115/150/203 253/235/203 +f 116/147/204 118/145/204 248/238/204 250/236/204 +f 249/239/205 119/146/205 117/148/205 251/237/205 +f 118/145/206 120/143/206 246/240/206 248/238/206 +f 247/241/207 121/144/207 119/146/207 249/239/207 +f 120/143/208 122/141/208 244/242/208 246/240/208 +f 245/243/209 123/142/209 121/144/209 247/241/209 +f 122/141/210 124/139/210 242/244/210 244/242/210 +f 243/245/211 125/140/211 123/142/211 245/243/211 +f 124/139/212 126/137/212 240/246/212 242/244/212 +f 241/247/213 127/138/213 125/140/213 243/245/213 +f 126/137/214 179/135/214 236/248/214 240/246/214 +f 237/249/215 180/136/215 127/138/215 241/247/215 +f 179/135/216 128/132/216 238/250/216 236/248/216 +f 239/251/217 129/133/217 180/136/217 237/249/217 +f 128/132/218 110/131/218 256/232/218 238/250/218 +f 257/233/219 111/134/219 129/133/219 239/251/219 +f 238/250/220 256/232/220 258/252/220 276/253/220 +f 259/254/221 257/233/221 239/251/221 277/255/221 +f 236/248/222 238/250/222 276/253/222 278/256/222 +f 277/255/223 239/251/223 237/249/223 279/257/223 +f 240/246/224 236/248/224 278/256/224 274/258/224 +f 279/257/225 237/249/225 241/247/225 275/259/225 +f 242/244/226 240/246/226 274/258/226 272/260/226 +f 275/259/227 241/247/227 243/245/227 273/261/227 +f 244/242/228 242/244/228 272/260/228 270/262/228 +f 273/261/229 243/245/229 245/243/229 271/263/229 +f 246/240/230 244/242/230 270/262/230 268/264/230 +f 271/263/231 245/243/231 247/241/231 269/265/231 +f 248/238/232 246/240/232 268/264/232 266/266/232 +f 269/265/233 247/241/233 249/239/233 267/267/233 +f 250/236/234 248/238/234 266/266/234 264/268/234 +f 267/267/235 249/239/235 251/237/235 265/269/235 +f 252/234/236 250/236/236 264/268/236 262/270/236 +f 265/269/237 251/237/237 253/235/237 263/271/237 +f 234/226/238 252/234/238 262/270/238 280/272/238 +f 263/271/239 253/235/239 235/228/239 281/273/239 +f 256/232/240 254/230/240 260/274/240 258/252/240 +f 261/275/241 255/231/241 257/233/241 259/254/241 +f 254/230/242 232/227/242 282/276/242 260/274/242 +f 283/277/243 233/229/243 255/231/243 261/275/243 +f 232/227/244 234/226/244 280/272/244 282/276/244 +f 281/273/245 235/228/245 233/229/245 283/277/245 +f 67/129/246 108/125/246 284/278/246 73/279/246 +f 285/280/247 109/128/247 67/129/247 73/279/247 +f 108/125/248 106/121/248 286/281/248 284/278/248 +f 287/282/249 107/124/249 109/128/249 285/280/249 +f 106/121/250 104/117/250 288/283/250 286/281/250 +f 289/284/251 105/120/251 107/124/251 287/282/251 +f 104/117/252 102/113/252 290/285/252 288/283/252 +f 291/286/253 103/116/253 105/120/253 289/284/253 +f 102/113/254 100/109/254 292/287/254 290/285/254 +f 293/288/255 101/112/255 103/116/255 291/286/255 +f 100/109/256 98/105/256 294/289/256 292/287/256 +f 295/290/257 99/108/257 101/112/257 293/288/257 +f 98/105/258 96/101/258 296/291/258 294/289/258 +f 297/292/259 97/104/259 99/108/259 295/290/259 +f 96/101/260 94/97/260 298/293/260 296/291/260 +f 299/294/261 95/100/261 97/104/261 297/292/261 +f 94/97/262 92/90/262 300/295/262 298/293/262 +f 301/296/263 93/94/263 95/100/263 299/294/263 +f 308/297/264 309/298/264 328/299/264 338/300/264 +f 329/301/265 309/302/265 308/303/265 339/304/265 +f 307/305/266 308/297/266 338/300/266 336/306/266 +f 339/304/267 308/303/267 307/307/267 337/308/267 +f 306/309/268 307/305/268 336/306/268 340/310/268 +f 337/308/269 307/307/269 306/309/269 341/311/269 +f 89/67/270 91/70/270 306/309/270 340/310/270 +f 306/309/271 91/70/271 90/72/271 341/311/271 +f 87/73/272 89/67/272 340/310/272 334/312/272 +f 341/311/273 90/72/273 88/76/273 335/313/273 +f 85/77/274 87/73/274 334/312/274 330/314/274 +f 335/313/275 88/76/275 86/80/275 331/315/275 +f 83/81/276 85/77/276 330/314/276 332/316/276 +f 331/315/277 86/80/277 84/84/277 333/317/277 +f 330/314/278 336/306/278 338/300/278 332/316/278 +f 339/304/279 337/308/279 331/315/279 333/317/279 +f 330/314/280 334/312/280 340/310/280 336/306/280 +f 341/311/281 335/313/281 331/315/281 337/308/281 +f 326/318/282 332/316/282 338/300/282 328/299/282 +f 339/304/283 333/317/283 327/319/283 329/301/283 +f 81/85/284 83/81/284 332/316/284 326/318/284 +f 333/317/285 84/84/285 82/88/285 327/319/285 +f 209/206/286 342/320/286 344/321/286 215/208/286 +f 345/322/287 343/323/287 210/207/287 216/209/287 +f 81/85/288 326/318/288 342/320/288 209/206/288 +f 343/323/289 327/319/289 82/88/289 210/207/289 +f 79/89/290 215/208/290 344/321/290 346/324/290 +f 345/322/291 216/209/291 80/95/291 347/325/291 +f 79/89/292 346/324/292 300/295/292 92/90/292 +f 301/296/293 347/325/293 80/95/293 93/94/293 +f 77/326/294 324/327/294 352/328/294 304/329/294 +f 353/330/295 325/331/295 77/332/295 304/333/295 +f 304/329/296 352/328/296 350/334/296 78/335/296 +f 351/336/297 353/330/297 304/333/297 78/337/297 +f 78/335/298 350/334/298 348/338/298 305/339/298 +f 349/340/299 351/336/299 78/337/299 305/341/299 +f 305/339/300 348/338/300 328/299/300 309/298/300 +f 329/301/301 349/340/301 305/341/301 309/302/301 +f 326/318/302 328/299/302 348/338/302 342/320/302 +f 349/340/303 329/301/303 327/319/303 343/323/303 +f 296/291/304 298/293/304 318/342/304 310/343/304 +f 319/344/305 299/294/305 297/292/305 311/345/305 +f 76/346/306 316/347/306 324/327/306 77/326/306 +f 325/331/307 317/348/307 76/349/307 77/332/307 +f 302/350/308 358/351/308 356/352/308 303/353/308 +f 357/354/309 359/355/309 302/356/309 303/357/309 +f 303/353/310 356/352/310 354/358/310 75/359/310 +f 355/360/311 357/354/311 303/357/311 75/361/311 +f 75/359/312 354/358/312 316/347/312 76/346/312 +f 317/348/313 355/360/313 75/361/313 76/349/313 +f 292/362/314 294/289/314 362/363/314 364/364/314 +f 363/365/315 295/290/315 293/366/315 365/367/315 +f 364/364/316 362/363/316 368/368/316 366/369/316 +f 369/370/317 363/365/317 365/367/317 367/371/317 +f 366/369/318 368/368/318 370/372/318 372/373/318 +f 371/374/319 369/370/319 367/371/319 373/375/319 +f 372/373/320 370/372/320 376/376/320 374/377/320 +f 377/378/321 371/374/321 373/375/321 375/379/321 +f 314/380/322 378/381/322 374/377/322 376/376/322 +f 375/379/323 379/382/323 315/383/323 377/378/323 +f 316/347/324 354/358/324 374/377/324 378/381/324 +f 375/379/325 355/360/325 317/348/325 379/382/325 +f 354/358/326 356/352/326 372/373/326 374/377/326 +f 373/375/327 357/354/327 355/360/327 375/379/327 +f 356/352/328 358/351/328 366/369/328 372/373/328 +f 367/371/329 359/355/329 357/354/329 373/375/329 +f 358/351/330 360/384/330 364/364/330 366/369/330 +f 365/367/331 361/385/331 359/355/331 367/371/331 +f 290/386/332 292/362/332 364/364/332 360/384/332 +f 365/367/333 293/366/333 291/387/333 361/385/333 +f 74/388/334 360/384/334 358/351/334 302/350/334 +f 359/355/335 361/385/335 74/389/335 302/356/335 +f 284/390/336 286/391/336 288/392/336 290/386/336 +f 289/393/337 287/394/337 285/395/337 291/387/337 +f 284/390/338 290/386/338 360/384/338 74/388/338 +f 361/385/339 291/387/339 285/395/339 74/389/339 +f 73/396/340 284/390/340 74/388/340 +f 74/389/341 285/395/341 73/397/341 +f 294/289/342 296/291/342 310/343/342 362/363/342 +f 311/345/343 297/292/343 295/290/343 363/365/343 +f 310/343/344 312/398/344 368/368/344 362/363/344 +f 369/370/345 313/399/345 311/345/345 363/365/345 +f 312/398/346 382/400/346 370/372/346 368/368/346 +f 371/374/347 383/401/347 313/399/347 369/370/347 +f 314/380/348 376/376/348 370/372/348 382/400/348 +f 371/374/349 377/378/349 315/383/349 383/401/349 +f 348/338/350 350/334/350 386/402/350 384/403/350 +f 387/404/351 351/336/351 349/340/351 385/405/351 +f 318/342/352 384/403/352 386/402/352 320/406/352 +f 387/404/353 385/405/353 319/344/353 321/407/353 +f 298/293/354 300/295/354 384/403/354 318/342/354 +f 385/405/355 301/296/355 299/294/355 319/344/355 +f 300/295/356 344/321/356 342/320/356 384/403/356 +f 343/323/357 345/322/357 301/296/357 385/405/357 +f 342/320/358 348/338/358 384/403/358 +f 385/405/359 349/340/359 343/323/359 +f 300/295/360 346/324/360 344/321/360 +f 345/322/361 347/325/361 301/296/361 +f 314/380/362 322/408/362 380/409/362 378/381/362 +f 381/410/363 323/411/363 315/383/363 379/382/363 +f 316/347/364 378/381/364 380/409/364 324/327/364 +f 381/410/365 379/382/365 317/348/365 325/331/365 +f 320/406/366 386/402/366 380/409/366 322/408/366 +f 381/410/367 387/404/367 321/407/367 323/411/367 +f 350/334/368 352/328/368 380/409/368 386/402/368 +f 381/410/369 353/330/369 351/336/369 387/404/369 +f 324/327/370 380/409/370 352/328/370 +f 353/330/371 381/410/371 325/331/371 +f 400/412/372 388/413/372 414/414/372 402/415/372 +f 415/416/373 389/417/373 401/418/373 403/419/373 +f 400/412/374 402/415/374 404/420/374 398/421/374 +f 405/422/375 403/419/375 401/418/375 399/423/375 +f 398/421/376 404/420/376 406/424/376 396/425/376 +f 407/426/377 405/422/377 399/423/377 397/427/377 +f 396/425/378 406/424/378 408/428/378 394/429/378 +f 409/430/379 407/426/379 397/427/379 395/431/379 +f 394/429/380 408/428/380 410/432/380 392/433/380 +f 411/434/381 409/430/381 395/431/381 393/435/381 +f 392/433/382 410/432/382 412/436/382 390/437/382 +f 413/438/383 411/434/383 393/435/383 391/439/383 +f 410/432/384 420/440/384 418/441/384 412/436/384 +f 419/442/385 421/443/385 411/434/385 413/438/385 +f 408/428/386 422/444/386 420/440/386 410/432/386 +f 421/443/387 423/445/387 409/430/387 411/434/387 +f 406/424/388 424/446/388 422/444/388 408/428/388 +f 423/445/389 425/447/389 407/426/389 409/430/389 +f 404/420/390 426/448/390 424/446/390 406/424/390 +f 425/447/391 427/449/391 405/422/391 407/426/391 +f 402/415/392 428/450/392 426/448/392 404/420/392 +f 427/449/393 429/451/393 403/419/393 405/422/393 +f 402/415/394 414/414/394 416/452/394 428/450/394 +f 417/453/395 415/416/395 403/419/395 429/451/395 +f 318/342/396 320/406/396 444/454/396 442/455/396 +f 445/456/397 321/407/397 319/344/397 443/457/397 +f 320/458/398 390/437/398 412/436/398 444/459/398 +f 413/438/399 391/439/399 321/460/399 445/461/399 +f 310/343/400 318/342/400 442/455/400 312/398/400 +f 443/457/401 319/344/401 311/345/401 313/399/401 +f 382/462/402 430/463/402 414/414/402 388/413/402 +f 415/416/403 431/464/403 383/465/403 389/417/403 +f 412/436/404 418/441/404 440/466/404 444/459/404 +f 441/467/405 419/442/405 413/438/405 445/461/405 +f 438/468/406 446/469/406 444/459/406 440/466/406 +f 445/461/407 447/470/407 439/471/407 441/467/407 +f 434/472/408 446/469/408 438/468/408 436/473/408 +f 439/471/409 447/470/409 435/474/409 437/475/409 +f 432/476/410 448/477/410 446/469/410 434/472/410 +f 447/470/411 449/478/411 433/479/411 435/474/411 +f 430/463/412 448/477/412 432/476/412 450/480/412 +f 433/479/413 449/478/413 431/464/413 451/481/413 +f 414/414/414 430/463/414 450/480/414 416/452/414 +f 451/481/415 431/464/415 415/416/415 417/453/415 +f 312/398/416 448/482/416 430/483/416 382/400/416 +f 431/484/417 449/485/417 313/399/417 383/401/417 +f 312/398/418 442/455/418 446/486/418 448/482/418 +f 447/487/419 443/457/419 313/399/419 449/485/419 +f 442/455/420 444/454/420 446/486/420 +f 447/487/421 445/456/421 443/457/421 +f 416/452/422 450/480/422 452/488/422 476/489/422 +f 453/490/423 451/481/423 417/453/423 477/491/423 +f 450/480/424 432/476/424 462/492/424 452/488/424 +f 463/493/425 433/479/425 451/481/425 453/490/425 +f 432/476/426 434/472/426 460/494/426 462/492/426 +f 461/495/427 435/474/427 433/479/427 463/493/427 +f 434/472/428 436/473/428 458/496/428 460/494/428 +f 459/497/429 437/475/429 435/474/429 461/495/429 +f 436/473/430 438/468/430 456/498/430 458/496/430 +f 457/499/431 439/471/431 437/475/431 459/497/431 +f 438/468/432 440/466/432 454/500/432 456/498/432 +f 455/501/433 441/467/433 439/471/433 457/499/433 +f 440/466/434 418/441/434 474/502/434 454/500/434 +f 475/503/435 419/442/435 441/467/435 455/501/435 +f 428/450/436 416/452/436 476/489/436 464/504/436 +f 477/491/437 417/453/437 429/451/437 465/505/437 +f 426/448/438 428/450/438 464/504/438 466/506/438 +f 465/505/439 429/451/439 427/449/439 467/507/439 +f 424/446/440 426/448/440 466/506/440 468/508/440 +f 467/507/441 427/449/441 425/447/441 469/509/441 +f 422/444/442 424/446/442 468/508/442 470/510/442 +f 469/509/443 425/447/443 423/445/443 471/511/443 +f 420/440/444 422/444/444 470/510/444 472/512/444 +f 471/511/445 423/445/445 421/443/445 473/513/445 +f 418/441/446 420/440/446 472/512/446 474/502/446 +f 473/513/447 421/443/447 419/442/447 475/503/447 +f 458/496/448 456/498/448 480/514/448 478/515/448 +f 481/516/449 457/499/449 459/497/449 479/517/449 +f 478/515/450 480/514/450 482/518/450 484/519/450 +f 483/520/451 481/516/451 479/517/451 485/521/451 +f 484/519/452 482/518/452 488/522/452 486/523/452 +f 489/524/453 483/520/453 485/521/453 487/525/453 +f 486/523/454 488/522/454 490/526/454 492/527/454 +f 491/528/455 489/524/455 487/525/455 493/529/455 +f 464/504/456 476/489/456 486/523/456 492/527/456 +f 487/525/457 477/491/457 465/505/457 493/529/457 +f 452/488/458 484/519/458 486/523/458 476/489/458 +f 487/525/459 485/521/459 453/490/459 477/491/459 +f 452/488/460 462/492/460 478/515/460 484/519/460 +f 479/517/461 463/493/461 453/490/461 485/521/461 +f 458/496/462 478/515/462 462/492/462 460/494/462 +f 463/493/463 479/517/463 459/497/463 461/495/463 +f 454/500/464 474/502/464 480/514/464 456/498/464 +f 481/516/465 475/503/465 455/501/465 457/499/465 +f 472/512/466 482/518/466 480/514/466 474/502/466 +f 481/516/467 483/520/467 473/513/467 475/503/467 +f 470/510/468 488/522/468 482/518/468 472/512/468 +f 483/520/469 489/524/469 471/511/469 473/513/469 +f 468/508/470 490/526/470 488/522/470 470/510/470 +f 489/524/471 491/528/471 469/509/471 471/511/471 +f 466/506/472 492/527/472 490/526/472 468/508/472 +f 491/528/473 493/529/473 467/507/473 469/509/473 +f 464/504/474 492/527/474 466/506/474 +f 467/507/475 493/529/475 465/505/475 +f 392/433/476 390/437/476 504/530/476 502/531/476 +f 505/532/477 391/439/477 393/435/477 503/533/477 +f 394/429/478 392/433/478 502/531/478 500/534/478 +f 503/533/479 393/435/479 395/431/479 501/535/479 +f 396/425/480 394/429/480 500/534/480 498/536/480 +f 501/535/481 395/431/481 397/427/481 499/537/481 +f 398/538/482 396/425/482 498/536/482 496/539/482 +f 499/537/483 397/427/483 399/540/483 497/541/483 +f 400/542/484 398/538/484 496/539/484 494/543/484 +f 497/541/485 399/540/485 401/544/485 495/545/485 +f 388/546/486 400/542/486 494/543/486 506/547/486 +f 495/545/487 401/544/487 389/548/487 507/549/487 +f 494/543/488 502/531/488 504/530/488 506/547/488 +f 505/532/489 503/533/489 495/545/489 507/549/489 +f 494/543/490 496/539/490 500/534/490 502/531/490 +f 501/535/491 497/541/491 495/545/491 503/533/491 +f 496/539/492 498/536/492 500/534/492 +f 501/535/493 499/537/493 497/541/493 +f 314/550/494 382/551/494 388/546/494 506/547/494 +f 389/548/495 383/552/495 315/553/495 507/549/495 +f 314/550/496 506/547/496 504/530/496 322/554/496 +f 505/532/497 507/549/497 315/553/497 323/555/497 +f 320/458/498 322/554/498 504/530/498 390/437/498 +f 505/532/499 323/555/499 321/460/499 391/439/499 diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/index.html b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/index.html new file mode 100644 index 0000000000..581d6789f8 --- /dev/null +++ b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/index.html @@ -0,0 +1 @@ + diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/index.ts b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/index.ts new file mode 100644 index 0000000000..ef46927b29 --- /dev/null +++ b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/index.ts @@ -0,0 +1,482 @@ +import tgpu, { d, std } from 'typegpu'; +import { Camera, setupOrbitCamera } from '../../common/setup-orbit-camera.ts'; +import { defineControls } from '../../common/defineControls.ts'; +import { loadModel } from './load-model.ts'; +import { createSplitComparison } from './split-comparison.ts'; +import { + DEFAULT_MATERIAL, + INITIAL_PARAMS, + MATERIAL_IDS, + TriplanarParams, + VertexOutput, + VIEW_MODES, + modelVertexLayout, + type MaterialId, +} from './schemas.ts'; + +const MODEL_PATH = '/TypeGPU/assets/triplanar-mapping/suzanne.obj'; +const MATERIAL_PATH = '/TypeGPU/assets/pom'; +const MATERIAL_SIZE = [1024, 1024] as const; +const MATERIAL_MIP_LEVELS = 11; + +const root = await tgpu.init(); +const canvas = document.querySelector('canvas') as HTMLCanvasElement; +const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); + +const materialLayout = tgpu.bindGroupLayout({ + albedo: { texture: d.texture2d() }, + normal: { texture: d.texture2d() }, + ao: { texture: d.texture2d() }, + roughness: { texture: d.texture2d() }, + metallic: { texture: d.texture2d() }, + sampler: { sampler: 'filtering' }, +}); + +function createMaterialTexture(srgb = false) { + return root + .createTexture({ + size: MATERIAL_SIZE, + format: 'rgba8unorm', + mipLevelCount: MATERIAL_MIP_LEVELS, + ...(srgb ? { viewFormats: ['rgba8unorm-srgb'] } : {}), + }) + .$usage('sampled', 'render'); +} + +async function loadImage(src: string) { + const response = await fetch(src); + if (!response.ok) { + throw new Error(`Failed to load image: ${src}`); + } + + return createImageBitmap(await response.blob()); +} + +type MaterialImages = readonly [ImageBitmap, ImageBitmap, ImageBitmap, ImageBitmap, ImageBitmap]; + +function loadMaterialImages(material: MaterialId): Promise { + const path = `${MATERIAL_PATH}/${material}`; + return Promise.all([ + loadImage(`${path}/albedo.png`), + loadImage(`${path}/normal.png`), + loadImage(`${path}/ao.png`), + loadImage(`${path}/roughness.png`), + loadImage(`${path}/metallic.png`), + ]); +} + +function closeImages(images: MaterialImages) { + for (const image of images) { + image.close(); + } +} + +const albedoTexture = createMaterialTexture(true); +const normalTexture = createMaterialTexture(); +const aoTexture = createMaterialTexture(); +const roughnessTexture = createMaterialTexture(); +const metallicTexture = createMaterialTexture(); + +function applyMaterialImages(images: MaterialImages) { + albedoTexture.write(images[0]); + normalTexture.write(images[1]); + aoTexture.write(images[2]); + roughnessTexture.write(images[3]); + metallicTexture.write(images[4]); + + albedoTexture.generateMipmaps(); + normalTexture.generateMipmaps(); + aoTexture.generateMipmaps(); + roughnessTexture.generateMipmaps(); + metallicTexture.generateMipmaps(); + closeImages(images); +} + +let disposed = false; +let materialLoadRequestId = 0; +async function setMaterial(material: MaterialId) { + const requestId = ++materialLoadRequestId; + const images = await loadMaterialImages(material); + + if (disposed || requestId !== materialLoadRequestId) { + closeImages(images); + return; + } + + applyMaterialImages(images); +} + +const model = await loadModel(root, MODEL_PATH); +await setMaterial(DEFAULT_MATERIAL); + +const sampler = root.createSampler({ + addressModeU: 'repeat', + addressModeV: 'repeat', + magFilter: 'linear', + minFilter: 'linear', + mipmapFilter: 'linear', + maxAnisotropy: 4, +}); + +const materialBindGroup = root.createBindGroup(materialLayout, { + albedo: albedoTexture.createView(d.texture2d(), { format: 'rgba8unorm-srgb' }), + normal: normalTexture.createView(d.texture2d()), + ao: aoTexture.createView(d.texture2d()), + roughness: roughnessTexture.createView(d.texture2d()), + metallic: metallicTexture.createView(d.texture2d()), + sampler, +}); + +const cameraUniform = root.createUniform(Camera); +const paramsUniform = root.createUniform(TriplanarParams, INITIAL_PARAMS); + +const { cleanupCamera } = setupOrbitCamera( + canvas, + { + initPos: d.vec4f(0, 1, -5, 1), + target: d.vec4f(0, 0, 0, 1), + minZoom: 1.5, + maxZoom: 8, + }, + (updates) => cameraUniform.patch(updates), +); + +const splitComparison = createSplitComparison(canvas, { + leftLabel: 'Triplanar Mapping', + rightLabel: 'Mesh UVs', + onChange(ratio) { + paramsUniform.patch({ splitX: canvas.width * ratio }); + }, +}); + +function triplanarWeights(n: d.v3f, sharpness: number) { + 'use gpu'; + const w = std.pow(std.abs(n), d.vec3f(sharpness)); + return w / std.max(w.x + w.y + w.z, 0.0001); +} + +function axisSign(v: number) { + 'use gpu'; + return std.select(d.f32(-1), d.f32(1), v >= 0); +} + +function sampleAlbedo(uv: d.v2f) { + 'use gpu'; + return std.textureSample(materialLayout.$.albedo, materialLayout.$.sampler, uv).rgb; +} + +function sampleAo(uv: d.v2f) { + 'use gpu'; + return std.textureSample(materialLayout.$.ao, materialLayout.$.sampler, uv).r; +} + +function sampleRoughness(uv: d.v2f) { + 'use gpu'; + return std.textureSample(materialLayout.$.roughness, materialLayout.$.sampler, uv).r; +} + +function sampleMetallic(uv: d.v2f) { + 'use gpu'; + return std.textureSample(materialLayout.$.metallic, materialLayout.$.sampler, uv).r; +} + +function sampleNormal(uv: d.v2f) { + 'use gpu'; + const decoded = + std.textureSample(materialLayout.$.normal, materialLayout.$.sampler, uv).rgb * 2 - 1; + return std.normalize(d.vec3f(decoded.x, -decoded.y, decoded.z)); +} + +function triplanarNormal( + n: d.v3f, + weights: d.v3f, + uvX: d.v2f, + uvY: d.v2f, + uvZ: d.v2f, + ratio: number, +) { + 'use gpu'; + const tx = sampleNormal(uvX); + const ty = sampleNormal(uvY); + const tz = sampleNormal(uvZ); + + const baseX = d.vec3f(axisSign(n.x), 0, 0); + const baseY = d.vec3f(0, axisSign(n.y), 0); + const baseZ = d.vec3f(0, 0, axisSign(n.z)); + + const nx = std.normalize(d.vec3f(tx.z * baseX.x, tx.y, tx.x)); + const ny = std.normalize(d.vec3f(ty.x, ty.z * baseY.y, ty.y)); + const nz = std.normalize(d.vec3f(tz.x, tz.y, tz.z * baseZ.z)); + + const detail = (nx - baseX) * weights.x + (ny - baseY) * weights.y + (nz - baseZ) * weights.z; + return std.normalize(std.mix(n, std.normalize(n + detail), ratio)); +} + +function meshUvNormal(uv: d.v2f, worldNormal: d.v3f, worldTangent: d.v4f, ratio: number) { + 'use gpu'; + const n = std.normalize(worldNormal); + const t = std.normalize(worldTangent.xyz - n * std.dot(n, worldTangent.xyz)); + const b = std.normalize(std.cross(n, t) * worldTangent.w); + const mapped = sampleNormal(uv); + const normal = std.normalize(t * mapped.x + b * mapped.y + n * mapped.z); + + return std.normalize(std.mix(n, normal, ratio)); +} + +function toDisplayColor(linear: d.v3f) { + 'use gpu'; + return std.pow(std.max(linear, d.vec3f(0)), d.vec3f(1 / 2.2)); +} + +function shade( + albedo: d.v3f, + normal: d.v3f, + ao: number, + roughness: number, + metallic: number, + worldPos: d.v3f, + cameraPos: d.v3f, + lightDir: d.v3f, +) { + 'use gpu'; + const L = std.normalize(lightDir); + const V = std.normalize(cameraPos - worldPos); + const H = std.normalize(L + V); + const NdotL = std.max(std.dot(normal, L), 0); + const NdotH = std.max(std.dot(normal, H), 0); + + const ambient = albedo * (0.08 + ao * 0.22); + const diffuse = albedo * (1 - metallic) * NdotL * 0.85; + const specularPower = std.mix(96, 8, roughness); + const specularColor = std.mix(d.vec3f(0.04), albedo, metallic); + const specular = specularColor * std.pow(NdotH, specularPower) * (1 - roughness) * 0.6; + + return ambient + diffuse + specular; +} + +const vertexShader = tgpu.vertexFn({ + in: { position: d.vec3f, normal: d.vec3f, uv: d.vec2f, tangent: d.vec4f }, + out: VertexOutput, +})((input) => { + 'use gpu'; + const worldPosition = d.vec4f(input.position, 1); + const camera = cameraUniform.$; + + return { + canvasPosition: camera.projection * camera.view * worldPosition, + worldPos: input.position, + worldNormal: std.normalize(input.normal), + worldTangent: d.vec4f(std.normalize(input.tangent.xyz), input.tangent.w), + uv: input.uv, + }; +}); + +const fragmentShader = tgpu.fragmentFn({ + in: VertexOutput, + out: d.vec4f, +})((input) => { + 'use gpu'; + const params = paramsUniform.$; + const meshNormal = std.normalize(input.worldNormal); + const weights = triplanarWeights(meshNormal, params.sharpness); + + const uvX = + d.vec2f(input.worldPos.z * axisSign(meshNormal.x), input.worldPos.y) * params.triplanarScale; + const uvY = + d.vec2f(input.worldPos.x * axisSign(meshNormal.y), input.worldPos.z) * params.triplanarScale; + const uvZ = + d.vec2f(input.worldPos.x * axisSign(meshNormal.z), input.worldPos.y) * params.triplanarScale; + + const albedoX = sampleAlbedo(uvX); + const albedoY = sampleAlbedo(uvY); + const albedoZ = sampleAlbedo(uvZ); + const triAlbedo = albedoX * weights.x + albedoY * weights.y + albedoZ * weights.z; + + const aoX = sampleAo(uvX); + const aoY = sampleAo(uvY); + const aoZ = sampleAo(uvZ); + const triAo = aoX * weights.x + aoY * weights.y + aoZ * weights.z; + const triRoughness = + sampleRoughness(uvX) * weights.x + + sampleRoughness(uvY) * weights.y + + sampleRoughness(uvZ) * weights.z; + const triMetallic = + sampleMetallic(uvX) * weights.x + + sampleMetallic(uvY) * weights.y + + sampleMetallic(uvZ) * weights.z; + + const triNormal = triplanarNormal(meshNormal, weights, uvX, uvY, uvZ, params.materialNormalRatio); + const meshUv = d.vec2f(input.uv.x, 1 - input.uv.y) * params.uvScale; + const meshAlbedo = sampleAlbedo(meshUv); + const meshAo = sampleAo(meshUv); + const meshRoughness = sampleRoughness(meshUv); + const meshMetallic = sampleMetallic(meshUv); + const meshMappedNormal = meshUvNormal( + meshUv, + meshNormal, + input.worldTangent, + params.materialNormalRatio, + ); + + let albedo = d.vec3f(triAlbedo); + let normal = d.vec3f(triNormal); + let ao = triAo; + let roughness = triRoughness; + let metallic = triMetallic; + + const showMeshUvs = input.canvasPosition.x > params.splitX; + if (showMeshUvs) { + albedo = d.vec3f(meshAlbedo); + normal = d.vec3f(meshMappedNormal); + ao = meshAo; + roughness = meshRoughness; + metallic = meshMetallic; + } + + if (params.debugMode === 1) { + return d.vec4f(toDisplayColor(albedo), 1); + } + if (params.debugMode === 2) { + return d.vec4f(weights, 1); + } + if (params.debugMode === 3) { + return d.vec4f(toDisplayColor(albedoX), 1); + } + if (params.debugMode === 4) { + return d.vec4f(toDisplayColor(albedoY), 1); + } + if (params.debugMode === 5) { + return d.vec4f(toDisplayColor(albedoZ), 1); + } + if (params.debugMode === 6) { + return d.vec4f(normal * 0.5 + 0.5, 1); + } + + const lit = shade( + albedo, + normal, + ao, + roughness, + metallic, + input.worldPos, + cameraUniform.$.position.xyz, + params.lightDir, + ); + return d.vec4f(toDisplayColor(lit), 1); +}); + +const pipeline = root + .createRenderPipeline({ + attribs: modelVertexLayout.attrib, + vertex: vertexShader, + fragment: fragmentShader, + depthStencil: { + format: 'depth32float', + depthWriteEnabled: true, + depthCompare: 'less', + }, + }) + .with(modelVertexLayout, model.vertexBuffer) + .with(materialBindGroup); + +function createDepthTexture() { + return root + .createTexture({ + size: [canvas.width, canvas.height], + format: 'depth32float', + }) + .$usage('render'); +} + +let depthTexture = createDepthTexture(); + +let frameId: number; +function frame() { + pipeline + .withColorAttachment({ view: context }) + .withDepthStencilAttachment({ + view: depthTexture, + depthClearValue: 1, + depthLoadOp: 'clear', + depthStoreOp: 'store', + }) + .draw(model.vertexCount); + + frameId = requestAnimationFrame(frame); +} +frameId = requestAnimationFrame(frame); + +// #region Example controls and cleanup + +export const controls = defineControls({ + material: { + initial: DEFAULT_MATERIAL, + options: MATERIAL_IDS, + onSelectChange(material) { + void setMaterial(material).catch((error) => { + console.error(`Failed to load triplanar material "${material}"`, error); + }); + }, + }, + view: { + initial: 'lit', + options: VIEW_MODES, + onSelectChange(mode) { + paramsUniform.patch({ debugMode: VIEW_MODES.indexOf(mode) }); + }, + }, + 'triplanar scale': { + initial: INITIAL_PARAMS.triplanarScale, + min: 0.5, + max: 10, + step: 0.1, + onSliderChange(triplanarScale) { + paramsUniform.patch({ triplanarScale }); + }, + }, + 'UV scale': { + initial: INITIAL_PARAMS.uvScale, + min: 0.25, + max: 6, + step: 0.05, + onSliderChange(uvScale) { + paramsUniform.patch({ uvScale }); + }, + }, + 'blend sharpness': { + initial: INITIAL_PARAMS.sharpness, + min: 1, + max: 10, + step: 0.1, + onSliderChange(sharpness) { + paramsUniform.patch({ sharpness }); + }, + }, + 'material normal ratio': { + initial: INITIAL_PARAMS.materialNormalRatio, + min: 0, + max: 1, + step: 0.01, + onSliderChange(materialNormalRatio) { + paramsUniform.patch({ materialNormalRatio }); + }, + }, +}); + +const resizeObserver = new ResizeObserver(() => { + depthTexture.destroy(); + depthTexture = createDepthTexture(); + splitComparison.sync(); +}); +resizeObserver.observe(canvas); + +export function onCleanup() { + disposed = true; + cancelAnimationFrame(frameId); + cleanupCamera(); + resizeObserver.disconnect(); + splitComparison.destroy(); + root.destroy(); +} + +// #endregion diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/load-model.ts b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/load-model.ts new file mode 100644 index 0000000000..3c47cd84d8 --- /dev/null +++ b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/load-model.ts @@ -0,0 +1,138 @@ +import { load } from '@loaders.gl/core'; +import { OBJLoader } from '@loaders.gl/obj'; +import { common, type TgpuRoot } from 'typegpu'; +import { modelVertexLayout } from './schemas.ts'; + +type MeshAttribute = { + value: Float32Array; +}; + +type LoadedObj = { + attributes: { + POSITION?: MeshAttribute; + NORMAL?: MeshAttribute; + TEXCOORD_0?: MeshAttribute; + }; +}; + +function computeTangents(position: Float32Array, normal: Float32Array, uv: Float32Array) { + const vertexCount = position.length / 3; + const tangent = new Float32Array(vertexCount * 4); + const tangentSum = new Float32Array(vertexCount * 3); + const bitangentSum = new Float32Array(vertexCount * 3); + + for (let i = 0; i + 2 < vertexCount; i += 3) { + const p0 = i * 3; + const p1 = p0 + 3; + const p2 = p0 + 6; + + const e1x = position[p1] - position[p0]; + const e1y = position[p1 + 1] - position[p0 + 1]; + const e1z = position[p1 + 2] - position[p0 + 2]; + const e2x = position[p2] - position[p0]; + const e2y = position[p2 + 1] - position[p0 + 1]; + const e2z = position[p2 + 2] - position[p0 + 2]; + + const uv0 = i * 2; + const uv1 = uv0 + 2; + const uv2 = uv0 + 4; + const du1 = uv[uv1] - uv[uv0]; + const dv1 = uv[uv0 + 1] - uv[uv1 + 1]; + const du2 = uv[uv2] - uv[uv0]; + const dv2 = uv[uv0 + 1] - uv[uv2 + 1]; + const det = du1 * dv2 - du2 * dv1; + + if (Math.abs(det) < 1e-8) { + continue; + } + + const r = 1 / det; + const tx = (e1x * dv2 - e2x * dv1) * r; + const ty = (e1y * dv2 - e2y * dv1) * r; + const tz = (e1z * dv2 - e2z * dv1) * r; + const bx = (e2x * du1 - e1x * du2) * r; + const by = (e2y * du1 - e1y * du2) * r; + const bz = (e2z * du1 - e1z * du2) * r; + + for (let j = p0; j <= p2; j += 3) { + tangentSum[j] += tx; + tangentSum[j + 1] += ty; + tangentSum[j + 2] += tz; + bitangentSum[j] += bx; + bitangentSum[j + 1] += by; + bitangentSum[j + 2] += bz; + } + } + + for (let i = 0; i < vertexCount; i++) { + const v = i * 3; + const nLen = Math.hypot(normal[v], normal[v + 1], normal[v + 2]) || 1; + const nx = normal[v] / nLen; + const ny = normal[v + 1] / nLen; + const nz = normal[v + 2] / nLen; + + const tDotN = tangentSum[v] * nx + tangentSum[v + 1] * ny + tangentSum[v + 2] * nz; + let tx = tangentSum[v] - nx * tDotN; + let ty = tangentSum[v + 1] - ny * tDotN; + let tz = tangentSum[v + 2] - nz * tDotN; + const tLen = Math.hypot(tx, ty, tz); + + if (tLen > 1e-8) { + tx /= tLen; + ty /= tLen; + tz /= tLen; + } else { + tx = Math.abs(ny) < 0.999 ? nz : 0; + ty = 0; + tz = Math.abs(ny) < 0.999 ? -nx : 1; + const fallbackLen = Math.hypot(tx, ty, tz) || 1; + tx /= fallbackLen; + ty /= fallbackLen; + tz /= fallbackLen; + } + + const cx = ny * tz - nz * ty; + const cy = nz * tx - nx * tz; + const cz = nx * ty - ny * tx; + const handedness = + cx * bitangentSum[v] + cy * bitangentSum[v + 1] + cz * bitangentSum[v + 2] < 0 ? -1 : 1; + + const out = i * 4; + tangent[out] = tx; + tangent[out + 1] = ty; + tangent[out + 2] = tz; + tangent[out + 3] = handedness; + } + + return tangent; +} + +export async function loadModel(root: TgpuRoot, modelPath: string) { + const mesh = (await load(modelPath, OBJLoader)) as LoadedObj; + const position = mesh.attributes.POSITION?.value; + const normal = mesh.attributes.NORMAL?.value; + + if (!position || !normal) { + throw new Error(`Model "${modelPath}" must contain positions and normals.`); + } + + if (position.length !== normal.length) { + throw new Error(`Model "${modelPath}" has mismatched position and normal counts.`); + } + + const vertexCount = position.length / 3; + const uv = mesh.attributes.TEXCOORD_0?.value ?? new Float32Array(vertexCount * 2); + const tangent = computeTangents(position, normal, uv); + + const vertexBuffer = root + .createBuffer(modelVertexLayout.schemaForCount(vertexCount)) + .$usage('vertex') + .$name(`vertices for ${modelPath}`); + + common.writeSoA(vertexBuffer, { position, normal, uv, tangent }); + + return { + vertexBuffer, + vertexCount, + }; +} diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/meta.json b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/meta.json new file mode 100644 index 0000000000..ad27584fbb --- /dev/null +++ b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/meta.json @@ -0,0 +1,6 @@ +{ + "title": "Triplanar Mapping", + "category": "rendering", + "tags": ["3d", "textures", "rasterization", "lighting"], + "coolFactor": 7 +} diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/schemas.ts b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/schemas.ts new file mode 100644 index 0000000000..a9cbcd6f1a --- /dev/null +++ b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/schemas.ts @@ -0,0 +1,61 @@ +import tgpu, { d } from 'typegpu'; + +export const ModelVertex = d.struct({ + position: d.vec3f, + normal: d.vec3f, + uv: d.vec2f, + tangent: d.vec4f, +}); + +export const modelVertexLayout = tgpu.vertexLayout(d.arrayOf(ModelVertex)); + +export const VertexOutput = { + canvasPosition: d.builtin.position, + worldPos: d.vec3f, + worldNormal: d.vec3f, + worldTangent: d.vec4f, + uv: d.vec2f, +} as const; + +export const TriplanarParams = d.struct({ + triplanarScale: d.f32, + uvScale: d.f32, + sharpness: d.f32, + materialNormalRatio: d.f32, + splitX: d.f32, + debugMode: d.u32, + lightDir: d.vec3f, +}); + +export const VIEW_MODES = [ + 'lit', + 'albedo', + 'blend weights', + 'X projection', + 'Y projection', + 'Z projection', + 'normal', +] as const; + +export const MATERIAL_IDS = [ + 'rocks', + 'bricks', + 'beach', + 'aerial-rocks', + 'acoustic-foam', + 'manhole-cover', +] as const; + +export type MaterialId = (typeof MATERIAL_IDS)[number]; + +export const DEFAULT_MATERIAL: MaterialId = 'rocks'; + +export const INITIAL_PARAMS: d.InferInput = { + triplanarScale: 1.3, + uvScale: 5, + sharpness: 8, + materialNormalRatio: 0.7, + splitX: 0.5, + debugMode: 0, + lightDir: [-0.4, 0.2, -0.35], +}; diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/split-comparison.ts b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/split-comparison.ts new file mode 100644 index 0000000000..b6c4c1780b --- /dev/null +++ b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/split-comparison.ts @@ -0,0 +1,191 @@ +type SplitComparisonOptions = { + leftLabel: string; + rightLabel: string; + initialRatio?: number; + onChange: (ratio: number) => void; +}; + +export type SplitComparison = { + readonly ratio: number; + sync(): void; + destroy(): void; +}; + +const MIN_RATIO = 0.02; +const MAX_RATIO = 0.98; +const LABEL_MARGIN = 28; + +const clampRatio = (ratio: number) => Math.min(MAX_RATIO, Math.max(MIN_RATIO, ratio)); + +function withStyle(element: T, cssText: string) { + element.style.cssText = cssText; + return element; +} + +function makePill(text: string, side: 'left' | 'right') { + const pill = withStyle( + document.createElement('span'), + ` + position: absolute; + top: 12px; + box-sizing: border-box; + max-width: 0; + overflow: hidden; + padding: 6px 12px; + border: 2px solid rgba(225, 220, 244, 0.92); + border-radius: 100px; + background: rgba(255, 255, 255, 0.88); + color: rgb(30, 27, 42); + box-shadow: 0 4px 14px rgba(30, 27, 42, 0.08); + backdrop-filter: blur(10px); + font: 500 13px/1.2 ui-sans-serif, system-ui, sans-serif; + letter-spacing: 0; + text-overflow: ellipsis; + white-space: nowrap; + transform: translateX(${side === 'left' ? 'calc(-100% - 10px)' : '10px'}); + `, + ); + pill.textContent = text; + return pill; +} + +export function createSplitComparison( + canvas: HTMLCanvasElement, + { leftLabel, rightLabel, initialRatio = 0.5, onChange }: SplitComparisonOptions, +): SplitComparison { + const host = canvas.parentElement; + if (!host) { + throw new Error('Split comparison requires the canvas to have a parent element.'); + } + + let ratio = clampRatio(initialRatio); + let pointerId: number | undefined; + + const handle = withStyle( + document.createElement('div'), + ` + position: absolute; + inset: 0 auto 0 50%; + z-index: 4; + display: flex; + width: 16px; + cursor: ew-resize; + justify-content: center; + opacity: 0.68; + outline: none; + touch-action: none; + transform: translateX(-50%); + `, + ); + const labels = withStyle( + document.createElement('div'), + 'position:absolute;inset:0;z-index:5;pointer-events:none;', + ); + const line = withStyle( + document.createElement('div'), + ` + width: 1px; + background: rgba(30, 27, 42, 0.22); + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5); + pointer-events: none; + `, + ); + const grip = withStyle( + document.createElement('div'), + ` + position: absolute; + top: 48px; + width: 6px; + height: 28px; + border: 1px solid rgba(126, 115, 169, 0.46); + border-radius: 100px; + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 4px 12px rgba(30, 27, 42, 0.14); + pointer-events: none; + `, + ); + const leftPill = makePill(leftLabel, 'left'); + const rightPill = makePill(rightLabel, 'right'); + + handle.dataset.triplanarSplitHandle = 'true'; + handle.tabIndex = 0; + handle.setAttribute('role', 'slider'); + handle.setAttribute('aria-label', 'Compare triplanar mapping and mesh UVs'); + handle.setAttribute('aria-valuemin', `${MIN_RATIO * 100}`); + handle.setAttribute('aria-valuemax', `${MAX_RATIO * 100}`); + + function sync() { + const splitPercent = `${ratio * 100}%`; + const splitX = canvas.clientWidth * ratio; + + handle.style.left = splitPercent; + handle.setAttribute('aria-valuenow', `${Math.round(ratio * 100)}`); + leftPill.style.left = splitPercent; + leftPill.style.maxWidth = `${Math.max(0, splitX - LABEL_MARGIN)}px`; + rightPill.style.left = splitPercent; + rightPill.style.maxWidth = `${Math.max(0, canvas.clientWidth - splitX - LABEL_MARGIN)}px`; + onChange(ratio); + } + + function setRatio(nextRatio: number) { + ratio = clampRatio(nextRatio); + sync(); + } + + function setRatioFromClientX(clientX: number) { + const rect = canvas.getBoundingClientRect(); + if (rect.width > 0) { + setRatio((clientX - rect.left) / rect.width); + } + } + + handle.addEventListener('pointerdown', (event) => { + event.preventDefault(); + pointerId = event.pointerId; + handle.style.opacity = '1'; + handle.setPointerCapture(pointerId); + setRatioFromClientX(event.clientX); + }); + handle.addEventListener('pointermove', (event) => { + if (event.pointerId === pointerId) { + setRatioFromClientX(event.clientX); + } + }); + + const stopDrag = (event: PointerEvent) => { + if (event.pointerId !== pointerId) { + return; + } + + if (handle.hasPointerCapture(pointerId)) { + handle.releasePointerCapture(pointerId); + } + handle.style.opacity = '0.68'; + pointerId = undefined; + }; + handle.addEventListener('pointerup', stopDrag); + handle.addEventListener('pointercancel', stopDrag); + handle.addEventListener('keydown', (event) => { + const step = event.shiftKey ? 0.1 : 0.02; + if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') { + event.preventDefault(); + setRatio(ratio + step * (event.key === 'ArrowLeft' ? -1 : 1)); + } + }); + + handle.append(line, grip); + labels.append(leftPill, rightPill); + host.append(handle, labels); + sync(); + + return { + get ratio() { + return ratio; + }, + sync, + destroy() { + handle.remove(); + labels.remove(); + }, + }; +} diff --git a/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/thumbnail.png b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/thumbnail.png new file mode 100644 index 0000000000..ae19f0ad3a Binary files /dev/null and b/apps/typegpu-docs/src/examples/rendering/triplanar-mapping/thumbnail.png differ