warp-lang 0.11.0__py3-none-manylinux2014_x86_64.whl → 1.0.0__py3-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +8 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +7 -6
- warp/build_dll.py +70 -79
- warp/builtins.py +10 -6
- warp/codegen.py +51 -19
- warp/config.py +7 -8
- warp/constants.py +3 -0
- warp/context.py +948 -245
- warp/dlpack.py +198 -113
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -0
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usda +42 -0
- warp/examples/assets/nv_ant.xml +92 -0
- warp/examples/assets/nv_humanoid.xml +183 -0
- warp/examples/assets/quadruped.urdf +268 -0
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usda +56 -0
- warp/examples/assets/torus.usda +105 -0
- warp/examples/benchmarks/benchmark_api.py +383 -0
- warp/examples/benchmarks/benchmark_cloth.py +279 -0
- warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -0
- warp/examples/benchmarks/benchmark_cloth_jax.py +100 -0
- warp/examples/benchmarks/benchmark_cloth_numba.py +142 -0
- warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -0
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -0
- warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +146 -0
- warp/examples/benchmarks/benchmark_launches.py +295 -0
- warp/examples/core/example_dem.py +221 -0
- warp/examples/core/example_fluid.py +267 -0
- warp/examples/core/example_graph_capture.py +129 -0
- warp/examples/core/example_marching_cubes.py +177 -0
- warp/examples/core/example_mesh.py +154 -0
- warp/examples/core/example_mesh_intersect.py +193 -0
- warp/examples/core/example_nvdb.py +169 -0
- warp/examples/core/example_raycast.py +89 -0
- warp/examples/core/example_raymarch.py +178 -0
- warp/examples/core/example_render_opengl.py +141 -0
- warp/examples/core/example_sph.py +389 -0
- warp/examples/core/example_torch.py +181 -0
- warp/examples/core/example_wave.py +249 -0
- warp/examples/fem/bsr_utils.py +380 -0
- warp/examples/fem/example_apic_fluid.py +391 -0
- warp/examples/fem/example_convection_diffusion.py +168 -0
- warp/examples/fem/example_convection_diffusion_dg.py +209 -0
- warp/examples/fem/example_convection_diffusion_dg0.py +194 -0
- warp/examples/fem/example_deformed_geometry.py +159 -0
- warp/examples/fem/example_diffusion.py +173 -0
- warp/examples/fem/example_diffusion_3d.py +152 -0
- warp/examples/fem/example_diffusion_mgpu.py +214 -0
- warp/examples/fem/example_mixed_elasticity.py +222 -0
- warp/examples/fem/example_navier_stokes.py +243 -0
- warp/examples/fem/example_stokes.py +192 -0
- warp/examples/fem/example_stokes_transfer.py +249 -0
- warp/examples/fem/mesh_utils.py +109 -0
- warp/examples/fem/plot_utils.py +287 -0
- warp/examples/optim/example_bounce.py +248 -0
- warp/examples/optim/example_cloth_throw.py +210 -0
- warp/examples/optim/example_diffray.py +535 -0
- warp/examples/optim/example_drone.py +850 -0
- warp/examples/optim/example_inverse_kinematics.py +169 -0
- warp/examples/optim/example_inverse_kinematics_torch.py +170 -0
- warp/examples/optim/example_spring_cage.py +234 -0
- warp/examples/optim/example_trajectory.py +201 -0
- warp/examples/sim/example_cartpole.py +128 -0
- warp/examples/sim/example_cloth.py +184 -0
- warp/examples/sim/example_granular.py +113 -0
- warp/examples/sim/example_granular_collision_sdf.py +185 -0
- warp/examples/sim/example_jacobian_ik.py +213 -0
- warp/examples/sim/example_particle_chain.py +106 -0
- warp/examples/sim/example_quadruped.py +179 -0
- warp/examples/sim/example_rigid_chain.py +191 -0
- warp/examples/sim/example_rigid_contact.py +176 -0
- warp/examples/sim/example_rigid_force.py +126 -0
- warp/examples/sim/example_rigid_gyroscopic.py +97 -0
- warp/examples/sim/example_rigid_soft_contact.py +124 -0
- warp/examples/sim/example_soft_body.py +178 -0
- warp/fabric.py +29 -20
- warp/fem/cache.py +0 -1
- warp/fem/dirichlet.py +0 -2
- warp/fem/integrate.py +0 -1
- warp/jax.py +45 -0
- warp/jax_experimental.py +339 -0
- warp/native/builtin.h +12 -0
- warp/native/bvh.cu +18 -18
- warp/native/clang/clang.cpp +8 -3
- warp/native/cuda_util.cpp +94 -5
- warp/native/cuda_util.h +35 -6
- warp/native/cutlass_gemm.cpp +1 -1
- warp/native/cutlass_gemm.cu +4 -1
- warp/native/error.cpp +66 -0
- warp/native/error.h +27 -0
- warp/native/mesh.cu +2 -2
- warp/native/reduce.cu +4 -4
- warp/native/runlength_encode.cu +2 -2
- warp/native/scan.cu +2 -2
- warp/native/sparse.cu +0 -1
- warp/native/temp_buffer.h +2 -2
- warp/native/warp.cpp +95 -60
- warp/native/warp.cu +1053 -218
- warp/native/warp.h +49 -32
- warp/optim/linear.py +33 -16
- warp/render/render_opengl.py +202 -101
- warp/render/render_usd.py +82 -40
- warp/sim/__init__.py +13 -4
- warp/sim/articulation.py +4 -5
- warp/sim/collide.py +320 -175
- warp/sim/import_mjcf.py +25 -30
- warp/sim/import_urdf.py +94 -63
- warp/sim/import_usd.py +51 -36
- warp/sim/inertia.py +3 -2
- warp/sim/integrator.py +233 -0
- warp/sim/integrator_euler.py +447 -469
- warp/sim/integrator_featherstone.py +1991 -0
- warp/sim/integrator_xpbd.py +1420 -640
- warp/sim/model.py +765 -487
- warp/sim/particles.py +2 -1
- warp/sim/render.py +35 -13
- warp/sim/utils.py +222 -11
- warp/stubs.py +8 -0
- warp/tape.py +16 -1
- warp/tests/aux_test_grad_customs.py +23 -0
- warp/tests/test_array.py +190 -1
- warp/tests/test_async.py +656 -0
- warp/tests/test_bool.py +50 -0
- warp/tests/test_dlpack.py +164 -11
- warp/tests/test_examples.py +166 -74
- warp/tests/test_fem.py +8 -1
- warp/tests/test_generics.py +15 -5
- warp/tests/test_grad.py +1 -1
- warp/tests/test_grad_customs.py +172 -12
- warp/tests/test_jax.py +254 -0
- warp/tests/test_large.py +29 -6
- warp/tests/test_launch.py +25 -0
- warp/tests/test_linear_solvers.py +20 -3
- warp/tests/test_matmul.py +61 -16
- warp/tests/test_matmul_lite.py +13 -13
- warp/tests/test_mempool.py +186 -0
- warp/tests/test_multigpu.py +3 -0
- warp/tests/test_options.py +16 -2
- warp/tests/test_peer.py +137 -0
- warp/tests/test_print.py +3 -1
- warp/tests/test_quat.py +23 -0
- warp/tests/test_sim_kinematics.py +97 -0
- warp/tests/test_snippet.py +126 -3
- warp/tests/test_streams.py +108 -79
- warp/tests/test_torch.py +16 -8
- warp/tests/test_utils.py +32 -27
- warp/tests/test_verify_fp.py +65 -0
- warp/tests/test_volume.py +1 -1
- warp/tests/unittest_serial.py +2 -0
- warp/tests/unittest_suites.py +12 -0
- warp/tests/unittest_utils.py +14 -7
- warp/thirdparty/unittest_parallel.py +15 -3
- warp/torch.py +10 -8
- warp/types.py +363 -246
- warp/utils.py +143 -19
- warp_lang-1.0.0.dist-info/LICENSE.md +126 -0
- warp_lang-1.0.0.dist-info/METADATA +394 -0
- {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/RECORD +167 -86
- warp/sim/optimizer.py +0 -138
- warp_lang-0.11.0.dist-info/LICENSE.md +0 -36
- warp_lang-0.11.0.dist-info/METADATA +0 -238
- /warp/tests/{walkthough_debug.py → walkthrough_debug.py} +0 -0
- {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/WHEEL +0 -0
- {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/top_level.txt +0 -0
warp/render/render_opengl.py
CHANGED
|
@@ -667,6 +667,45 @@ class ShapeInstancer:
|
|
|
667
667
|
|
|
668
668
|
self.face_count = len(indices)
|
|
669
669
|
|
|
670
|
+
def update_colors(self, colors1, colors2):
|
|
671
|
+
from pyglet import gl
|
|
672
|
+
|
|
673
|
+
if colors1 is None:
|
|
674
|
+
colors1 = np.tile(self.color1, (self.num_instances, 1))
|
|
675
|
+
if colors2 is None:
|
|
676
|
+
colors2 = np.tile(self.color2, (self.num_instances, 1))
|
|
677
|
+
if np.shape(colors1) != (self.num_instances, 3):
|
|
678
|
+
colors1 = np.tile(colors1, (self.num_instances, 1))
|
|
679
|
+
if np.shape(colors2) != (self.num_instances, 3):
|
|
680
|
+
colors2 = np.tile(colors2, (self.num_instances, 1))
|
|
681
|
+
colors1 = np.array(colors1, dtype=np.float32)
|
|
682
|
+
colors2 = np.array(colors2, dtype=np.float32)
|
|
683
|
+
|
|
684
|
+
gl.glBindVertexArray(self.vao)
|
|
685
|
+
|
|
686
|
+
# create buffer for checkerboard colors
|
|
687
|
+
if self.instance_color1_buffer is None:
|
|
688
|
+
self.instance_color1_buffer = gl.GLuint()
|
|
689
|
+
gl.glGenBuffers(1, self.instance_color1_buffer)
|
|
690
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color1_buffer)
|
|
691
|
+
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors1.nbytes, colors1.ctypes.data, gl.GL_STATIC_DRAW)
|
|
692
|
+
|
|
693
|
+
if self.instance_color2_buffer is None:
|
|
694
|
+
self.instance_color2_buffer = gl.GLuint()
|
|
695
|
+
gl.glGenBuffers(1, self.instance_color2_buffer)
|
|
696
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color2_buffer)
|
|
697
|
+
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors2.nbytes, colors2.ctypes.data, gl.GL_STATIC_DRAW)
|
|
698
|
+
|
|
699
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color1_buffer)
|
|
700
|
+
gl.glVertexAttribPointer(7, 3, gl.GL_FLOAT, gl.GL_FALSE, colors1[0].nbytes, ctypes.c_void_p(0))
|
|
701
|
+
gl.glEnableVertexAttribArray(7)
|
|
702
|
+
gl.glVertexAttribDivisor(7, 1)
|
|
703
|
+
|
|
704
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color2_buffer)
|
|
705
|
+
gl.glVertexAttribPointer(8, 3, gl.GL_FLOAT, gl.GL_FALSE, colors2[0].nbytes, ctypes.c_void_p(0))
|
|
706
|
+
gl.glEnableVertexAttribArray(8)
|
|
707
|
+
gl.glVertexAttribDivisor(8, 1)
|
|
708
|
+
|
|
670
709
|
def allocate_instances(self, positions, rotations=None, colors1=None, colors2=None, scalings=None):
|
|
671
710
|
from pyglet import gl
|
|
672
711
|
|
|
@@ -723,31 +762,11 @@ class ShapeInstancer:
|
|
|
723
762
|
int(self.instance_transform_gl_buffer.value), self.device
|
|
724
763
|
)
|
|
725
764
|
|
|
726
|
-
|
|
727
|
-
colors1 = np.tile(self.color1, (self.num_instances, 1))
|
|
728
|
-
if colors2 is None:
|
|
729
|
-
colors2 = np.tile(self.color2, (self.num_instances, 1))
|
|
730
|
-
colors1 = np.array(colors1, dtype=np.float32)
|
|
731
|
-
colors2 = np.array(colors2, dtype=np.float32)
|
|
732
|
-
|
|
733
|
-
# create buffer for checkerboard colors
|
|
734
|
-
if self.instance_color1_buffer is None:
|
|
735
|
-
self.instance_color1_buffer = gl.GLuint()
|
|
736
|
-
gl.glGenBuffers(1, self.instance_color1_buffer)
|
|
737
|
-
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color1_buffer)
|
|
738
|
-
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors1.nbytes, colors1.ctypes.data, gl.GL_STATIC_DRAW)
|
|
739
|
-
|
|
740
|
-
if self.instance_color2_buffer is None:
|
|
741
|
-
self.instance_color2_buffer = gl.GLuint()
|
|
742
|
-
gl.glGenBuffers(1, self.instance_color2_buffer)
|
|
743
|
-
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color2_buffer)
|
|
744
|
-
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors2.nbytes, colors2.ctypes.data, gl.GL_STATIC_DRAW)
|
|
765
|
+
self.update_colors(colors1, colors2)
|
|
745
766
|
|
|
746
767
|
# Set up instance attribute pointers
|
|
747
768
|
matrix_size = vbo_transforms[0].nbytes
|
|
748
769
|
|
|
749
|
-
gl.glBindVertexArray(self.vao)
|
|
750
|
-
|
|
751
770
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_transform_gl_buffer)
|
|
752
771
|
|
|
753
772
|
# we can only send vec4s to the shader, so we need to split the instance transforms matrix into its column vectors
|
|
@@ -758,16 +777,6 @@ class ShapeInstancer:
|
|
|
758
777
|
gl.glEnableVertexAttribArray(3 + i)
|
|
759
778
|
gl.glVertexAttribDivisor(3 + i, 1)
|
|
760
779
|
|
|
761
|
-
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color1_buffer)
|
|
762
|
-
gl.glVertexAttribPointer(7, 3, gl.GL_FLOAT, gl.GL_FALSE, colors1[0].nbytes, ctypes.c_void_p(0))
|
|
763
|
-
gl.glEnableVertexAttribArray(7)
|
|
764
|
-
gl.glVertexAttribDivisor(7, 1)
|
|
765
|
-
|
|
766
|
-
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.instance_color2_buffer)
|
|
767
|
-
gl.glVertexAttribPointer(8, 3, gl.GL_FLOAT, gl.GL_FALSE, colors2[0].nbytes, ctypes.c_void_p(0))
|
|
768
|
-
gl.glEnableVertexAttribArray(8)
|
|
769
|
-
gl.glVertexAttribDivisor(8, 1)
|
|
770
|
-
|
|
771
780
|
gl.glBindVertexArray(0)
|
|
772
781
|
|
|
773
782
|
def update_instances(self, transforms: wp.array = None, scalings: wp.array = None, colors1=None, colors2=None):
|
|
@@ -808,6 +817,9 @@ class ShapeInstancer:
|
|
|
808
817
|
|
|
809
818
|
self._instance_transform_cuda_buffer.unmap()
|
|
810
819
|
|
|
820
|
+
if colors1 is not None or colors2 is not None:
|
|
821
|
+
self.update_colors(colors1, colors2)
|
|
822
|
+
|
|
811
823
|
def render(self):
|
|
812
824
|
from pyglet import gl
|
|
813
825
|
|
|
@@ -914,9 +926,6 @@ class OpenGLRenderer:
|
|
|
914
926
|
self.enable_mouse_interaction = enable_mouse_interaction
|
|
915
927
|
self.enable_keyboard_interaction = enable_keyboard_interaction
|
|
916
928
|
|
|
917
|
-
self._camera_pos = PyVec3(*camera_pos)
|
|
918
|
-
self._camera_front = PyVec3(*camera_front)
|
|
919
|
-
self._camera_up = PyVec3(*camera_up)
|
|
920
929
|
self._camera_speed = 0.04
|
|
921
930
|
if isinstance(up_axis, int):
|
|
922
931
|
self._camera_axis = up_axis
|
|
@@ -927,12 +936,19 @@ class OpenGLRenderer:
|
|
|
927
936
|
self._first_mouse = True
|
|
928
937
|
self._left_mouse_pressed = False
|
|
929
938
|
self._keys_pressed = defaultdict(bool)
|
|
939
|
+
self._input_processors = []
|
|
930
940
|
self._key_callbacks = []
|
|
931
941
|
|
|
932
942
|
self.render_2d_callbacks = []
|
|
933
943
|
self.render_3d_callbacks = []
|
|
934
944
|
|
|
935
|
-
self.
|
|
945
|
+
self._camera_pos = PyVec3(0.0, 0.0, 0.0)
|
|
946
|
+
self._camera_front = PyVec3(0.0, 0.0, -1.0)
|
|
947
|
+
self._camera_up = PyVec3(0.0, 1.0, 0.0)
|
|
948
|
+
self._scaling = scaling
|
|
949
|
+
|
|
950
|
+
self._model_matrix = self.compute_model_matrix(self._camera_axis, scaling)
|
|
951
|
+
self.update_view_matrix(cam_pos=camera_pos, cam_front=camera_front, cam_up=camera_up)
|
|
936
952
|
self.update_projection_matrix()
|
|
937
953
|
|
|
938
954
|
self._frame_dt = 1.0 / fps
|
|
@@ -1549,37 +1565,65 @@ class OpenGLRenderer:
|
|
|
1549
1565
|
self.camera_fov, aspect_ratio, self.camera_near_plane, self.camera_far_plane
|
|
1550
1566
|
)
|
|
1551
1567
|
|
|
1552
|
-
|
|
1553
|
-
|
|
1568
|
+
@property
|
|
1569
|
+
def camera_pos(self):
|
|
1570
|
+
return self._camera_pos
|
|
1554
1571
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1572
|
+
@camera_pos.setter
|
|
1573
|
+
def camera_pos(self, value):
|
|
1574
|
+
self.update_view_matrix(cam_pos=value)
|
|
1557
1575
|
|
|
1558
|
-
|
|
1576
|
+
@property
|
|
1577
|
+
def camera_front(self):
|
|
1578
|
+
return self._camera_front
|
|
1579
|
+
|
|
1580
|
+
@camera_front.setter
|
|
1581
|
+
def camera_front(self, value):
|
|
1582
|
+
self.update_view_matrix(cam_front=value)
|
|
1583
|
+
|
|
1584
|
+
@property
|
|
1585
|
+
def camera_up(self):
|
|
1586
|
+
return self._camera_up
|
|
1587
|
+
|
|
1588
|
+
@camera_up.setter
|
|
1589
|
+
def camera_up(self, value):
|
|
1590
|
+
self.update_view_matrix(cam_up=value)
|
|
1591
|
+
|
|
1592
|
+
def update_view_matrix(self, cam_pos=None, cam_front=None, cam_up=None, stiffness=1.0):
|
|
1593
|
+
from pyglet.math import Vec3, Mat4
|
|
1594
|
+
|
|
1595
|
+
if cam_pos is not None:
|
|
1596
|
+
self._camera_pos = self._camera_pos * (1.0 - stiffness) + Vec3(*cam_pos) * stiffness
|
|
1597
|
+
if cam_front is not None:
|
|
1598
|
+
self._camera_front = self._camera_front * (1.0 - stiffness) + Vec3(*cam_front) * stiffness
|
|
1599
|
+
if cam_up is not None:
|
|
1600
|
+
self._camera_up = self._camera_up * (1.0 - stiffness) + Vec3(*cam_up) * stiffness
|
|
1601
|
+
|
|
1602
|
+
model = np.array(self._model_matrix).reshape((4, 4))
|
|
1603
|
+
cp = model @ np.array([*self._camera_pos / self._scaling, 1.0])
|
|
1604
|
+
cf = model @ np.array([*self._camera_front / self._scaling, 1.0])
|
|
1605
|
+
up = model @ np.array([*self._camera_up / self._scaling, 0.0])
|
|
1606
|
+
cp = Vec3(*cp[:3])
|
|
1607
|
+
cf = Vec3(*cf[:3])
|
|
1608
|
+
up = Vec3(*up[:3])
|
|
1609
|
+
self._view_matrix = np.array(Mat4.look_at(cp, cp + cf, up))
|
|
1610
|
+
|
|
1611
|
+
def compute_model_matrix(self, camera_axis: int, scaling: float):
|
|
1612
|
+
if camera_axis == 0:
|
|
1613
|
+
return np.array((0, 0, scaling, 0, scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, 0, 1))
|
|
1614
|
+
elif camera_axis == 2:
|
|
1615
|
+
return np.array((-scaling, 0, 0, 0, 0, 0, scaling, 0, 0, scaling, 0, 0, 0, 0, 0, 1))
|
|
1616
|
+
|
|
1617
|
+
return np.array((scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, 1))
|
|
1618
|
+
|
|
1619
|
+
def update_model_matrix(self, model_matrix: Optional[Mat44] = None):
|
|
1559
1620
|
from pyglet import gl
|
|
1560
1621
|
|
|
1561
1622
|
# fmt: off
|
|
1562
|
-
if
|
|
1563
|
-
self._model_matrix =
|
|
1564
|
-
0, 0, self._scaling, 0,
|
|
1565
|
-
self._scaling, 0, 0, 0,
|
|
1566
|
-
0, self._scaling, 0, 0,
|
|
1567
|
-
0, 0, 0, 1
|
|
1568
|
-
))
|
|
1569
|
-
elif self._camera_axis == 2:
|
|
1570
|
-
self._model_matrix = np.array((
|
|
1571
|
-
-self._scaling, 0, 0, 0,
|
|
1572
|
-
0, 0, self._scaling, 0,
|
|
1573
|
-
0, self._scaling, 0, 0,
|
|
1574
|
-
0, 0, 0, 1
|
|
1575
|
-
))
|
|
1623
|
+
if model_matrix is None:
|
|
1624
|
+
self._model_matrix = self.compute_model_matrix(self._camera_axis, self._scaling)
|
|
1576
1625
|
else:
|
|
1577
|
-
self._model_matrix = np.array((
|
|
1578
|
-
self._scaling, 0, 0, 0,
|
|
1579
|
-
0, self._scaling, 0, 0,
|
|
1580
|
-
0, 0, self._scaling, 0,
|
|
1581
|
-
0, 0, 0, 1
|
|
1582
|
-
))
|
|
1626
|
+
self._model_matrix = np.array(model_matrix).flatten()
|
|
1583
1627
|
# fmt: on
|
|
1584
1628
|
ptr = arr_pointer(self._model_matrix)
|
|
1585
1629
|
gl.glUseProgram(self._shape_shader.id)
|
|
@@ -1890,6 +1934,10 @@ Instances: {len(self._instances)}"""
|
|
|
1890
1934
|
import pyglet
|
|
1891
1935
|
from pyglet.math import Vec3 as PyVec3
|
|
1892
1936
|
|
|
1937
|
+
for cb in self._input_processors:
|
|
1938
|
+
if cb(self._key_handler) == pyglet.event.EVENT_HANDLED:
|
|
1939
|
+
return
|
|
1940
|
+
|
|
1893
1941
|
if self._key_handler[pyglet.window.key.W] or self._key_handler[pyglet.window.key.UP]:
|
|
1894
1942
|
self._camera_pos += self._camera_front * (self._camera_speed * self._frame_speed)
|
|
1895
1943
|
self.update_view_matrix()
|
|
@@ -1905,12 +1953,19 @@ Instances: {len(self._instances)}"""
|
|
|
1905
1953
|
self._camera_pos += camera_side * (self._camera_speed * self._frame_speed)
|
|
1906
1954
|
self.update_view_matrix()
|
|
1907
1955
|
|
|
1956
|
+
def register_input_processor(self, callback):
|
|
1957
|
+
self._input_processors.append(callback)
|
|
1958
|
+
|
|
1908
1959
|
def _key_press_callback(self, symbol, modifiers):
|
|
1909
1960
|
import pyglet
|
|
1910
1961
|
|
|
1911
1962
|
if not self.enable_keyboard_interaction:
|
|
1912
1963
|
return
|
|
1913
1964
|
|
|
1965
|
+
for cb in self._key_callbacks:
|
|
1966
|
+
if cb(symbol, modifiers) == pyglet.event.EVENT_HANDLED:
|
|
1967
|
+
return pyglet.event.EVENT_HANDLED
|
|
1968
|
+
|
|
1914
1969
|
if symbol == pyglet.window.key.ESCAPE:
|
|
1915
1970
|
self.close()
|
|
1916
1971
|
if symbol == pyglet.window.key.SPACE:
|
|
@@ -1930,9 +1985,6 @@ Instances: {len(self._instances)}"""
|
|
|
1930
1985
|
if symbol == pyglet.window.key.B:
|
|
1931
1986
|
self.enable_backface_culling = not self.enable_backface_culling
|
|
1932
1987
|
|
|
1933
|
-
for cb in self._key_callbacks:
|
|
1934
|
-
cb(symbol, modifiers)
|
|
1935
|
-
|
|
1936
1988
|
def register_key_press_callback(self, callback):
|
|
1937
1989
|
self._key_callbacks.append(callback)
|
|
1938
1990
|
|
|
@@ -2018,6 +2070,34 @@ Instances: {len(self._instances)}"""
|
|
|
2018
2070
|
self._instance_count = len(self._instances)
|
|
2019
2071
|
return instance
|
|
2020
2072
|
|
|
2073
|
+
def update_instance_colors(self):
|
|
2074
|
+
from pyglet import gl
|
|
2075
|
+
|
|
2076
|
+
colors1, colors2 = [], []
|
|
2077
|
+
all_instances = list(self._instances.values())
|
|
2078
|
+
for shape, instances in self._shape_instances.items():
|
|
2079
|
+
for i in instances:
|
|
2080
|
+
if i >= len(all_instances):
|
|
2081
|
+
continue
|
|
2082
|
+
instance = all_instances[i]
|
|
2083
|
+
colors1.append(instance[5])
|
|
2084
|
+
colors2.append(instance[6])
|
|
2085
|
+
colors1 = np.array(colors1, dtype=np.float32)
|
|
2086
|
+
colors2 = np.array(colors2, dtype=np.float32)
|
|
2087
|
+
|
|
2088
|
+
# create buffer for checkerboard colors
|
|
2089
|
+
if self._instance_color1_buffer is None:
|
|
2090
|
+
self._instance_color1_buffer = gl.GLuint()
|
|
2091
|
+
gl.glGenBuffers(1, self._instance_color1_buffer)
|
|
2092
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color1_buffer)
|
|
2093
|
+
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors1.nbytes, colors1.ctypes.data, gl.GL_STATIC_DRAW)
|
|
2094
|
+
|
|
2095
|
+
if self._instance_color2_buffer is None:
|
|
2096
|
+
self._instance_color2_buffer = gl.GLuint()
|
|
2097
|
+
gl.glGenBuffers(1, self._instance_color2_buffer)
|
|
2098
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
|
|
2099
|
+
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors2.nbytes, colors2.ctypes.data, gl.GL_STATIC_DRAW)
|
|
2100
|
+
|
|
2021
2101
|
def allocate_shape_instances(self):
|
|
2022
2102
|
from pyglet import gl
|
|
2023
2103
|
|
|
@@ -2051,28 +2131,7 @@ Instances: {len(self._instances)}"""
|
|
|
2051
2131
|
int(self._instance_transform_gl_buffer.value), self._device
|
|
2052
2132
|
)
|
|
2053
2133
|
|
|
2054
|
-
|
|
2055
|
-
all_instances = list(self._instances.values())
|
|
2056
|
-
for shape, instances in self._shape_instances.items():
|
|
2057
|
-
for i in instances:
|
|
2058
|
-
if i >= len(all_instances):
|
|
2059
|
-
continue
|
|
2060
|
-
instance = all_instances[i]
|
|
2061
|
-
colors1.append(instance[5])
|
|
2062
|
-
colors2.append(instance[6])
|
|
2063
|
-
colors1 = np.array(colors1, dtype=np.float32)
|
|
2064
|
-
colors2 = np.array(colors2, dtype=np.float32)
|
|
2065
|
-
|
|
2066
|
-
# create buffer for checkerboard colors
|
|
2067
|
-
self._instance_color1_buffer = gl.GLuint()
|
|
2068
|
-
gl.glGenBuffers(1, self._instance_color1_buffer)
|
|
2069
|
-
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color1_buffer)
|
|
2070
|
-
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors1.nbytes, colors1.ctypes.data, gl.GL_STATIC_DRAW)
|
|
2071
|
-
|
|
2072
|
-
self._instance_color2_buffer = gl.GLuint()
|
|
2073
|
-
gl.glGenBuffers(1, self._instance_color2_buffer)
|
|
2074
|
-
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
|
|
2075
|
-
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors2.nbytes, colors2.ctypes.data, gl.GL_STATIC_DRAW)
|
|
2134
|
+
self.update_instance_colors()
|
|
2076
2135
|
|
|
2077
2136
|
# set up instance attribute pointers
|
|
2078
2137
|
matrix_size = transforms[0].nbytes
|
|
@@ -2083,6 +2142,7 @@ Instances: {len(self._instances)}"""
|
|
|
2083
2142
|
instances = list(self._instances.values())
|
|
2084
2143
|
inverse_instance_ids = {}
|
|
2085
2144
|
instance_count = 0
|
|
2145
|
+
colors_size = np.zeros(3, dtype=np.float32).nbytes
|
|
2086
2146
|
for shape, (vao, vbo, ebo, tri_count, vertex_cuda_buffer) in self._shape_gl_buffers.items():
|
|
2087
2147
|
gl.glBindVertexArray(vao)
|
|
2088
2148
|
|
|
@@ -2097,12 +2157,12 @@ Instances: {len(self._instances)}"""
|
|
|
2097
2157
|
gl.glVertexAttribDivisor(3 + i, 1)
|
|
2098
2158
|
|
|
2099
2159
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color1_buffer)
|
|
2100
|
-
gl.glVertexAttribPointer(7, 3, gl.GL_FLOAT, gl.GL_FALSE,
|
|
2160
|
+
gl.glVertexAttribPointer(7, 3, gl.GL_FLOAT, gl.GL_FALSE, colors_size, ctypes.c_void_p(0))
|
|
2101
2161
|
gl.glEnableVertexAttribArray(7)
|
|
2102
2162
|
gl.glVertexAttribDivisor(7, 1)
|
|
2103
2163
|
|
|
2104
2164
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
|
|
2105
|
-
gl.glVertexAttribPointer(8, 3, gl.GL_FLOAT, gl.GL_FALSE,
|
|
2165
|
+
gl.glVertexAttribPointer(8, 3, gl.GL_FLOAT, gl.GL_FALSE, colors_size, ctypes.c_void_p(0))
|
|
2106
2166
|
gl.glEnableVertexAttribArray(8)
|
|
2107
2167
|
gl.glVertexAttribDivisor(8, 1)
|
|
2108
2168
|
|
|
@@ -2124,7 +2184,7 @@ Instances: {len(self._instances)}"""
|
|
|
2124
2184
|
|
|
2125
2185
|
gl.glBindVertexArray(0)
|
|
2126
2186
|
|
|
2127
|
-
def update_shape_instance(self, name, pos, rot, color1=None, color2=None, visible=None):
|
|
2187
|
+
def update_shape_instance(self, name, pos=None, rot=None, color1=None, color2=None, visible=None):
|
|
2128
2188
|
"""Update the instance transform of the shape
|
|
2129
2189
|
|
|
2130
2190
|
Args:
|
|
@@ -2135,21 +2195,33 @@ Instances: {len(self._instances)}"""
|
|
|
2135
2195
|
color2: The second color of the checker pattern
|
|
2136
2196
|
visible: Whether the shape is visible
|
|
2137
2197
|
"""
|
|
2198
|
+
from pyglet import gl
|
|
2199
|
+
|
|
2138
2200
|
if name in self._instances:
|
|
2139
|
-
i, body, shape,
|
|
2201
|
+
i, body, shape, tf, scale, old_color1, old_color2, v = self._instances[name]
|
|
2140
2202
|
if visible is None:
|
|
2141
2203
|
visible = v
|
|
2204
|
+
new_tf = np.copy(tf)
|
|
2205
|
+
if pos is not None:
|
|
2206
|
+
new_tf[:3] = pos
|
|
2207
|
+
if rot is not None:
|
|
2208
|
+
new_tf[3:] = rot
|
|
2142
2209
|
self._instances[name] = (
|
|
2143
2210
|
i,
|
|
2144
2211
|
body,
|
|
2145
2212
|
shape,
|
|
2146
|
-
|
|
2213
|
+
new_tf,
|
|
2147
2214
|
scale,
|
|
2148
2215
|
color1 or old_color1,
|
|
2149
2216
|
color2 or old_color2,
|
|
2150
2217
|
visible,
|
|
2151
2218
|
)
|
|
2152
2219
|
self._update_shape_instances = True
|
|
2220
|
+
if color1 is not None or color2 is not None:
|
|
2221
|
+
vao, vbo, ebo, tri_count, vertex_cuda_buffer = self._shape_gl_buffers[shape]
|
|
2222
|
+
gl.glBindVertexArray(vao)
|
|
2223
|
+
self.update_instance_colors()
|
|
2224
|
+
gl.glBindVertexArray(0)
|
|
2153
2225
|
return True
|
|
2154
2226
|
return False
|
|
2155
2227
|
|
|
@@ -2425,7 +2497,7 @@ Instances: {len(self._instances)}"""
|
|
|
2425
2497
|
self.add_shape_instance(name, shape, body, pos, rot)
|
|
2426
2498
|
return shape
|
|
2427
2499
|
|
|
2428
|
-
def render_ground(self, size: float =
|
|
2500
|
+
def render_ground(self, size: float = 1000.0, plane=None):
|
|
2429
2501
|
"""Add a ground plane for visualization
|
|
2430
2502
|
|
|
2431
2503
|
Args:
|
|
@@ -2440,9 +2512,22 @@ Instances: {len(self._instances)}"""
|
|
|
2440
2512
|
q = (0.0, 0.0, 0.0, 1.0)
|
|
2441
2513
|
elif self._camera_axis == 2:
|
|
2442
2514
|
q = (sqh, 0.0, 0.0, sqh)
|
|
2515
|
+
pos = (0.0, 0.0, 0.0)
|
|
2516
|
+
if plane is not None:
|
|
2517
|
+
normal = np.array(plane[:3])
|
|
2518
|
+
normal /= np.linalg.norm(normal)
|
|
2519
|
+
pos = plane[3] * normal
|
|
2520
|
+
if np.allclose(normal, (0.0, 1.0, 0.0)):
|
|
2521
|
+
# no rotation necessary
|
|
2522
|
+
q = (0.0, 0.0, 0.0, 1.0)
|
|
2523
|
+
else:
|
|
2524
|
+
c = np.cross(normal, (0.0, 1.0, 0.0))
|
|
2525
|
+
angle = np.arcsin(np.linalg.norm(c))
|
|
2526
|
+
axis = np.abs(c) / np.linalg.norm(c)
|
|
2527
|
+
q = wp.quat_from_axis_angle(axis, angle)
|
|
2443
2528
|
return self.render_plane(
|
|
2444
2529
|
"ground",
|
|
2445
|
-
|
|
2530
|
+
pos,
|
|
2446
2531
|
q,
|
|
2447
2532
|
size,
|
|
2448
2533
|
size,
|
|
@@ -2453,7 +2538,14 @@ Instances: {len(self._instances)}"""
|
|
|
2453
2538
|
)
|
|
2454
2539
|
|
|
2455
2540
|
def render_sphere(
|
|
2456
|
-
self,
|
|
2541
|
+
self,
|
|
2542
|
+
name: str,
|
|
2543
|
+
pos: tuple,
|
|
2544
|
+
rot: tuple,
|
|
2545
|
+
radius: float,
|
|
2546
|
+
parent_body: str = None,
|
|
2547
|
+
is_template: bool = False,
|
|
2548
|
+
color=None,
|
|
2457
2549
|
):
|
|
2458
2550
|
"""Add a sphere for visualization
|
|
2459
2551
|
|
|
@@ -2461,18 +2553,19 @@ Instances: {len(self._instances)}"""
|
|
|
2461
2553
|
pos: The position of the sphere
|
|
2462
2554
|
radius: The radius of the sphere
|
|
2463
2555
|
name: A name for the USD prim on the stage
|
|
2556
|
+
color: The color of the sphere
|
|
2464
2557
|
"""
|
|
2465
2558
|
geo_hash = hash(("sphere", radius))
|
|
2466
2559
|
if geo_hash in self._shape_geo_hash:
|
|
2467
2560
|
shape = self._shape_geo_hash[geo_hash]
|
|
2468
|
-
if self.update_shape_instance(name, pos, rot):
|
|
2561
|
+
if self.update_shape_instance(name, pos, rot, color1=color, color2=color):
|
|
2469
2562
|
return shape
|
|
2470
2563
|
else:
|
|
2471
2564
|
vertices, indices = self._create_sphere_mesh(radius)
|
|
2472
|
-
shape = self.register_shape(geo_hash, vertices, indices)
|
|
2565
|
+
shape = self.register_shape(geo_hash, vertices, indices, color1=color, color2=color)
|
|
2473
2566
|
if not is_template:
|
|
2474
2567
|
body = self._resolve_body_id(parent_body)
|
|
2475
|
-
self.add_shape_instance(name, shape, body, pos, rot)
|
|
2568
|
+
self.add_shape_instance(name, shape, body, pos, rot, color1=color, color2=color)
|
|
2476
2569
|
return shape
|
|
2477
2570
|
|
|
2478
2571
|
def render_capsule(
|
|
@@ -2485,6 +2578,7 @@ Instances: {len(self._instances)}"""
|
|
|
2485
2578
|
parent_body: str = None,
|
|
2486
2579
|
is_template: bool = False,
|
|
2487
2580
|
up_axis: int = 1,
|
|
2581
|
+
color: tuple = None,
|
|
2488
2582
|
):
|
|
2489
2583
|
"""Add a capsule for visualization
|
|
2490
2584
|
|
|
@@ -2494,6 +2588,7 @@ Instances: {len(self._instances)}"""
|
|
|
2494
2588
|
half_height: The half height of the capsule
|
|
2495
2589
|
name: A name for the USD prim on the stage
|
|
2496
2590
|
up_axis: The axis of the capsule that points up (0: x, 1: y, 2: z)
|
|
2591
|
+
color: The color of the capsule
|
|
2497
2592
|
"""
|
|
2498
2593
|
geo_hash = hash(("capsule", radius, half_height))
|
|
2499
2594
|
if geo_hash in self._shape_geo_hash:
|
|
@@ -2502,7 +2597,7 @@ Instances: {len(self._instances)}"""
|
|
|
2502
2597
|
return shape
|
|
2503
2598
|
else:
|
|
2504
2599
|
vertices, indices = self._create_capsule_mesh(radius, half_height, up_axis=up_axis)
|
|
2505
|
-
shape = self.register_shape(geo_hash, vertices, indices)
|
|
2600
|
+
shape = self.register_shape(geo_hash, vertices, indices, color1=color, color2=color)
|
|
2506
2601
|
if not is_template:
|
|
2507
2602
|
body = self._resolve_body_id(parent_body)
|
|
2508
2603
|
self.add_shape_instance(name, shape, body, pos, rot)
|
|
@@ -2518,6 +2613,7 @@ Instances: {len(self._instances)}"""
|
|
|
2518
2613
|
parent_body: str = None,
|
|
2519
2614
|
is_template: bool = False,
|
|
2520
2615
|
up_axis: int = 1,
|
|
2616
|
+
color: tuple = None,
|
|
2521
2617
|
):
|
|
2522
2618
|
"""Add a cylinder for visualization
|
|
2523
2619
|
|
|
@@ -2527,6 +2623,7 @@ Instances: {len(self._instances)}"""
|
|
|
2527
2623
|
half_height: The half height of the cylinder
|
|
2528
2624
|
name: A name for the USD prim on the stage
|
|
2529
2625
|
up_axis: The axis of the cylinder that points up (0: x, 1: y, 2: z)
|
|
2626
|
+
color: The color of the capsule
|
|
2530
2627
|
"""
|
|
2531
2628
|
geo_hash = hash(("cylinder", radius, half_height))
|
|
2532
2629
|
if geo_hash in self._shape_geo_hash:
|
|
@@ -2535,7 +2632,7 @@ Instances: {len(self._instances)}"""
|
|
|
2535
2632
|
return shape
|
|
2536
2633
|
else:
|
|
2537
2634
|
vertices, indices = self._create_cylinder_mesh(radius, half_height, up_axis=up_axis)
|
|
2538
|
-
shape = self.register_shape(geo_hash, vertices, indices)
|
|
2635
|
+
shape = self.register_shape(geo_hash, vertices, indices, color1=color, color2=color)
|
|
2539
2636
|
if not is_template:
|
|
2540
2637
|
body = self._resolve_body_id(parent_body)
|
|
2541
2638
|
self.add_shape_instance(name, shape, body, pos, rot)
|
|
@@ -2551,6 +2648,7 @@ Instances: {len(self._instances)}"""
|
|
|
2551
2648
|
parent_body: str = None,
|
|
2552
2649
|
is_template: bool = False,
|
|
2553
2650
|
up_axis: int = 1,
|
|
2651
|
+
color: tuple = None,
|
|
2554
2652
|
):
|
|
2555
2653
|
"""Add a cone for visualization
|
|
2556
2654
|
|
|
@@ -2560,6 +2658,7 @@ Instances: {len(self._instances)}"""
|
|
|
2560
2658
|
half_height: The half height of the cone
|
|
2561
2659
|
name: A name for the USD prim on the stage
|
|
2562
2660
|
up_axis: The axis of the cone that points up (0: x, 1: y, 2: z)
|
|
2661
|
+
color: The color of the cone
|
|
2563
2662
|
"""
|
|
2564
2663
|
geo_hash = hash(("cone", radius, half_height))
|
|
2565
2664
|
if geo_hash in self._shape_geo_hash:
|
|
@@ -2568,14 +2667,14 @@ Instances: {len(self._instances)}"""
|
|
|
2568
2667
|
return shape
|
|
2569
2668
|
else:
|
|
2570
2669
|
vertices, indices = self._create_cone_mesh(radius, half_height, up_axis=up_axis)
|
|
2571
|
-
shape = self.register_shape(geo_hash, vertices, indices)
|
|
2670
|
+
shape = self.register_shape(geo_hash, vertices, indices, color1=color, color2=color)
|
|
2572
2671
|
if not is_template:
|
|
2573
2672
|
body = self._resolve_body_id(parent_body)
|
|
2574
2673
|
self.add_shape_instance(name, shape, body, pos, rot)
|
|
2575
2674
|
return shape
|
|
2576
2675
|
|
|
2577
2676
|
def render_box(
|
|
2578
|
-
self, name: str, pos: tuple, rot: tuple, extents: tuple, parent_body: str = None, is_template: bool = False
|
|
2677
|
+
self, name: str, pos: tuple, rot: tuple, extents: tuple, parent_body: str = None, is_template: bool = False, color: tuple = None
|
|
2579
2678
|
):
|
|
2580
2679
|
"""Add a box for visualization
|
|
2581
2680
|
|
|
@@ -2583,6 +2682,7 @@ Instances: {len(self._instances)}"""
|
|
|
2583
2682
|
pos: The position of the box
|
|
2584
2683
|
extents: The extents of the box
|
|
2585
2684
|
name: A name for the USD prim on the stage
|
|
2685
|
+
color: The color of the box
|
|
2586
2686
|
"""
|
|
2587
2687
|
geo_hash = hash(("box", tuple(extents)))
|
|
2588
2688
|
if geo_hash in self._shape_geo_hash:
|
|
@@ -2591,7 +2691,7 @@ Instances: {len(self._instances)}"""
|
|
|
2591
2691
|
return shape
|
|
2592
2692
|
else:
|
|
2593
2693
|
vertices, indices = self._create_box_mesh(extents)
|
|
2594
|
-
shape = self.register_shape(geo_hash, vertices, indices)
|
|
2694
|
+
shape = self.register_shape(geo_hash, vertices, indices, color1=color, color2=color)
|
|
2595
2695
|
if not is_template:
|
|
2596
2696
|
body = self._resolve_body_id(parent_body)
|
|
2597
2697
|
self.add_shape_instance(name, shape, body, pos, rot)
|
|
@@ -2792,6 +2892,7 @@ Instances: {len(self._instances)}"""
|
|
|
2792
2892
|
instancer = self._shape_instancers[name]
|
|
2793
2893
|
if len(lines) != instancer.num_instances:
|
|
2794
2894
|
instancer.allocate_instances(np.zeros((len(lines), 3)))
|
|
2895
|
+
instancer.update_colors(color, color)
|
|
2795
2896
|
|
|
2796
2897
|
lines_wp = wp.array(lines, dtype=wp.vec3, ndim=2, device=self._device)
|
|
2797
2898
|
with instancer:
|