warp-lang 0.10.1__py3-none-win_amd64.whl → 0.11.0__py3-none-win_amd64.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 +10 -4
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +5 -3
- warp/build_dll.py +29 -9
- warp/builtins.py +868 -507
- warp/codegen.py +1074 -638
- warp/config.py +3 -3
- warp/constants.py +6 -0
- warp/context.py +715 -222
- warp/fabric.py +326 -0
- warp/fem/__init__.py +27 -0
- warp/fem/cache.py +389 -0
- warp/fem/dirichlet.py +181 -0
- warp/fem/domain.py +263 -0
- warp/fem/field/__init__.py +101 -0
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +299 -0
- warp/fem/field/restriction.py +21 -0
- warp/fem/field/test.py +181 -0
- warp/fem/field/trial.py +183 -0
- warp/fem/geometry/__init__.py +19 -0
- warp/fem/geometry/closest_point.py +70 -0
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +744 -0
- warp/fem/geometry/geometry.py +186 -0
- warp/fem/geometry/grid_2d.py +373 -0
- warp/fem/geometry/grid_3d.py +435 -0
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +376 -0
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +840 -0
- warp/fem/geometry/trimesh_2d.py +577 -0
- warp/fem/integrate.py +1616 -0
- warp/fem/operator.py +191 -0
- warp/fem/polynomial.py +213 -0
- warp/fem/quadrature/__init__.py +2 -0
- warp/fem/quadrature/pic_quadrature.py +245 -0
- warp/fem/quadrature/quadrature.py +294 -0
- warp/fem/space/__init__.py +292 -0
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +236 -0
- warp/fem/space/function_space.py +145 -0
- warp/fem/space/grid_2d_function_space.py +267 -0
- warp/fem/space/grid_3d_function_space.py +306 -0
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +350 -0
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +160 -0
- warp/fem/space/shape/__init__.py +15 -0
- warp/fem/space/shape/cube_shape_function.py +738 -0
- warp/fem/space/shape/shape_function.py +103 -0
- warp/fem/space/shape/square_shape_function.py +611 -0
- warp/fem/space/shape/tet_shape_function.py +567 -0
- warp/fem/space/shape/triangle_shape_function.py +429 -0
- warp/fem/space/tetmesh_function_space.py +292 -0
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +221 -0
- warp/fem/types.py +77 -0
- warp/fem/utils.py +495 -0
- warp/native/array.h +147 -44
- warp/native/builtin.h +122 -149
- warp/native/bvh.cpp +73 -325
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +34 -43
- warp/native/clang/clang.cpp +13 -8
- warp/native/crt.h +2 -0
- warp/native/cuda_crt.h +5 -0
- warp/native/cuda_util.cpp +15 -3
- warp/native/cuda_util.h +3 -1
- warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
- warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
- warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
- warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
- warp/native/cutlass/tools/library/scripts/library.py +799 -0
- warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
- warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
- warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
- warp/native/cutlass/tools/library/scripts/rt.py +796 -0
- warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
- warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
- warp/native/cutlass_gemm.cu +5 -3
- warp/native/exports.h +1240 -952
- warp/native/fabric.h +228 -0
- warp/native/hashgrid.cpp +4 -4
- warp/native/hashgrid.h +22 -2
- warp/native/intersect.h +22 -7
- warp/native/intersect_adj.h +8 -8
- warp/native/intersect_tri.h +1 -1
- warp/native/marching.cu +157 -161
- warp/native/mat.h +80 -19
- warp/native/matnn.h +2 -2
- warp/native/mesh.cpp +33 -108
- warp/native/mesh.cu +114 -23
- warp/native/mesh.h +446 -46
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +45 -35
- warp/native/range.h +6 -2
- warp/native/reduce.cpp +1 -1
- warp/native/reduce.cu +10 -12
- warp/native/runlength_encode.cu +6 -10
- warp/native/scan.cu +8 -11
- warp/native/sparse.cpp +4 -4
- warp/native/sparse.cu +164 -154
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +14 -30
- warp/native/vec.h +107 -23
- warp/native/volume.h +120 -0
- warp/native/warp.cpp +560 -30
- warp/native/warp.cu +431 -44
- warp/native/warp.h +13 -4
- warp/optim/__init__.py +1 -0
- warp/optim/linear.py +922 -0
- warp/optim/sgd.py +92 -0
- warp/render/render_opengl.py +335 -119
- warp/render/render_usd.py +11 -11
- warp/sim/__init__.py +2 -2
- warp/sim/articulation.py +385 -185
- warp/sim/collide.py +8 -0
- warp/sim/import_mjcf.py +297 -106
- warp/sim/import_urdf.py +389 -210
- warp/sim/import_usd.py +198 -97
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_euler.py +14 -8
- warp/sim/integrator_xpbd.py +158 -16
- warp/sim/model.py +795 -291
- warp/sim/render.py +3 -3
- warp/sim/utils.py +3 -0
- warp/sparse.py +640 -150
- warp/stubs.py +606 -267
- warp/tape.py +61 -10
- warp/tests/__main__.py +3 -6
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/disabled_kinematics.py +239 -0
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +103 -106
- warp/tests/test_arithmetic.py +128 -74
- warp/tests/test_array.py +212 -97
- warp/tests/test_array_reduce.py +57 -23
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +99 -0
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +42 -18
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +208 -130
- warp/tests/test_compile_consts.py +28 -20
- warp/tests/test_conditional.py +108 -24
- warp/tests/test_copy.py +10 -12
- warp/tests/test_ctypes.py +112 -88
- warp/tests/test_dense.py +21 -14
- warp/tests/test_devices.py +98 -0
- warp/tests/test_dlpack.py +75 -75
- warp/tests/test_examples.py +277 -0
- warp/tests/test_fabricarray.py +955 -0
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1271 -0
- warp/tests/test_fp16.py +53 -19
- warp/tests/test_func.py +187 -86
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +178 -109
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +52 -37
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +32 -31
- warp/tests/test_intersect.py +18 -9
- warp/tests/test_large.py +141 -0
- warp/tests/test_launch.py +14 -41
- warp/tests/test_lerp.py +64 -65
- warp/tests/test_linear_solvers.py +154 -0
- warp/tests/test_lvalue.py +493 -0
- warp/tests/test_marching_cubes.py +12 -13
- warp/tests/test_mat.py +517 -2898
- warp/tests/test_mat_lite.py +115 -0
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +103 -9
- warp/tests/test_matmul.py +305 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +71 -14
- warp/tests/test_mesh_query_aabb.py +41 -25
- warp/tests/test_mesh_query_point.py +140 -22
- warp/tests/test_mesh_query_ray.py +39 -22
- warp/tests/test_mlp.py +30 -22
- warp/tests/test_model.py +92 -89
- warp/tests/test_modules_lite.py +39 -0
- warp/tests/test_multigpu.py +88 -114
- warp/tests/test_noise.py +12 -11
- warp/tests/test_operators.py +16 -20
- warp/tests/test_options.py +11 -11
- warp/tests/test_pinned.py +17 -18
- warp/tests/test_print.py +32 -11
- warp/tests/test_quat.py +275 -129
- warp/tests/test_rand.py +18 -16
- warp/tests/test_reload.py +38 -34
- warp/tests/test_rounding.py +50 -43
- warp/tests/test_runlength_encode.py +168 -20
- warp/tests/test_smoothstep.py +9 -11
- warp/tests/test_snippet.py +143 -0
- warp/tests/test_sparse.py +261 -63
- warp/tests/test_spatial.py +276 -243
- warp/tests/test_streams.py +110 -85
- warp/tests/test_struct.py +268 -63
- warp/tests/test_tape.py +39 -21
- warp/tests/test_torch.py +118 -89
- warp/tests/test_transient_module.py +12 -13
- warp/tests/test_types.py +614 -0
- warp/tests/test_utils.py +494 -0
- warp/tests/test_vec.py +354 -2050
- warp/tests/test_vec_lite.py +73 -0
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +457 -293
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +341 -0
- warp/tests/unittest_utils.py +568 -0
- warp/tests/unused_test_misc.py +71 -0
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +549 -0
- warp/torch.py +9 -6
- warp/types.py +1089 -366
- warp/utils.py +93 -387
- warp_lang-0.11.0.dist-info/METADATA +238 -0
- warp_lang-0.11.0.dist-info/RECORD +332 -0
- {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
- warp/tests/test_all.py +0 -219
- warp/tests/test_array_scan.py +0 -60
- warp/tests/test_base.py +0 -208
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- warp_lang-0.10.1.dist-info/METADATA +0 -21
- warp_lang-0.10.1.dist-info/RECORD +0 -188
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
warp/render/render_opengl.py
CHANGED
|
@@ -13,12 +13,14 @@ from .utils import tab10_color_map
|
|
|
13
13
|
|
|
14
14
|
from collections import defaultdict
|
|
15
15
|
from typing import List, Tuple, Union, Optional
|
|
16
|
+
from enum import Enum
|
|
16
17
|
|
|
17
18
|
import numpy as np
|
|
18
19
|
import ctypes
|
|
19
20
|
|
|
20
21
|
Mat44 = Union[List[float], List[List[float]], np.ndarray]
|
|
21
22
|
|
|
23
|
+
|
|
22
24
|
wp.set_module_options({"enable_backward": False})
|
|
23
25
|
|
|
24
26
|
shape_vertex_shader = """
|
|
@@ -175,12 +177,13 @@ in vec2 TexCoord;
|
|
|
175
177
|
|
|
176
178
|
uniform vec3 color1;
|
|
177
179
|
uniform vec3 color2;
|
|
180
|
+
uniform float farPlane;
|
|
178
181
|
|
|
179
182
|
uniform vec3 sunDirection;
|
|
180
183
|
|
|
181
184
|
void main()
|
|
182
185
|
{
|
|
183
|
-
float y = tanh(FragPos.y*0
|
|
186
|
+
float y = tanh(FragPos.y/farPlane*10.0)*0.5+0.5;
|
|
184
187
|
float height = sqrt(1.0-y);
|
|
185
188
|
|
|
186
189
|
float s = pow(0.5, 1.0 / 10.0);
|
|
@@ -222,6 +225,42 @@ void main() {
|
|
|
222
225
|
}
|
|
223
226
|
"""
|
|
224
227
|
|
|
228
|
+
frame_depth_fragment_shader = """
|
|
229
|
+
#version 330 core
|
|
230
|
+
in vec2 TexCoord;
|
|
231
|
+
|
|
232
|
+
out vec4 FragColor;
|
|
233
|
+
|
|
234
|
+
uniform sampler2D textureSampler;
|
|
235
|
+
|
|
236
|
+
vec3 bourkeColorMap(float v) {
|
|
237
|
+
vec3 c = vec3(1.0, 1.0, 1.0);
|
|
238
|
+
|
|
239
|
+
v = clamp(v, 0.0, 1.0); // Ensures v is between 0 and 1
|
|
240
|
+
|
|
241
|
+
if (v < 0.25) {
|
|
242
|
+
c.r = 0.0;
|
|
243
|
+
c.g = 4.0 * v;
|
|
244
|
+
} else if (v < 0.5) {
|
|
245
|
+
c.r = 0.0;
|
|
246
|
+
c.b = 1.0 + 4.0 * (0.25 - v);
|
|
247
|
+
} else if (v < 0.75) {
|
|
248
|
+
c.r = 4.0 * (v - 0.5);
|
|
249
|
+
c.b = 0.0;
|
|
250
|
+
} else {
|
|
251
|
+
c.g = 1.0 + 4.0 * (0.75 - v);
|
|
252
|
+
c.b = 0.0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return c;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
void main() {
|
|
259
|
+
float depth = texture(textureSampler, TexCoord).r;
|
|
260
|
+
FragColor = vec4(bourkeColorMap(sqrt(1.0 - depth)), 1.0);
|
|
261
|
+
}
|
|
262
|
+
"""
|
|
263
|
+
|
|
225
264
|
|
|
226
265
|
@wp.kernel
|
|
227
266
|
def update_vbo_transforms(
|
|
@@ -411,7 +450,7 @@ def assemble_gfx_vertices(
|
|
|
411
450
|
|
|
412
451
|
|
|
413
452
|
@wp.kernel
|
|
414
|
-
def
|
|
453
|
+
def copy_rgb_frame(
|
|
415
454
|
input_img: wp.array(dtype=wp.uint8),
|
|
416
455
|
width: int,
|
|
417
456
|
height: int,
|
|
@@ -432,7 +471,26 @@ def copy_frame(
|
|
|
432
471
|
|
|
433
472
|
|
|
434
473
|
@wp.kernel
|
|
435
|
-
def
|
|
474
|
+
def copy_depth_frame(
|
|
475
|
+
input_img: wp.array(dtype=wp.float32),
|
|
476
|
+
width: int,
|
|
477
|
+
height: int,
|
|
478
|
+
near: float,
|
|
479
|
+
far: float,
|
|
480
|
+
# outputs
|
|
481
|
+
output_img: wp.array(dtype=wp.float32, ndim=3),
|
|
482
|
+
):
|
|
483
|
+
w, v = wp.tid()
|
|
484
|
+
pixel = v * width + w
|
|
485
|
+
# flip vertically (OpenGL coordinates start at bottom)
|
|
486
|
+
v = height - v - 1
|
|
487
|
+
d = 2.0 * input_img[pixel] - 1.0
|
|
488
|
+
d = 2.0 * near * far / ((far - near) * d - near - far)
|
|
489
|
+
output_img[v, w, 0] = -d
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
@wp.kernel
|
|
493
|
+
def copy_rgb_frame_tiles(
|
|
436
494
|
input_img: wp.array(dtype=wp.uint8),
|
|
437
495
|
positions: wp.array(dtype=int, ndim=2),
|
|
438
496
|
screen_width: int,
|
|
@@ -463,7 +521,34 @@ def copy_frame_tiles(
|
|
|
463
521
|
|
|
464
522
|
|
|
465
523
|
@wp.kernel
|
|
466
|
-
def
|
|
524
|
+
def copy_depth_frame_tiles(
|
|
525
|
+
input_img: wp.array(dtype=wp.float32),
|
|
526
|
+
positions: wp.array(dtype=int, ndim=2),
|
|
527
|
+
screen_width: int,
|
|
528
|
+
screen_height: int,
|
|
529
|
+
tile_height: int,
|
|
530
|
+
near: float,
|
|
531
|
+
far: float,
|
|
532
|
+
# outputs
|
|
533
|
+
output_img: wp.array(dtype=wp.float32, ndim=4),
|
|
534
|
+
):
|
|
535
|
+
tile, x, y = wp.tid()
|
|
536
|
+
p = positions[tile]
|
|
537
|
+
qx = x + p[0]
|
|
538
|
+
qy = y + p[1]
|
|
539
|
+
pixel = qy * screen_width + qx
|
|
540
|
+
# flip vertically (OpenGL coordinates start at bottom)
|
|
541
|
+
y = tile_height - y - 1
|
|
542
|
+
if qx >= screen_width or qy >= screen_height:
|
|
543
|
+
output_img[tile, y, x, 0] = far
|
|
544
|
+
return # prevent out-of-bounds access
|
|
545
|
+
d = 2.0 * input_img[pixel] - 1.0
|
|
546
|
+
d = 2.0 * near * far / ((far - near) * d - near - far)
|
|
547
|
+
output_img[tile, y, x, 0] = -d
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
@wp.kernel
|
|
551
|
+
def copy_rgb_frame_tile(
|
|
467
552
|
input_img: wp.array(dtype=wp.uint8),
|
|
468
553
|
offset_x: int,
|
|
469
554
|
offset_y: int,
|
|
@@ -765,22 +850,28 @@ class OpenGLRenderer:
|
|
|
765
850
|
title="Warp sim",
|
|
766
851
|
scaling=1.0,
|
|
767
852
|
fps=60,
|
|
768
|
-
up_axis="
|
|
853
|
+
up_axis="Y",
|
|
769
854
|
screen_width=1024,
|
|
770
855
|
screen_height=768,
|
|
771
|
-
near_plane=0
|
|
772
|
-
far_plane=
|
|
856
|
+
near_plane=1.0,
|
|
857
|
+
far_plane=100.0,
|
|
773
858
|
camera_fov=45.0,
|
|
859
|
+
camera_pos=(0.0, 2.0, 10.0),
|
|
860
|
+
camera_front=(0.0, 0.0, -1.0),
|
|
861
|
+
camera_up=(0.0, 1.0, 0.0),
|
|
774
862
|
background_color=(0.53, 0.8, 0.92),
|
|
775
863
|
draw_grid=True,
|
|
776
864
|
draw_sky=True,
|
|
777
865
|
draw_axis=True,
|
|
778
866
|
show_info=True,
|
|
779
867
|
render_wireframe=False,
|
|
868
|
+
render_depth=False,
|
|
780
869
|
axis_scale=1.0,
|
|
781
870
|
vsync=False,
|
|
782
871
|
headless=False,
|
|
783
872
|
enable_backface_culling=True,
|
|
873
|
+
enable_mouse_interaction=True,
|
|
874
|
+
enable_keyboard_interaction=True,
|
|
784
875
|
):
|
|
785
876
|
try:
|
|
786
877
|
import pyglet
|
|
@@ -804,6 +895,7 @@ class OpenGLRenderer:
|
|
|
804
895
|
self.draw_axis = draw_axis
|
|
805
896
|
self.show_info = show_info
|
|
806
897
|
self.render_wireframe = render_wireframe
|
|
898
|
+
self.render_depth = render_depth
|
|
807
899
|
self.enable_backface_culling = enable_backface_culling
|
|
808
900
|
|
|
809
901
|
self._device = wp.get_cuda_device()
|
|
@@ -819,19 +911,26 @@ class OpenGLRenderer:
|
|
|
819
911
|
|
|
820
912
|
self.screen_width, self.screen_height = self.window.get_framebuffer_size()
|
|
821
913
|
|
|
822
|
-
self.
|
|
823
|
-
self.
|
|
824
|
-
|
|
914
|
+
self.enable_mouse_interaction = enable_mouse_interaction
|
|
915
|
+
self.enable_keyboard_interaction = enable_keyboard_interaction
|
|
916
|
+
|
|
917
|
+
self._camera_pos = PyVec3(*camera_pos)
|
|
918
|
+
self._camera_front = PyVec3(*camera_front)
|
|
919
|
+
self._camera_up = PyVec3(*camera_up)
|
|
825
920
|
self._camera_speed = 0.04
|
|
826
921
|
if isinstance(up_axis, int):
|
|
827
922
|
self._camera_axis = up_axis
|
|
828
923
|
else:
|
|
829
|
-
self._camera_axis = "
|
|
924
|
+
self._camera_axis = "XYZ".index(up_axis.upper())
|
|
830
925
|
self._yaw, self._pitch = -90.0, 0.0
|
|
831
926
|
self._last_x, self._last_y = self.screen_width // 2, self.screen_height // 2
|
|
832
927
|
self._first_mouse = True
|
|
833
928
|
self._left_mouse_pressed = False
|
|
834
929
|
self._keys_pressed = defaultdict(bool)
|
|
930
|
+
self._key_callbacks = []
|
|
931
|
+
|
|
932
|
+
self.render_2d_callbacks = []
|
|
933
|
+
self.render_3d_callbacks = []
|
|
835
934
|
|
|
836
935
|
self.update_view_matrix()
|
|
837
936
|
self.update_projection_matrix()
|
|
@@ -854,6 +953,7 @@ class OpenGLRenderer:
|
|
|
854
953
|
self._shape_gl_buffers = {}
|
|
855
954
|
self._shape_instances = defaultdict(list)
|
|
856
955
|
self._instances = {}
|
|
956
|
+
self._instance_custom_ids = {}
|
|
857
957
|
self._instance_shape = {}
|
|
858
958
|
self._instance_gl_buffers = {}
|
|
859
959
|
self._instance_transform_gl_buffer = None
|
|
@@ -862,6 +962,8 @@ class OpenGLRenderer:
|
|
|
862
962
|
self._instance_color2_buffer = None
|
|
863
963
|
self._instance_count = 0
|
|
864
964
|
self._wp_instance_ids = None
|
|
965
|
+
self._wp_instance_custom_ids = None
|
|
966
|
+
self._np_instance_visible = None
|
|
865
967
|
self._instance_ids = None
|
|
866
968
|
self._inverse_instance_ids = None
|
|
867
969
|
self._wp_instance_transforms = None
|
|
@@ -888,6 +990,7 @@ class OpenGLRenderer:
|
|
|
888
990
|
self._tile_projection_matrices = None
|
|
889
991
|
|
|
890
992
|
self._frame_texture = None
|
|
993
|
+
self._frame_depth_texture = None
|
|
891
994
|
self._frame_fbo = None
|
|
892
995
|
self._frame_pbo = None
|
|
893
996
|
|
|
@@ -903,6 +1006,8 @@ class OpenGLRenderer:
|
|
|
903
1006
|
|
|
904
1007
|
gl.glClearColor(*self.background_color, 1)
|
|
905
1008
|
gl.glEnable(gl.GL_DEPTH_TEST)
|
|
1009
|
+
gl.glDepthMask(True)
|
|
1010
|
+
gl.glDepthRange(0.0, 1.0)
|
|
906
1011
|
|
|
907
1012
|
self._shape_shader = ShaderProgram(
|
|
908
1013
|
Shader(shape_vertex_shader, "vertex"), Shader(shape_fragment_shader, "fragment")
|
|
@@ -969,15 +1074,17 @@ class OpenGLRenderer:
|
|
|
969
1074
|
|
|
970
1075
|
self._loc_sky_color1 = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("color1"))
|
|
971
1076
|
self._loc_sky_color2 = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("color2"))
|
|
1077
|
+
self._loc_sky_far_plane = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("farPlane"))
|
|
972
1078
|
gl.glUniform3f(self._loc_sky_color1, *background_color)
|
|
973
1079
|
# glUniform3f(self._loc_sky_color2, *np.clip(np.array(background_color)+0.5, 0.0, 1.0))
|
|
974
1080
|
gl.glUniform3f(self._loc_sky_color2, 0.8, 0.4, 0.05)
|
|
1081
|
+
gl.glUniform1f(self._loc_sky_far_plane, self.camera_far_plane)
|
|
975
1082
|
self._loc_sky_view_pos = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("viewPos"))
|
|
976
1083
|
gl.glUniform3f(
|
|
977
1084
|
gl.glGetUniformLocation(self._sky_shader.id, str_buffer("sunDirection")), *self._sun_direction
|
|
978
1085
|
)
|
|
979
1086
|
|
|
980
|
-
#
|
|
1087
|
+
# create VAO, VBO, and EBO
|
|
981
1088
|
self._sky_vao = gl.GLuint()
|
|
982
1089
|
gl.glGenVertexArrays(1, self._sky_vao)
|
|
983
1090
|
gl.glBindVertexArray(self._sky_vao)
|
|
@@ -995,7 +1102,7 @@ class OpenGLRenderer:
|
|
|
995
1102
|
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._sky_ebo)
|
|
996
1103
|
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices.ctypes.data, gl.GL_STATIC_DRAW)
|
|
997
1104
|
|
|
998
|
-
#
|
|
1105
|
+
# set up vertex attributes
|
|
999
1106
|
vertex_stride = vertices.shape[1] * vertices.itemsize
|
|
1000
1107
|
# positions
|
|
1001
1108
|
gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, vertex_stride, ctypes.c_void_p(0))
|
|
@@ -1029,6 +1136,7 @@ class OpenGLRenderer:
|
|
|
1029
1136
|
|
|
1030
1137
|
# create frame buffer for rendering to a texture
|
|
1031
1138
|
self._frame_texture = None
|
|
1139
|
+
self._frame_depth_texture = None
|
|
1032
1140
|
self._frame_fbo = None
|
|
1033
1141
|
self._setup_framebuffer()
|
|
1034
1142
|
|
|
@@ -1076,7 +1184,15 @@ class OpenGLRenderer:
|
|
|
1076
1184
|
gl.glUseProgram(self._frame_shader.id)
|
|
1077
1185
|
self._frame_loc_texture = gl.glGetUniformLocation(self._frame_shader.id, str_buffer("textureSampler"))
|
|
1078
1186
|
|
|
1079
|
-
|
|
1187
|
+
self._frame_depth_shader = ShaderProgram(
|
|
1188
|
+
Shader(frame_vertex_shader, "vertex"), Shader(frame_depth_fragment_shader, "fragment")
|
|
1189
|
+
)
|
|
1190
|
+
gl.glUseProgram(self._frame_depth_shader.id)
|
|
1191
|
+
self._frame_loc_depth_texture = gl.glGetUniformLocation(
|
|
1192
|
+
self._frame_depth_shader.id, str_buffer("textureSampler")
|
|
1193
|
+
)
|
|
1194
|
+
|
|
1195
|
+
# unbind the VBO and VAO
|
|
1080
1196
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
|
|
1081
1197
|
gl.glBindVertexArray(0)
|
|
1082
1198
|
|
|
@@ -1164,11 +1280,17 @@ class OpenGLRenderer:
|
|
|
1164
1280
|
self._instance_color1_buffer = None
|
|
1165
1281
|
self._instance_color2_buffer = None
|
|
1166
1282
|
self._wp_instance_ids = None
|
|
1283
|
+
self._wp_instance_custom_ids = None
|
|
1167
1284
|
self._wp_instance_transforms = None
|
|
1168
1285
|
self._wp_instance_scalings = None
|
|
1169
1286
|
self._wp_instance_bodies = None
|
|
1287
|
+
self._np_instance_visible = None
|
|
1170
1288
|
self._update_shape_instances = False
|
|
1171
1289
|
|
|
1290
|
+
def close(self):
|
|
1291
|
+
self.clear()
|
|
1292
|
+
self.window.close()
|
|
1293
|
+
|
|
1172
1294
|
@property
|
|
1173
1295
|
def tiled_rendering(self):
|
|
1174
1296
|
return self._tiled_rendering
|
|
@@ -1322,7 +1444,11 @@ class OpenGLRenderer:
|
|
|
1322
1444
|
if self._frame_texture is None:
|
|
1323
1445
|
self._frame_texture = gl.GLuint()
|
|
1324
1446
|
gl.glGenTextures(1, self._frame_texture)
|
|
1447
|
+
if self._frame_depth_texture is None:
|
|
1448
|
+
self._frame_depth_texture = gl.GLuint()
|
|
1449
|
+
gl.glGenTextures(1, self._frame_depth_texture)
|
|
1325
1450
|
|
|
1451
|
+
# set up RGB texture
|
|
1326
1452
|
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
|
|
1327
1453
|
gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0)
|
|
1328
1454
|
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
|
|
@@ -1339,6 +1465,22 @@ class OpenGLRenderer:
|
|
|
1339
1465
|
)
|
|
1340
1466
|
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
|
|
1341
1467
|
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
|
|
1468
|
+
|
|
1469
|
+
# set up depth texture
|
|
1470
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_depth_texture)
|
|
1471
|
+
gl.glTexImage2D(
|
|
1472
|
+
gl.GL_TEXTURE_2D,
|
|
1473
|
+
0,
|
|
1474
|
+
gl.GL_DEPTH_COMPONENT32,
|
|
1475
|
+
self.screen_width,
|
|
1476
|
+
self.screen_height,
|
|
1477
|
+
0,
|
|
1478
|
+
gl.GL_DEPTH_COMPONENT,
|
|
1479
|
+
gl.GL_FLOAT,
|
|
1480
|
+
None,
|
|
1481
|
+
)
|
|
1482
|
+
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
|
|
1483
|
+
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
|
|
1342
1484
|
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
1343
1485
|
|
|
1344
1486
|
# create a framebuffer object (FBO)
|
|
@@ -1351,15 +1493,9 @@ class OpenGLRenderer:
|
|
|
1351
1493
|
gl.glFramebufferTexture2D(
|
|
1352
1494
|
gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self._frame_texture, 0
|
|
1353
1495
|
)
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self._frame_depth_renderbuffer)
|
|
1358
|
-
gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, self.screen_width, self.screen_height)
|
|
1359
|
-
|
|
1360
|
-
# attach the depth renderbuffer to the FBO
|
|
1361
|
-
gl.glFramebufferRenderbuffer(
|
|
1362
|
-
gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, self._frame_depth_renderbuffer
|
|
1496
|
+
# attach the depth texture to the FBO as its depth attachment
|
|
1497
|
+
gl.glFramebufferTexture2D(
|
|
1498
|
+
gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_TEXTURE_2D, self._frame_depth_texture, 0
|
|
1363
1499
|
)
|
|
1364
1500
|
|
|
1365
1501
|
if gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE:
|
|
@@ -1367,13 +1503,6 @@ class OpenGLRenderer:
|
|
|
1367
1503
|
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
|
|
1368
1504
|
sys.exit(1)
|
|
1369
1505
|
|
|
1370
|
-
gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, 0)
|
|
1371
|
-
else:
|
|
1372
|
-
# rescale framebuffer
|
|
1373
|
-
gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self._frame_depth_renderbuffer)
|
|
1374
|
-
gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, self.screen_width, self.screen_height)
|
|
1375
|
-
gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, 0)
|
|
1376
|
-
|
|
1377
1506
|
# unbind the FBO (switch back to the default framebuffer)
|
|
1378
1507
|
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
|
|
1379
1508
|
|
|
@@ -1383,7 +1512,11 @@ class OpenGLRenderer:
|
|
|
1383
1512
|
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, self._frame_pbo) # binding to this buffer
|
|
1384
1513
|
|
|
1385
1514
|
# allocate memory for PBO
|
|
1386
|
-
|
|
1515
|
+
rgb_bytes_per_pixel = 3
|
|
1516
|
+
depth_bytes_per_pixel = 4
|
|
1517
|
+
pixels = np.zeros(
|
|
1518
|
+
(self.screen_height, self.screen_width, rgb_bytes_per_pixel + depth_bytes_per_pixel), dtype=np.uint8
|
|
1519
|
+
)
|
|
1387
1520
|
gl.glBufferData(gl.GL_PIXEL_PACK_BUFFER, pixels.nbytes, pixels.ctypes.data, gl.GL_DYNAMIC_DRAW)
|
|
1388
1521
|
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
|
|
1389
1522
|
|
|
@@ -1542,7 +1675,6 @@ class OpenGLRenderer:
|
|
|
1542
1675
|
|
|
1543
1676
|
if self._frame_fbo is not None:
|
|
1544
1677
|
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._frame_fbo)
|
|
1545
|
-
gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, self._frame_fbo)
|
|
1546
1678
|
|
|
1547
1679
|
gl.glClearColor(*self.background_color, 1)
|
|
1548
1680
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
|
|
@@ -1571,6 +1703,9 @@ class OpenGLRenderer:
|
|
|
1571
1703
|
else:
|
|
1572
1704
|
self._render_scene()
|
|
1573
1705
|
|
|
1706
|
+
for cb in self.render_3d_callbacks:
|
|
1707
|
+
cb()
|
|
1708
|
+
|
|
1574
1709
|
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
|
|
1575
1710
|
|
|
1576
1711
|
gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0)
|
|
@@ -1580,15 +1715,26 @@ class OpenGLRenderer:
|
|
|
1580
1715
|
|
|
1581
1716
|
# render frame buffer texture to screen
|
|
1582
1717
|
if self._frame_fbo is not None:
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1718
|
+
if self.render_depth:
|
|
1719
|
+
with self._frame_depth_shader:
|
|
1720
|
+
gl.glActiveTexture(gl.GL_TEXTURE0)
|
|
1721
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_depth_texture)
|
|
1722
|
+
gl.glUniform1i(self._frame_loc_depth_texture, 0)
|
|
1723
|
+
|
|
1724
|
+
gl.glBindVertexArray(self._frame_vao)
|
|
1725
|
+
gl.glDrawElements(gl.GL_TRIANGLES, len(self._frame_indices), gl.GL_UNSIGNED_INT, None)
|
|
1726
|
+
gl.glBindVertexArray(0)
|
|
1727
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
1728
|
+
else:
|
|
1729
|
+
with self._frame_shader:
|
|
1730
|
+
gl.glActiveTexture(gl.GL_TEXTURE0)
|
|
1731
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
|
|
1732
|
+
gl.glUniform1i(self._frame_loc_texture, 0)
|
|
1587
1733
|
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1734
|
+
gl.glBindVertexArray(self._frame_vao)
|
|
1735
|
+
gl.glDrawElements(gl.GL_TRIANGLES, len(self._frame_indices), gl.GL_UNSIGNED_INT, None)
|
|
1736
|
+
gl.glBindVertexArray(0)
|
|
1737
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
1592
1738
|
|
|
1593
1739
|
# check for OpenGL errors
|
|
1594
1740
|
# check_gl_error()
|
|
@@ -1611,6 +1757,9 @@ Instances: {len(self._instances)}"""
|
|
|
1611
1757
|
self._info_label.y = self.screen_height - 5
|
|
1612
1758
|
self._info_label.draw()
|
|
1613
1759
|
|
|
1760
|
+
for cb in self.render_2d_callbacks:
|
|
1761
|
+
cb()
|
|
1762
|
+
|
|
1614
1763
|
def _draw_grid(self, is_tiled=False):
|
|
1615
1764
|
from pyglet import gl
|
|
1616
1765
|
|
|
@@ -1708,6 +1857,9 @@ Instances: {len(self._instances)}"""
|
|
|
1708
1857
|
gl.glBindVertexArray(0)
|
|
1709
1858
|
|
|
1710
1859
|
def _mouse_drag_callback(self, x, y, dx, dy, buttons, modifiers):
|
|
1860
|
+
if not self.enable_mouse_interaction:
|
|
1861
|
+
return
|
|
1862
|
+
|
|
1711
1863
|
import pyglet
|
|
1712
1864
|
|
|
1713
1865
|
if buttons & pyglet.window.mouse.LEFT:
|
|
@@ -1727,6 +1879,9 @@ Instances: {len(self._instances)}"""
|
|
|
1727
1879
|
self.update_view_matrix()
|
|
1728
1880
|
|
|
1729
1881
|
def _scroll_callback(self, x, y, scroll_x, scroll_y):
|
|
1882
|
+
if not self.enable_mouse_interaction:
|
|
1883
|
+
return
|
|
1884
|
+
|
|
1730
1885
|
self.camera_fov -= scroll_y
|
|
1731
1886
|
self.camera_fov = max(min(self.camera_fov, 90.0), 15.0)
|
|
1732
1887
|
self.update_projection_matrix()
|
|
@@ -1753,8 +1908,11 @@ Instances: {len(self._instances)}"""
|
|
|
1753
1908
|
def _key_press_callback(self, symbol, modifiers):
|
|
1754
1909
|
import pyglet
|
|
1755
1910
|
|
|
1911
|
+
if not self.enable_keyboard_interaction:
|
|
1912
|
+
return
|
|
1913
|
+
|
|
1756
1914
|
if symbol == pyglet.window.key.ESCAPE:
|
|
1757
|
-
self.
|
|
1915
|
+
self.close()
|
|
1758
1916
|
if symbol == pyglet.window.key.SPACE:
|
|
1759
1917
|
self.paused = not self.paused
|
|
1760
1918
|
if symbol == pyglet.window.key.TAB:
|
|
@@ -1767,9 +1925,17 @@ Instances: {len(self._instances)}"""
|
|
|
1767
1925
|
self.show_info = not self.show_info
|
|
1768
1926
|
if symbol == pyglet.window.key.X:
|
|
1769
1927
|
self.render_wireframe = not self.render_wireframe
|
|
1928
|
+
if symbol == pyglet.window.key.T:
|
|
1929
|
+
self.render_depth = not self.render_depth
|
|
1770
1930
|
if symbol == pyglet.window.key.B:
|
|
1771
1931
|
self.enable_backface_culling = not self.enable_backface_culling
|
|
1772
1932
|
|
|
1933
|
+
for cb in self._key_callbacks:
|
|
1934
|
+
cb(symbol, modifiers)
|
|
1935
|
+
|
|
1936
|
+
def register_key_press_callback(self, callback):
|
|
1937
|
+
self._key_callbacks.append(callback)
|
|
1938
|
+
|
|
1773
1939
|
def _window_resize_callback(self, width, height):
|
|
1774
1940
|
self._first_mouse = True
|
|
1775
1941
|
self.screen_width, self.screen_height = self.window.get_framebuffer_size()
|
|
@@ -1826,7 +1992,17 @@ Instances: {len(self._instances)}"""
|
|
|
1826
1992
|
return shape
|
|
1827
1993
|
|
|
1828
1994
|
def add_shape_instance(
|
|
1829
|
-
self,
|
|
1995
|
+
self,
|
|
1996
|
+
name: str,
|
|
1997
|
+
shape: int,
|
|
1998
|
+
body,
|
|
1999
|
+
pos,
|
|
2000
|
+
rot,
|
|
2001
|
+
scale=(1.0, 1.0, 1.0),
|
|
2002
|
+
color1=None,
|
|
2003
|
+
color2=None,
|
|
2004
|
+
custom_index: int = -1,
|
|
2005
|
+
visible: bool = True,
|
|
1830
2006
|
):
|
|
1831
2007
|
if color1 is None:
|
|
1832
2008
|
color1 = self._shapes[shape][2]
|
|
@@ -1835,8 +2011,9 @@ Instances: {len(self._instances)}"""
|
|
|
1835
2011
|
instance = len(self._instances)
|
|
1836
2012
|
self._shape_instances[shape].append(instance)
|
|
1837
2013
|
body = self._resolve_body_id(body)
|
|
1838
|
-
self._instances[name] = (instance, body, shape, [*pos, *rot], scale, color1, color2)
|
|
2014
|
+
self._instances[name] = (instance, body, shape, [*pos, *rot], scale, color1, color2, visible)
|
|
1839
2015
|
self._instance_shape[instance] = shape
|
|
2016
|
+
self._instance_custom_ids[instance] = custom_index
|
|
1840
2017
|
self._add_shape_instances = True
|
|
1841
2018
|
self._instance_count = len(self._instances)
|
|
1842
2019
|
return instance
|
|
@@ -1861,7 +2038,7 @@ Instances: {len(self._instances)}"""
|
|
|
1861
2038
|
gl.glDeleteBuffers(1, self._instance_color1_buffer)
|
|
1862
2039
|
gl.glDeleteBuffers(1, self._instance_color2_buffer)
|
|
1863
2040
|
|
|
1864
|
-
#
|
|
2041
|
+
# create instance buffer and bind it as an instanced array
|
|
1865
2042
|
self._instance_transform_gl_buffer = gl.GLuint()
|
|
1866
2043
|
gl.glGenBuffers(1, self._instance_transform_gl_buffer)
|
|
1867
2044
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_transform_gl_buffer)
|
|
@@ -1869,7 +2046,7 @@ Instances: {len(self._instances)}"""
|
|
|
1869
2046
|
transforms = np.tile(np.diag(np.ones(4, dtype=np.float32)), (len(self._instances), 1, 1))
|
|
1870
2047
|
gl.glBufferData(gl.GL_ARRAY_BUFFER, transforms.nbytes, transforms.ctypes.data, gl.GL_DYNAMIC_DRAW)
|
|
1871
2048
|
|
|
1872
|
-
#
|
|
2049
|
+
# create CUDA buffer for instance transforms
|
|
1873
2050
|
self._instance_transform_cuda_buffer = wp.RegisteredGLBuffer(
|
|
1874
2051
|
int(self._instance_transform_gl_buffer.value), self._device
|
|
1875
2052
|
)
|
|
@@ -1897,10 +2074,13 @@ Instances: {len(self._instances)}"""
|
|
|
1897
2074
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
|
|
1898
2075
|
gl.glBufferData(gl.GL_ARRAY_BUFFER, colors2.nbytes, colors2.ctypes.data, gl.GL_STATIC_DRAW)
|
|
1899
2076
|
|
|
1900
|
-
#
|
|
2077
|
+
# set up instance attribute pointers
|
|
1901
2078
|
matrix_size = transforms[0].nbytes
|
|
1902
2079
|
|
|
1903
2080
|
instance_ids = []
|
|
2081
|
+
instance_custom_ids = []
|
|
2082
|
+
instance_visible = []
|
|
2083
|
+
instances = list(self._instances.values())
|
|
1904
2084
|
inverse_instance_ids = {}
|
|
1905
2085
|
instance_count = 0
|
|
1906
2086
|
for shape, (vao, vbo, ebo, tri_count, vertex_cuda_buffer) in self._shape_gl_buffers.items():
|
|
@@ -1930,27 +2110,45 @@ Instances: {len(self._instances)}"""
|
|
|
1930
2110
|
for i in self._shape_instances[shape]:
|
|
1931
2111
|
inverse_instance_ids[i] = instance_count
|
|
1932
2112
|
instance_count += 1
|
|
2113
|
+
instance_custom_ids.append(self._instance_custom_ids[i])
|
|
2114
|
+
instance_visible.append(instances[i][7])
|
|
1933
2115
|
|
|
1934
2116
|
# trigger update to the instance transforms
|
|
1935
2117
|
self._update_shape_instances = True
|
|
1936
2118
|
|
|
1937
2119
|
self._wp_instance_ids = wp.array(instance_ids, dtype=wp.int32, device=self._device)
|
|
2120
|
+
self._wp_instance_custom_ids = wp.array(instance_custom_ids, dtype=wp.int32, device=self._device)
|
|
2121
|
+
self._np_instance_visible = np.array(instance_visible)
|
|
1938
2122
|
self._instance_ids = instance_ids
|
|
1939
2123
|
self._inverse_instance_ids = inverse_instance_ids
|
|
1940
2124
|
|
|
1941
2125
|
gl.glBindVertexArray(0)
|
|
1942
2126
|
|
|
1943
|
-
def update_shape_instance(self, name, pos, rot, color1=None, color2=None):
|
|
2127
|
+
def update_shape_instance(self, name, pos, rot, color1=None, color2=None, visible=None):
|
|
1944
2128
|
"""Update the instance transform of the shape
|
|
1945
2129
|
|
|
1946
2130
|
Args:
|
|
1947
2131
|
name: The name of the shape
|
|
1948
2132
|
pos: The position of the shape
|
|
1949
2133
|
rot: The rotation of the shape
|
|
2134
|
+
color1: The first color of the checker pattern
|
|
2135
|
+
color2: The second color of the checker pattern
|
|
2136
|
+
visible: Whether the shape is visible
|
|
1950
2137
|
"""
|
|
1951
2138
|
if name in self._instances:
|
|
1952
|
-
i, body, shape, _, scale, old_color1, old_color2 = self._instances[name]
|
|
1953
|
-
|
|
2139
|
+
i, body, shape, _, scale, old_color1, old_color2, v = self._instances[name]
|
|
2140
|
+
if visible is None:
|
|
2141
|
+
visible = v
|
|
2142
|
+
self._instances[name] = (
|
|
2143
|
+
i,
|
|
2144
|
+
body,
|
|
2145
|
+
shape,
|
|
2146
|
+
[*pos, *rot],
|
|
2147
|
+
scale,
|
|
2148
|
+
color1 or old_color1,
|
|
2149
|
+
color2 or old_color2,
|
|
2150
|
+
visible,
|
|
2151
|
+
)
|
|
1954
2152
|
self._update_shape_instances = True
|
|
1955
2153
|
return True
|
|
1956
2154
|
return False
|
|
@@ -2018,9 +2216,27 @@ Instances: {len(self._instances)}"""
|
|
|
2018
2216
|
self.clear()
|
|
2019
2217
|
self.app.event_loop.exit()
|
|
2020
2218
|
|
|
2021
|
-
def get_pixels(self, target_image: wp.array, split_up_tiles=True):
|
|
2219
|
+
def get_pixels(self, target_image: wp.array, split_up_tiles=True, mode="rgb"):
|
|
2220
|
+
"""
|
|
2221
|
+
Read the pixels from the frame buffer (RGB or depth are supported) into the given array.
|
|
2222
|
+
|
|
2223
|
+
If `split_up_tiles` is False, array must be of shape (screen_height, screen_width, 3) for RGB mode or
|
|
2224
|
+
(screen_height, screen_width, 1) for depth mode.
|
|
2225
|
+
If `split_up_tiles` is True, the pixels will be split up into tiles (see :attr:`tile_width` and :attr:`tile_height` for dimensions):
|
|
2226
|
+
array must be of shape (num_tiles, tile_height, tile_width, 3) for RGB mode or (num_tiles, tile_height, tile_width, 1) for depth mode.
|
|
2227
|
+
|
|
2228
|
+
Args:
|
|
2229
|
+
target_image (array): The array to read the pixels into. Must have float32 as dtype and be on a CUDA device.
|
|
2230
|
+
split_up_tiles (bool): Whether to split up the viewport into tiles, see :meth:`setup_tiled_rendering`.
|
|
2231
|
+
mode (str): can be either "rgb" or "depth"
|
|
2232
|
+
|
|
2233
|
+
Returns:
|
|
2234
|
+
bool: Whether the pixels were successfully read.
|
|
2235
|
+
"""
|
|
2022
2236
|
from pyglet import gl
|
|
2023
2237
|
|
|
2238
|
+
channels = 3 if mode == "rgb" else 1
|
|
2239
|
+
|
|
2024
2240
|
if split_up_tiles:
|
|
2025
2241
|
assert (
|
|
2026
2242
|
self._tile_width is not None and self._tile_height is not None
|
|
@@ -2035,20 +2251,26 @@ Instances: {len(self._instances)}"""
|
|
|
2035
2251
|
self.num_tiles,
|
|
2036
2252
|
self._tile_height,
|
|
2037
2253
|
self._tile_width,
|
|
2038
|
-
|
|
2039
|
-
), f"Shape of `target_image` array does not match {self.num_tiles} x {self.screen_height} x {self.screen_width} x
|
|
2254
|
+
channels,
|
|
2255
|
+
), f"Shape of `target_image` array does not match {self.num_tiles} x {self.screen_height} x {self.screen_width} x {channels}"
|
|
2040
2256
|
else:
|
|
2041
2257
|
assert target_image.shape == (
|
|
2042
2258
|
self.screen_height,
|
|
2043
2259
|
self.screen_width,
|
|
2044
|
-
|
|
2045
|
-
), f"Shape of `target_image` array does not match {self.screen_height} x {self.screen_width} x
|
|
2260
|
+
channels,
|
|
2261
|
+
), f"Shape of `target_image` array does not match {self.screen_height} x {self.screen_width} x {channels}"
|
|
2046
2262
|
|
|
2047
2263
|
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, self._frame_pbo)
|
|
2048
|
-
|
|
2264
|
+
if mode == "rgb":
|
|
2265
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
|
|
2266
|
+
if mode == "depth":
|
|
2267
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_depth_texture)
|
|
2049
2268
|
try:
|
|
2050
2269
|
# read screen texture into PBO
|
|
2051
|
-
|
|
2270
|
+
if mode == "rgb":
|
|
2271
|
+
gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, ctypes.c_void_p(0))
|
|
2272
|
+
elif mode == "depth":
|
|
2273
|
+
gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT, ctypes.c_void_p(0))
|
|
2052
2274
|
except gl.GLException:
|
|
2053
2275
|
# this can happen if the window is closed/being moved to a different display
|
|
2054
2276
|
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
@@ -2061,63 +2283,54 @@ Instances: {len(self._instances)}"""
|
|
|
2061
2283
|
int(self._frame_pbo.value), self._device, wp.RegisteredGLBuffer.WRITE_DISCARD
|
|
2062
2284
|
)
|
|
2063
2285
|
screen_size = self.screen_height * self.screen_width
|
|
2064
|
-
|
|
2286
|
+
if mode == "rgb":
|
|
2287
|
+
img = pbo_buffer.map(dtype=wp.uint8, shape=(screen_size * channels))
|
|
2288
|
+
elif mode == "depth":
|
|
2289
|
+
img = pbo_buffer.map(dtype=wp.float32, shape=(screen_size * channels))
|
|
2065
2290
|
img = img.to(target_image.device)
|
|
2066
2291
|
if split_up_tiles:
|
|
2067
2292
|
positions = wp.array(self._tile_viewports, ndim=2, dtype=wp.int32, device=target_image.device)
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2293
|
+
if mode == "rgb":
|
|
2294
|
+
wp.launch(
|
|
2295
|
+
copy_rgb_frame_tiles,
|
|
2296
|
+
dim=(self.num_tiles, self._tile_width, self._tile_height),
|
|
2297
|
+
inputs=[img, positions, self.screen_width, self.screen_height, self._tile_height],
|
|
2298
|
+
outputs=[target_image],
|
|
2299
|
+
device=target_image.device,
|
|
2300
|
+
)
|
|
2301
|
+
elif mode == "depth":
|
|
2302
|
+
wp.launch(
|
|
2303
|
+
copy_depth_frame_tiles,
|
|
2304
|
+
dim=(self.num_tiles, self._tile_width, self._tile_height),
|
|
2305
|
+
inputs=[
|
|
2306
|
+
img,
|
|
2307
|
+
positions,
|
|
2308
|
+
self.screen_width,
|
|
2309
|
+
self.screen_height,
|
|
2310
|
+
self._tile_height,
|
|
2311
|
+
self.camera_near_plane,
|
|
2312
|
+
self.camera_far_plane,
|
|
2313
|
+
],
|
|
2314
|
+
outputs=[target_image],
|
|
2315
|
+
device=target_image.device,
|
|
2316
|
+
)
|
|
2075
2317
|
else:
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
viewport[2],
|
|
2093
|
-
3,
|
|
2094
|
-
), f"Shape of `target_image` array does not match {viewport[3]} x {viewport[2]} x 3"
|
|
2095
|
-
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, self._frame_pbo)
|
|
2096
|
-
gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
|
|
2097
|
-
try:
|
|
2098
|
-
# read screen texture into PBO
|
|
2099
|
-
gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, ctypes.c_void_p(0))
|
|
2100
|
-
except gl.GLException:
|
|
2101
|
-
# this can happen if the window is closed/being moved to a different display
|
|
2102
|
-
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
2103
|
-
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
|
|
2104
|
-
return False
|
|
2105
|
-
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
2106
|
-
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
|
|
2107
|
-
|
|
2108
|
-
pbo_buffer = wp.RegisteredGLBuffer(
|
|
2109
|
-
int(self._frame_pbo.value), self._device, wp.RegisteredGLBuffer.WRITE_DISCARD
|
|
2110
|
-
)
|
|
2111
|
-
screen_size = self.screen_height * self.screen_width
|
|
2112
|
-
img = pbo_buffer.map(dtype=wp.uint8, shape=(screen_size * 3))
|
|
2113
|
-
img = img.to(target_image.device)
|
|
2114
|
-
wp.launch(
|
|
2115
|
-
copy_frame_tiles,
|
|
2116
|
-
dim=(self.num_tiles, self._tile_width, self._tile_height),
|
|
2117
|
-
inputs=[img, viewport[0], viewport[1], self.screen_width, self.screen_height, self._tile_height],
|
|
2118
|
-
outputs=[target_image],
|
|
2119
|
-
device=target_image.device,
|
|
2120
|
-
)
|
|
2318
|
+
if mode == "rgb":
|
|
2319
|
+
wp.launch(
|
|
2320
|
+
copy_rgb_frame,
|
|
2321
|
+
dim=(self.screen_width, self.screen_height),
|
|
2322
|
+
inputs=[img, self.screen_width, self.screen_height],
|
|
2323
|
+
outputs=[target_image],
|
|
2324
|
+
device=target_image.device,
|
|
2325
|
+
)
|
|
2326
|
+
elif mode == "depth":
|
|
2327
|
+
wp.launch(
|
|
2328
|
+
copy_depth_frame,
|
|
2329
|
+
dim=(self.screen_width, self.screen_height),
|
|
2330
|
+
inputs=[img, self.screen_width, self.screen_height, self.camera_near_plane, self.camera_far_plane],
|
|
2331
|
+
outputs=[target_image],
|
|
2332
|
+
device=target_image.device,
|
|
2333
|
+
)
|
|
2121
2334
|
pbo_buffer.unmap()
|
|
2122
2335
|
return True
|
|
2123
2336
|
|
|
@@ -2570,7 +2783,7 @@ Instances: {len(self._instances)}"""
|
|
|
2570
2783
|
if name not in self._shape_instancers:
|
|
2571
2784
|
instancer = ShapeInstancer(self._shape_shader, self._device)
|
|
2572
2785
|
vertices, indices = self._create_capsule_mesh(radius, 0.5)
|
|
2573
|
-
if color is None or isinstance(color, list):
|
|
2786
|
+
if color is None or isinstance(color, list) and len(color) > 0 and isinstance(color[0], list):
|
|
2574
2787
|
color = tab10_color_map(len(self._shape_geo_hash))
|
|
2575
2788
|
instancer.register_shape(vertices, indices, color, color)
|
|
2576
2789
|
instancer.allocate_instances(np.zeros((len(lines), 3)))
|
|
@@ -2590,7 +2803,7 @@ Instances: {len(self._instances)}"""
|
|
|
2590
2803
|
device=self._device,
|
|
2591
2804
|
)
|
|
2592
2805
|
|
|
2593
|
-
def render_line_list(self, name, vertices, indices, color, radius):
|
|
2806
|
+
def render_line_list(self, name: str, vertices, indices, color: tuple = None, radius: float = 0.01):
|
|
2594
2807
|
"""Add a line list as a set of capsules
|
|
2595
2808
|
|
|
2596
2809
|
Args:
|
|
@@ -2605,7 +2818,7 @@ Instances: {len(self._instances)}"""
|
|
|
2605
2818
|
lines = np.array(lines)
|
|
2606
2819
|
self._render_lines(name, lines, color, radius)
|
|
2607
2820
|
|
|
2608
|
-
def render_line_strip(self, name: str, vertices, color: tuple, radius: float = 0.01):
|
|
2821
|
+
def render_line_strip(self, name: str, vertices, color: tuple = None, radius: float = 0.01):
|
|
2609
2822
|
"""Add a line strip as a set of capsules
|
|
2610
2823
|
|
|
2611
2824
|
Args:
|
|
@@ -2640,7 +2853,12 @@ Instances: {len(self._instances)}"""
|
|
|
2640
2853
|
cuda_buffer.unmap()
|
|
2641
2854
|
|
|
2642
2855
|
@staticmethod
|
|
2643
|
-
def _create_sphere_mesh(
|
|
2856
|
+
def _create_sphere_mesh(
|
|
2857
|
+
radius=1.0,
|
|
2858
|
+
num_latitudes=default_num_segments,
|
|
2859
|
+
num_longitudes=default_num_segments,
|
|
2860
|
+
reverse_winding=False,
|
|
2861
|
+
):
|
|
2644
2862
|
vertices = []
|
|
2645
2863
|
indices = []
|
|
2646
2864
|
|
|
@@ -2754,7 +2972,7 @@ Instances: {len(self._instances)}"""
|
|
|
2754
2972
|
top_radius = radius
|
|
2755
2973
|
side_slope = -np.arctan2(top_radius - radius, 2 * half_height)
|
|
2756
2974
|
|
|
2757
|
-
#
|
|
2975
|
+
# create the cylinder base and top vertices
|
|
2758
2976
|
for j in (-1, 1):
|
|
2759
2977
|
center_index = max(j, 0)
|
|
2760
2978
|
if j == 1:
|
|
@@ -2782,12 +3000,10 @@ Instances: {len(self._instances)}"""
|
|
|
2782
3000
|
vertex = np.hstack([position[[x_dir, y_dir, z_dir]], normal[[x_dir, y_dir, z_dir]], uv])
|
|
2783
3001
|
cap_vertices.append(vertex)
|
|
2784
3002
|
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
(i + 1) % segments + center_index * segments + 2][::-j]
|
|
2788
|
-
)
|
|
3003
|
+
cs = center_index * segments
|
|
3004
|
+
indices.extend([center_index, i + cs + 2, (i + 1) % segments + cs + 2][::-j])
|
|
2789
3005
|
|
|
2790
|
-
#
|
|
3006
|
+
# create the cylinder side indices
|
|
2791
3007
|
for i in range(segments):
|
|
2792
3008
|
index1 = len(cap_vertices) + i + segments
|
|
2793
3009
|
index2 = len(cap_vertices) + ((i + 1) % segments) + segments
|