Spaces:
Running
on
Zero
Running
on
Zero
Commit
•
26b3ad9
1
Parent(s):
75482e2
encapsulate in pipeline
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitignore +3 -0
- .gitmodules +3 -0
- README.md +1 -1
- app.py +72 -135
- core/__init__.py +0 -0
- core/__pycache__/__init__.cpython-39.pyc +0 -0
- core/__pycache__/attention.cpython-39.pyc +0 -0
- core/__pycache__/gs.cpython-39.pyc +0 -0
- core/__pycache__/models.cpython-39.pyc +0 -0
- core/__pycache__/options.cpython-39.pyc +0 -0
- core/__pycache__/provider_objaverse.cpython-39.pyc +0 -0
- core/__pycache__/unet.cpython-39.pyc +0 -0
- core/__pycache__/utils.cpython-39.pyc +0 -0
- core/attention.py +0 -156
- core/gs.py +0 -193
- core/models.py +0 -185
- core/options.py +0 -120
- core/provider_objaverse.py +0 -172
- core/unet.py +0 -319
- core/utils.py +0 -109
- diff-gaussian-rasterization +1 -0
- diff-gaussian-rasterization/.gitignore +0 -7
- diff-gaussian-rasterization/.gitmodules +0 -3
- diff-gaussian-rasterization/CMakeLists.txt +0 -36
- diff-gaussian-rasterization/LICENSE.md +0 -83
- diff-gaussian-rasterization/README.md +0 -35
- diff-gaussian-rasterization/cuda_rasterizer/auxiliary.h +0 -175
- diff-gaussian-rasterization/cuda_rasterizer/backward.cu +0 -712
- diff-gaussian-rasterization/cuda_rasterizer/backward.h +0 -70
- diff-gaussian-rasterization/cuda_rasterizer/config.h +0 -19
- diff-gaussian-rasterization/cuda_rasterizer/forward.cu +0 -466
- diff-gaussian-rasterization/cuda_rasterizer/forward.h +0 -68
- diff-gaussian-rasterization/cuda_rasterizer/rasterizer.h +0 -94
- diff-gaussian-rasterization/cuda_rasterizer/rasterizer_impl.cu +0 -447
- diff-gaussian-rasterization/cuda_rasterizer/rasterizer_impl.h +0 -73
- diff-gaussian-rasterization/diff_gaussian_rasterization/__init__.py +0 -224
- diff-gaussian-rasterization/ext.cpp +0 -19
- diff-gaussian-rasterization/rasterize_points.cu +0 -229
- diff-gaussian-rasterization/rasterize_points.h +0 -70
- diff-gaussian-rasterization/setup.py +0 -34
- diff-gaussian-rasterization/third_party/glm/.appveyor.yml +0 -92
- diff-gaussian-rasterization/third_party/glm/.gitignore +0 -61
- diff-gaussian-rasterization/third_party/glm/.travis.yml +0 -388
- diff-gaussian-rasterization/third_party/glm/CMakeLists.txt +0 -45
- diff-gaussian-rasterization/third_party/glm/cmake/cmake_uninstall.cmake.in +0 -21
- diff-gaussian-rasterization/third_party/glm/copying.txt +0 -54
- diff-gaussian-rasterization/third_party/glm/doc/api/a00001_source.html +0 -493
- diff-gaussian-rasterization/third_party/glm/doc/api/a00002_source.html +0 -121
- diff-gaussian-rasterization/third_party/glm/doc/api/a00003_source.html +0 -182
- diff-gaussian-rasterization/third_party/glm/doc/api/a00004_source.html +0 -0
.gitignore
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
__pycache__/
|
2 |
+
venv/
|
3 |
+
gradio_cached_examples/
|
.gitmodules
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
[submodule "diff-gaussian-rasterization"]
|
2 |
+
path = diff-gaussian-rasterization
|
3 |
+
url = https://github.com/ashawkey/diff-gaussian-rasterization.git
|
README.md
CHANGED
@@ -4,7 +4,7 @@ emoji: 🦀
|
|
4 |
colorFrom: red
|
5 |
colorTo: indigo
|
6 |
sdk: gradio
|
7 |
-
sdk_version: 4.
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
license: mit
|
|
|
4 |
colorFrom: red
|
5 |
colorTo: indigo
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 4.26.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
license: mit
|
app.py
CHANGED
@@ -1,172 +1,109 @@
|
|
1 |
import os
|
2 |
-
import numpy as np
|
3 |
-
import torch
|
4 |
-
import torch.nn.functional as F
|
5 |
-
import torchvision.transforms.functional as TF
|
6 |
-
from safetensors.torch import load_file
|
7 |
-
import rembg
|
8 |
-
import gradio as gr
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
13 |
|
14 |
try:
|
15 |
-
import diff_gaussian_rasterization
|
16 |
except ImportError:
|
17 |
os.system("pip install ./diff-gaussian-rasterization")
|
18 |
|
19 |
-
|
20 |
-
from kiui.op import recenter
|
21 |
-
|
22 |
-
from core.options import Options
|
23 |
-
from core.models import LGM
|
24 |
-
from mvdream.pipeline_mvdream import MVDreamPipeline
|
25 |
-
|
26 |
-
IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
|
27 |
-
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)
|
28 |
-
|
29 |
-
TMP_DIR = '/tmp'
|
30 |
os.makedirs(TMP_DIR, exist_ok=True)
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
up_attention=(True, True, True, False, False),
|
37 |
-
splat_size=128,
|
38 |
-
output_size=512, # render & supervise Gaussians at a higher resolution.
|
39 |
-
batch_size=8,
|
40 |
-
num_views=8,
|
41 |
-
gradient_accumulation_steps=1,
|
42 |
-
mixed_precision='bf16',
|
43 |
-
resume=ckpt_path,
|
44 |
-
)
|
45 |
-
|
46 |
-
# model
|
47 |
-
model = LGM(opt)
|
48 |
-
|
49 |
-
# resume pretrained checkpoint
|
50 |
-
if opt.resume is not None:
|
51 |
-
if opt.resume.endswith('safetensors'):
|
52 |
-
ckpt = load_file(opt.resume, device='cpu')
|
53 |
-
else:
|
54 |
-
ckpt = torch.load(opt.resume, map_location='cpu')
|
55 |
-
model.load_state_dict(ckpt, strict=False)
|
56 |
-
print(f'[INFO] Loaded checkpoint from {opt.resume}')
|
57 |
-
else:
|
58 |
-
print(f'[WARN] model randomly initialized, are you sure?')
|
59 |
-
|
60 |
-
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
61 |
-
model = model.half().to(device)
|
62 |
-
model.eval()
|
63 |
-
|
64 |
-
tan_half_fov = np.tan(0.5 * np.deg2rad(opt.fovy))
|
65 |
-
proj_matrix = torch.zeros(4, 4, dtype=torch.float32, device=device)
|
66 |
-
proj_matrix[0, 0] = -1 / tan_half_fov
|
67 |
-
proj_matrix[1, 1] = -1 / tan_half_fov
|
68 |
-
proj_matrix[2, 2] = - (opt.zfar + opt.znear) / (opt.zfar - opt.znear)
|
69 |
-
proj_matrix[3, 2] = - (opt.zfar * opt.znear) / (opt.zfar - opt.znear)
|
70 |
-
proj_matrix[2, 3] = 1
|
71 |
-
|
72 |
-
# load dreams
|
73 |
-
pipe_text = MVDreamPipeline.from_pretrained(
|
74 |
-
'ashawkey/mvdream-sd2.1-diffusers', # remote weights
|
75 |
torch_dtype=torch.float16,
|
76 |
trust_remote_code=True,
|
77 |
-
|
78 |
-
)
|
79 |
-
pipe_text = pipe_text.to(device)
|
80 |
|
81 |
-
|
82 |
-
|
|
|
|
|
83 |
torch_dtype=torch.float16,
|
84 |
trust_remote_code=True,
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
input_image = F.interpolate(input_image, size=(opt.input_size, opt.input_size), mode='bilinear', align_corners=False)
|
114 |
-
input_image = TF.normalize(input_image, IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)
|
115 |
-
|
116 |
-
rays_embeddings = model.prepare_default_rays(device, elevation=0)
|
117 |
-
input_image = torch.cat([input_image, rays_embeddings], dim=1).unsqueeze(0) # [1, 4, 9, H, W]
|
118 |
-
|
119 |
-
with torch.no_grad():
|
120 |
-
with torch.autocast(device_type='cuda', dtype=torch.float16):
|
121 |
-
# generate gaussians
|
122 |
-
gaussians = model.forward_gaussians(input_image)
|
123 |
-
|
124 |
-
# save gaussians
|
125 |
-
model.gs.save_ply(gaussians, output_ply_path)
|
126 |
-
|
127 |
-
return output_ply_path
|
128 |
-
|
129 |
-
# gradio UI
|
130 |
-
|
131 |
-
_TITLE = '''LGM Mini'''
|
132 |
-
|
133 |
-
_DESCRIPTION = '''
|
134 |
<div>
|
135 |
A lightweight version of <a href="https://huggingface.co/spaces/ashawkey/LGM">LGM: Large Multi-View Gaussian Model for High-Resolution 3D Content Creation</a>.
|
136 |
</div>
|
137 |
-
|
138 |
|
139 |
-
css =
|
140 |
#duplicate-button {
|
141 |
margin: auto;
|
142 |
color: white;
|
143 |
background: #1565c0;
|
144 |
border-radius: 100vh;
|
145 |
}
|
146 |
-
|
147 |
|
148 |
block = gr.Blocks(title=_TITLE, css=css)
|
149 |
with block:
|
150 |
-
gr.DuplicateButton(
|
|
|
|
|
151 |
|
152 |
with gr.Row():
|
153 |
with gr.Column(scale=1):
|
154 |
-
gr.Markdown(
|
155 |
gr.Markdown(_DESCRIPTION)
|
156 |
-
|
157 |
-
with gr.Row(variant=
|
158 |
with gr.Column(scale=1):
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
button_gen = gr.Button("Generate")
|
163 |
|
164 |
-
|
165 |
with gr.Column(scale=1):
|
166 |
output_splat = gr.Model3D(label="3D Gaussians")
|
167 |
|
168 |
-
button_gen.click(
|
169 |
-
|
|
|
|
|
170 |
gr.Examples(
|
171 |
examples=[
|
172 |
"data_test/frog_sweater.jpg",
|
@@ -178,9 +115,9 @@ with block:
|
|
178 |
],
|
179 |
inputs=[input_image],
|
180 |
outputs=[output_splat],
|
181 |
-
fn=lambda x: run(input_image=x),
|
182 |
cache_examples=True,
|
183 |
-
label=
|
184 |
)
|
185 |
-
|
186 |
block.queue().launch(debug=True, share=True)
|
|
|
1 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
import gradio as gr
|
4 |
+
import torch
|
5 |
+
from diffusers import DiffusionPipeline
|
6 |
+
from gradio_client import Client, file
|
7 |
|
8 |
try:
|
9 |
+
import diff_gaussian_rasterization # noqa: F401
|
10 |
except ImportError:
|
11 |
os.system("pip install ./diff-gaussian-rasterization")
|
12 |
|
13 |
+
TMP_DIR = "/tmp"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
os.makedirs(TMP_DIR, exist_ok=True)
|
15 |
|
16 |
+
|
17 |
+
image_pipeline = DiffusionPipeline.from_pretrained(
|
18 |
+
"ashawkey/imagedream-ipmv-diffusers",
|
19 |
+
custom_pipeline="dylanebert/multi_view_diffusion",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
torch_dtype=torch.float16,
|
21 |
trust_remote_code=True,
|
22 |
+
).to("cuda")
|
|
|
|
|
23 |
|
24 |
+
|
25 |
+
splat_pipeline = DiffusionPipeline.from_pretrained(
|
26 |
+
"dylanebert/LGM",
|
27 |
+
custom_pipeline="dylanebert/LGM",
|
28 |
torch_dtype=torch.float16,
|
29 |
trust_remote_code=True,
|
30 |
+
).to("cuda")
|
31 |
+
|
32 |
+
|
33 |
+
def run(input_image, convert):
|
34 |
+
input_image = input_image.astype("float32") / 255.0
|
35 |
+
images = image_pipeline(
|
36 |
+
"", input_image, guidance_scale=5, num_inference_steps=30, elevation=0
|
37 |
+
)
|
38 |
+
gaussians = splat_pipeline(images)
|
39 |
+
output_ply_path = os.path.join(TMP_DIR, "output.ply")
|
40 |
+
splat_pipeline.save_ply(gaussians, output_ply_path)
|
41 |
+
if convert:
|
42 |
+
output_mesh_path = convert_to_mesh(output_ply_path)
|
43 |
+
return output_mesh_path
|
44 |
+
else:
|
45 |
+
return output_ply_path
|
46 |
+
|
47 |
+
|
48 |
+
def convert_to_mesh(input_ply):
|
49 |
+
client = Client("https://dylanebert-splat-to-mesh.hf.space/")
|
50 |
+
output_mesh_path = client.predict(file(input_ply), api_name="/run")
|
51 |
+
client.close()
|
52 |
+
return output_mesh_path
|
53 |
+
|
54 |
+
|
55 |
+
_TITLE = """LGM Mini"""
|
56 |
+
|
57 |
+
_DESCRIPTION = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
<div>
|
59 |
A lightweight version of <a href="https://huggingface.co/spaces/ashawkey/LGM">LGM: Large Multi-View Gaussian Model for High-Resolution 3D Content Creation</a>.
|
60 |
</div>
|
61 |
+
"""
|
62 |
|
63 |
+
css = """
|
64 |
#duplicate-button {
|
65 |
margin: auto;
|
66 |
color: white;
|
67 |
background: #1565c0;
|
68 |
border-radius: 100vh;
|
69 |
}
|
70 |
+
"""
|
71 |
|
72 |
block = gr.Blocks(title=_TITLE, css=css)
|
73 |
with block:
|
74 |
+
gr.DuplicateButton(
|
75 |
+
value="Duplicate Space for private use", elem_id="duplicate-button"
|
76 |
+
)
|
77 |
|
78 |
with gr.Row():
|
79 |
with gr.Column(scale=1):
|
80 |
+
gr.Markdown("# " + _TITLE)
|
81 |
gr.Markdown(_DESCRIPTION)
|
82 |
+
|
83 |
+
with gr.Row(variant="panel"):
|
84 |
with gr.Column(scale=1):
|
85 |
+
|
86 |
+
def update_warning(checked):
|
87 |
+
if checked:
|
88 |
+
return '<span style="color: #ff0000;">Warning: Mesh conversion takes several minutes</span>'
|
89 |
+
else:
|
90 |
+
return ""
|
91 |
+
|
92 |
+
input_image = gr.Image(label="image", type="numpy")
|
93 |
+
convert_checkbox = gr.Checkbox(label="Convert to Mesh")
|
94 |
+
warning = gr.HTML()
|
95 |
+
convert_checkbox.change(
|
96 |
+
fn=update_warning, inputs=[convert_checkbox], outputs=[warning]
|
97 |
+
)
|
98 |
button_gen = gr.Button("Generate")
|
99 |
|
|
|
100 |
with gr.Column(scale=1):
|
101 |
output_splat = gr.Model3D(label="3D Gaussians")
|
102 |
|
103 |
+
button_gen.click(
|
104 |
+
fn=run, inputs=[input_image, convert_checkbox], outputs=[output_splat]
|
105 |
+
)
|
106 |
+
|
107 |
gr.Examples(
|
108 |
examples=[
|
109 |
"data_test/frog_sweater.jpg",
|
|
|
115 |
],
|
116 |
inputs=[input_image],
|
117 |
outputs=[output_splat],
|
118 |
+
fn=lambda x: run(input_image=x, convert=False),
|
119 |
cache_examples=True,
|
120 |
+
label="Image-to-3D Examples",
|
121 |
)
|
122 |
+
|
123 |
block.queue().launch(debug=True, share=True)
|
core/__init__.py
DELETED
File without changes
|
core/__pycache__/__init__.cpython-39.pyc
DELETED
Binary file (123 Bytes)
|
|
core/__pycache__/attention.cpython-39.pyc
DELETED
Binary file (4.36 kB)
|
|
core/__pycache__/gs.cpython-39.pyc
DELETED
Binary file (5.48 kB)
|
|
core/__pycache__/models.cpython-39.pyc
DELETED
Binary file (4.47 kB)
|
|
core/__pycache__/options.cpython-39.pyc
DELETED
Binary file (2.46 kB)
|
|
core/__pycache__/provider_objaverse.cpython-39.pyc
DELETED
Binary file (7.74 kB)
|
|
core/__pycache__/unet.cpython-39.pyc
DELETED
Binary file (7.45 kB)
|
|
core/__pycache__/utils.cpython-39.pyc
DELETED
Binary file (2.54 kB)
|
|
core/attention.py
DELETED
@@ -1,156 +0,0 @@
|
|
1 |
-
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
2 |
-
#
|
3 |
-
# This source code is licensed under the Apache License, Version 2.0
|
4 |
-
# found in the LICENSE file in the root directory of this source tree.
|
5 |
-
|
6 |
-
# References:
|
7 |
-
# https://github.com/facebookresearch/dino/blob/master/vision_transformer.py
|
8 |
-
# https://github.com/rwightman/pytorch-image-models/tree/master/timm/models/vision_transformer.py
|
9 |
-
|
10 |
-
import os
|
11 |
-
import warnings
|
12 |
-
|
13 |
-
from torch import Tensor
|
14 |
-
from torch import nn
|
15 |
-
|
16 |
-
XFORMERS_ENABLED = os.environ.get("XFORMERS_DISABLED") is None
|
17 |
-
try:
|
18 |
-
if XFORMERS_ENABLED:
|
19 |
-
from xformers.ops import memory_efficient_attention, unbind
|
20 |
-
|
21 |
-
XFORMERS_AVAILABLE = True
|
22 |
-
warnings.warn("xFormers is available (Attention)")
|
23 |
-
else:
|
24 |
-
warnings.warn("xFormers is disabled (Attention)")
|
25 |
-
raise ImportError
|
26 |
-
except ImportError:
|
27 |
-
XFORMERS_AVAILABLE = False
|
28 |
-
warnings.warn("xFormers is not available (Attention)")
|
29 |
-
|
30 |
-
|
31 |
-
class Attention(nn.Module):
|
32 |
-
def __init__(
|
33 |
-
self,
|
34 |
-
dim: int,
|
35 |
-
num_heads: int = 8,
|
36 |
-
qkv_bias: bool = False,
|
37 |
-
proj_bias: bool = True,
|
38 |
-
attn_drop: float = 0.0,
|
39 |
-
proj_drop: float = 0.0,
|
40 |
-
) -> None:
|
41 |
-
super().__init__()
|
42 |
-
self.num_heads = num_heads
|
43 |
-
head_dim = dim // num_heads
|
44 |
-
self.scale = head_dim**-0.5
|
45 |
-
|
46 |
-
self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
|
47 |
-
self.attn_drop = nn.Dropout(attn_drop)
|
48 |
-
self.proj = nn.Linear(dim, dim, bias=proj_bias)
|
49 |
-
self.proj_drop = nn.Dropout(proj_drop)
|
50 |
-
|
51 |
-
def forward(self, x: Tensor) -> Tensor:
|
52 |
-
B, N, C = x.shape
|
53 |
-
qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
|
54 |
-
|
55 |
-
q, k, v = qkv[0] * self.scale, qkv[1], qkv[2]
|
56 |
-
attn = q @ k.transpose(-2, -1)
|
57 |
-
|
58 |
-
attn = attn.softmax(dim=-1)
|
59 |
-
attn = self.attn_drop(attn)
|
60 |
-
|
61 |
-
x = (attn @ v).transpose(1, 2).reshape(B, N, C)
|
62 |
-
x = self.proj(x)
|
63 |
-
x = self.proj_drop(x)
|
64 |
-
return x
|
65 |
-
|
66 |
-
|
67 |
-
class MemEffAttention(Attention):
|
68 |
-
def forward(self, x: Tensor, attn_bias=None) -> Tensor:
|
69 |
-
if not XFORMERS_AVAILABLE:
|
70 |
-
if attn_bias is not None:
|
71 |
-
raise AssertionError("xFormers is required for using nested tensors")
|
72 |
-
return super().forward(x)
|
73 |
-
|
74 |
-
B, N, C = x.shape
|
75 |
-
qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads)
|
76 |
-
|
77 |
-
q, k, v = unbind(qkv, 2)
|
78 |
-
|
79 |
-
x = memory_efficient_attention(q, k, v, attn_bias=attn_bias)
|
80 |
-
x = x.reshape([B, N, C])
|
81 |
-
|
82 |
-
x = self.proj(x)
|
83 |
-
x = self.proj_drop(x)
|
84 |
-
return x
|
85 |
-
|
86 |
-
|
87 |
-
class CrossAttention(nn.Module):
|
88 |
-
def __init__(
|
89 |
-
self,
|
90 |
-
dim: int,
|
91 |
-
dim_q: int,
|
92 |
-
dim_k: int,
|
93 |
-
dim_v: int,
|
94 |
-
num_heads: int = 8,
|
95 |
-
qkv_bias: bool = False,
|
96 |
-
proj_bias: bool = True,
|
97 |
-
attn_drop: float = 0.0,
|
98 |
-
proj_drop: float = 0.0,
|
99 |
-
) -> None:
|
100 |
-
super().__init__()
|
101 |
-
self.dim = dim
|
102 |
-
self.num_heads = num_heads
|
103 |
-
head_dim = dim // num_heads
|
104 |
-
self.scale = head_dim**-0.5
|
105 |
-
|
106 |
-
self.to_q = nn.Linear(dim_q, dim, bias=qkv_bias)
|
107 |
-
self.to_k = nn.Linear(dim_k, dim, bias=qkv_bias)
|
108 |
-
self.to_v = nn.Linear(dim_v, dim, bias=qkv_bias)
|
109 |
-
self.attn_drop = nn.Dropout(attn_drop)
|
110 |
-
self.proj = nn.Linear(dim, dim, bias=proj_bias)
|
111 |
-
self.proj_drop = nn.Dropout(proj_drop)
|
112 |
-
|
113 |
-
def forward(self, q: Tensor, k: Tensor, v: Tensor) -> Tensor:
|
114 |
-
# q: [B, N, Cq]
|
115 |
-
# k: [B, M, Ck]
|
116 |
-
# v: [B, M, Cv]
|
117 |
-
# return: [B, N, C]
|
118 |
-
|
119 |
-
B, N, _ = q.shape
|
120 |
-
M = k.shape[1]
|
121 |
-
|
122 |
-
q = self.scale * self.to_q(q).reshape(B, N, self.num_heads, self.dim // self.num_heads).permute(0, 2, 1, 3) # [B, nh, N, C/nh]
|
123 |
-
k = self.to_k(k).reshape(B, M, self.num_heads, self.dim // self.num_heads).permute(0, 2, 1, 3) # [B, nh, M, C/nh]
|
124 |
-
v = self.to_v(v).reshape(B, M, self.num_heads, self.dim // self.num_heads).permute(0, 2, 1, 3) # [B, nh, M, C/nh]
|
125 |
-
|
126 |
-
attn = q @ k.transpose(-2, -1) # [B, nh, N, M]
|
127 |
-
|
128 |
-
attn = attn.softmax(dim=-1) # [B, nh, N, M]
|
129 |
-
attn = self.attn_drop(attn)
|
130 |
-
|
131 |
-
x = (attn @ v).transpose(1, 2).reshape(B, N, -1) # [B, nh, N, M] @ [B, nh, M, C/nh] --> [B, nh, N, C/nh] --> [B, N, nh, C/nh] --> [B, N, C]
|
132 |
-
x = self.proj(x)
|
133 |
-
x = self.proj_drop(x)
|
134 |
-
return x
|
135 |
-
|
136 |
-
|
137 |
-
class MemEffCrossAttention(CrossAttention):
|
138 |
-
def forward(self, q: Tensor, k: Tensor, v: Tensor, attn_bias=None) -> Tensor:
|
139 |
-
if not XFORMERS_AVAILABLE:
|
140 |
-
if attn_bias is not None:
|
141 |
-
raise AssertionError("xFormers is required for using nested tensors")
|
142 |
-
return super().forward(x)
|
143 |
-
|
144 |
-
B, N, _ = q.shape
|
145 |
-
M = k.shape[1]
|
146 |
-
|
147 |
-
q = self.scale * self.to_q(q).reshape(B, N, self.num_heads, self.dim // self.num_heads) # [B, N, nh, C/nh]
|
148 |
-
k = self.to_k(k).reshape(B, M, self.num_heads, self.dim // self.num_heads) # [B, M, nh, C/nh]
|
149 |
-
v = self.to_v(v).reshape(B, M, self.num_heads, self.dim // self.num_heads) # [B, M, nh, C/nh]
|
150 |
-
|
151 |
-
x = memory_efficient_attention(q, k, v, attn_bias=attn_bias)
|
152 |
-
x = x.reshape(B, N, -1)
|
153 |
-
|
154 |
-
x = self.proj(x)
|
155 |
-
x = self.proj_drop(x)
|
156 |
-
return x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/gs.py
DELETED
@@ -1,193 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
import numpy as np
|
3 |
-
|
4 |
-
import torch
|
5 |
-
import torch.nn as nn
|
6 |
-
import torch.nn.functional as F
|
7 |
-
|
8 |
-
from diff_gaussian_rasterization import (
|
9 |
-
GaussianRasterizationSettings,
|
10 |
-
GaussianRasterizer,
|
11 |
-
)
|
12 |
-
|
13 |
-
from core.options import Options
|
14 |
-
|
15 |
-
import kiui
|
16 |
-
|
17 |
-
class GaussianRenderer:
|
18 |
-
def __init__(self, opt: Options):
|
19 |
-
|
20 |
-
self.opt = opt
|
21 |
-
self.bg_color = torch.tensor([1, 1, 1], dtype=torch.float32, device="cuda")
|
22 |
-
|
23 |
-
# intrinsics
|
24 |
-
self.tan_half_fov = np.tan(0.5 * np.deg2rad(self.opt.fovy))
|
25 |
-
self.proj_matrix = torch.zeros(4, 4, dtype=torch.float32)
|
26 |
-
self.proj_matrix[0, 0] = 1 / self.tan_half_fov
|
27 |
-
self.proj_matrix[1, 1] = 1 / self.tan_half_fov
|
28 |
-
self.proj_matrix[2, 2] = (opt.zfar + opt.znear) / (opt.zfar - opt.znear)
|
29 |
-
self.proj_matrix[3, 2] = - (opt.zfar * opt.znear) / (opt.zfar - opt.znear)
|
30 |
-
self.proj_matrix[2, 3] = 1
|
31 |
-
|
32 |
-
def render(self, gaussians, cam_view, cam_view_proj, cam_pos, bg_color=None, scale_modifier=1):
|
33 |
-
# gaussians: [B, N, 14]
|
34 |
-
# cam_view, cam_view_proj: [B, V, 4, 4]
|
35 |
-
# cam_pos: [B, V, 3]
|
36 |
-
|
37 |
-
device = gaussians.device
|
38 |
-
B, V = cam_view.shape[:2]
|
39 |
-
|
40 |
-
# loop of loop...
|
41 |
-
images = []
|
42 |
-
alphas = []
|
43 |
-
for b in range(B):
|
44 |
-
|
45 |
-
# pos, opacity, scale, rotation, shs
|
46 |
-
means3D = gaussians[b, :, 0:3].contiguous().float()
|
47 |
-
opacity = gaussians[b, :, 3:4].contiguous().float()
|
48 |
-
scales = gaussians[b, :, 4:7].contiguous().float()
|
49 |
-
rotations = gaussians[b, :, 7:11].contiguous().float()
|
50 |
-
rgbs = gaussians[b, :, 11:].contiguous().float() # [N, 3]
|
51 |
-
|
52 |
-
for v in range(V):
|
53 |
-
|
54 |
-
# render novel views
|
55 |
-
view_matrix = cam_view[b, v].float()
|
56 |
-
view_proj_matrix = cam_view_proj[b, v].float()
|
57 |
-
campos = cam_pos[b, v].float()
|
58 |
-
|
59 |
-
raster_settings = GaussianRasterizationSettings(
|
60 |
-
image_height=self.opt.output_size,
|
61 |
-
image_width=self.opt.output_size,
|
62 |
-
tanfovx=self.tan_half_fov,
|
63 |
-
tanfovy=self.tan_half_fov,
|
64 |
-
bg=self.bg_color if bg_color is None else bg_color,
|
65 |
-
scale_modifier=scale_modifier,
|
66 |
-
viewmatrix=view_matrix,
|
67 |
-
projmatrix=view_proj_matrix,
|
68 |
-
sh_degree=0,
|
69 |
-
campos=campos,
|
70 |
-
prefiltered=False,
|
71 |
-
debug=False,
|
72 |
-
)
|
73 |
-
|
74 |
-
rasterizer = GaussianRasterizer(raster_settings=raster_settings)
|
75 |
-
|
76 |
-
# Rasterize visible Gaussians to image, obtain their radii (on screen).
|
77 |
-
rendered_image, radii, rendered_depth, rendered_alpha = rasterizer(
|
78 |
-
means3D=means3D,
|
79 |
-
means2D=torch.zeros_like(means3D, dtype=torch.float32, device=device),
|
80 |
-
shs=None,
|
81 |
-
colors_precomp=rgbs,
|
82 |
-
opacities=opacity,
|
83 |
-
scales=scales,
|
84 |
-
rotations=rotations,
|
85 |
-
cov3D_precomp=None,
|
86 |
-
)
|
87 |
-
|
88 |
-
rendered_image = rendered_image.clamp(0, 1)
|
89 |
-
|
90 |
-
images.append(rendered_image)
|
91 |
-
alphas.append(rendered_alpha)
|
92 |
-
|
93 |
-
images = torch.stack(images, dim=0).view(B, V, 3, self.opt.output_size, self.opt.output_size)
|
94 |
-
alphas = torch.stack(alphas, dim=0).view(B, V, 1, self.opt.output_size, self.opt.output_size)
|
95 |
-
|
96 |
-
return {
|
97 |
-
"image": images, # [B, V, 3, H, W]
|
98 |
-
"alpha": alphas, # [B, V, 1, H, W]
|
99 |
-
}
|
100 |
-
|
101 |
-
|
102 |
-
def save_ply(self, gaussians, path, compatible=True):
|
103 |
-
# gaussians: [B, N, 14]
|
104 |
-
# compatible: save pre-activated gaussians as in the original paper
|
105 |
-
|
106 |
-
assert gaussians.shape[0] == 1, 'only support batch size 1'
|
107 |
-
|
108 |
-
from plyfile import PlyData, PlyElement
|
109 |
-
|
110 |
-
os.makedirs(os.path.dirname(path), exist_ok=True)
|
111 |
-
|
112 |
-
means3D = gaussians[0, :, 0:3].contiguous().float()
|
113 |
-
opacity = gaussians[0, :, 3:4].contiguous().float()
|
114 |
-
scales = gaussians[0, :, 4:7].contiguous().float()
|
115 |
-
rotations = gaussians[0, :, 7:11].contiguous().float()
|
116 |
-
shs = gaussians[0, :, 11:].unsqueeze(1).contiguous().float() # [N, 1, 3]
|
117 |
-
|
118 |
-
# prune by opacity
|
119 |
-
mask = opacity.squeeze(-1) >= 0.005
|
120 |
-
means3D = means3D[mask]
|
121 |
-
opacity = opacity[mask]
|
122 |
-
scales = scales[mask]
|
123 |
-
rotations = rotations[mask]
|
124 |
-
shs = shs[mask]
|
125 |
-
|
126 |
-
# invert activation to make it compatible with the original ply format
|
127 |
-
if compatible:
|
128 |
-
opacity = kiui.op.inverse_sigmoid(opacity)
|
129 |
-
scales = torch.log(scales + 1e-8)
|
130 |
-
shs = (shs - 0.5) / 0.28209479177387814
|
131 |
-
|
132 |
-
xyzs = means3D.detach().cpu().numpy()
|
133 |
-
f_dc = shs.detach().transpose(1, 2).flatten(start_dim=1).contiguous().cpu().numpy()
|
134 |
-
opacities = opacity.detach().cpu().numpy()
|
135 |
-
scales = scales.detach().cpu().numpy()
|
136 |
-
rotations = rotations.detach().cpu().numpy()
|
137 |
-
|
138 |
-
l = ['x', 'y', 'z']
|
139 |
-
# All channels except the 3 DC
|
140 |
-
for i in range(f_dc.shape[1]):
|
141 |
-
l.append('f_dc_{}'.format(i))
|
142 |
-
l.append('opacity')
|
143 |
-
for i in range(scales.shape[1]):
|
144 |
-
l.append('scale_{}'.format(i))
|
145 |
-
for i in range(rotations.shape[1]):
|
146 |
-
l.append('rot_{}'.format(i))
|
147 |
-
|
148 |
-
dtype_full = [(attribute, 'f4') for attribute in l]
|
149 |
-
|
150 |
-
elements = np.empty(xyzs.shape[0], dtype=dtype_full)
|
151 |
-
attributes = np.concatenate((xyzs, f_dc, opacities, scales, rotations), axis=1)
|
152 |
-
elements[:] = list(map(tuple, attributes))
|
153 |
-
el = PlyElement.describe(elements, 'vertex')
|
154 |
-
|
155 |
-
PlyData([el]).write(path)
|
156 |
-
|
157 |
-
def load_ply(self, path, compatible=True):
|
158 |
-
|
159 |
-
from plyfile import PlyData, PlyElement
|
160 |
-
|
161 |
-
plydata = PlyData.read(path)
|
162 |
-
|
163 |
-
xyz = np.stack((np.asarray(plydata.elements[0]["x"]),
|
164 |
-
np.asarray(plydata.elements[0]["y"]),
|
165 |
-
np.asarray(plydata.elements[0]["z"])), axis=1)
|
166 |
-
print("Number of points at loading : ", xyz.shape[0])
|
167 |
-
|
168 |
-
opacities = np.asarray(plydata.elements[0]["opacity"])[..., np.newaxis]
|
169 |
-
|
170 |
-
shs = np.zeros((xyz.shape[0], 3))
|
171 |
-
shs[:, 0] = np.asarray(plydata.elements[0]["f_dc_0"])
|
172 |
-
shs[:, 1] = np.asarray(plydata.elements[0]["f_dc_1"])
|
173 |
-
shs[:, 2] = np.asarray(plydata.elements[0]["f_dc_2"])
|
174 |
-
|
175 |
-
scale_names = [p.name for p in plydata.elements[0].properties if p.name.startswith("scale_")]
|
176 |
-
scales = np.zeros((xyz.shape[0], len(scale_names)))
|
177 |
-
for idx, attr_name in enumerate(scale_names):
|
178 |
-
scales[:, idx] = np.asarray(plydata.elements[0][attr_name])
|
179 |
-
|
180 |
-
rot_names = [p.name for p in plydata.elements[0].properties if p.name.startswith("rot_")]
|
181 |
-
rots = np.zeros((xyz.shape[0], len(rot_names)))
|
182 |
-
for idx, attr_name in enumerate(rot_names):
|
183 |
-
rots[:, idx] = np.asarray(plydata.elements[0][attr_name])
|
184 |
-
|
185 |
-
gaussians = np.concatenate([xyz, opacities, scales, rots, shs], axis=1)
|
186 |
-
gaussians = torch.from_numpy(gaussians).float() # cpu
|
187 |
-
|
188 |
-
if compatible:
|
189 |
-
gaussians[..., 3:4] = torch.sigmoid(gaussians[..., 3:4])
|
190 |
-
gaussians[..., 4:7] = torch.exp(gaussians[..., 4:7])
|
191 |
-
gaussians[..., 11:] = 0.28209479177387814 * gaussians[..., 11:] + 0.5
|
192 |
-
|
193 |
-
return gaussians
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/models.py
DELETED
@@ -1,185 +0,0 @@
|
|
1 |
-
import torch
|
2 |
-
import torch.nn as nn
|
3 |
-
import torch.nn.functional as F
|
4 |
-
import numpy as np
|
5 |
-
|
6 |
-
import kiui
|
7 |
-
from kiui.lpips import LPIPS
|
8 |
-
|
9 |
-
from core.unet import UNet
|
10 |
-
from core.options import Options
|
11 |
-
from core.gs import GaussianRenderer
|
12 |
-
|
13 |
-
|
14 |
-
class LGM(nn.Module):
|
15 |
-
def __init__(
|
16 |
-
self,
|
17 |
-
opt: Options,
|
18 |
-
):
|
19 |
-
super().__init__()
|
20 |
-
|
21 |
-
self.opt = opt
|
22 |
-
|
23 |
-
# unet
|
24 |
-
self.unet = UNet(
|
25 |
-
9, 14,
|
26 |
-
down_channels=self.opt.down_channels,
|
27 |
-
down_attention=self.opt.down_attention,
|
28 |
-
mid_attention=self.opt.mid_attention,
|
29 |
-
up_channels=self.opt.up_channels,
|
30 |
-
up_attention=self.opt.up_attention,
|
31 |
-
)
|
32 |
-
|
33 |
-
# last conv
|
34 |
-
self.conv = nn.Conv2d(14, 14, kernel_size=1) # NOTE: maybe remove it if train again
|
35 |
-
|
36 |
-
# Gaussian Renderer
|
37 |
-
self.gs = GaussianRenderer(opt)
|
38 |
-
|
39 |
-
# activations...
|
40 |
-
self.pos_act = lambda x: x.clamp(-1, 1)
|
41 |
-
self.scale_act = lambda x: 0.1 * F.softplus(x)
|
42 |
-
self.opacity_act = lambda x: torch.sigmoid(x)
|
43 |
-
self.rot_act = F.normalize
|
44 |
-
self.rgb_act = lambda x: 0.5 * torch.tanh(x) + 0.5 # NOTE: may use sigmoid if train again
|
45 |
-
|
46 |
-
# LPIPS loss
|
47 |
-
if self.opt.lambda_lpips > 0:
|
48 |
-
self.lpips_loss = LPIPS(net='vgg')
|
49 |
-
self.lpips_loss.requires_grad_(False)
|
50 |
-
|
51 |
-
|
52 |
-
def state_dict(self, **kwargs):
|
53 |
-
# remove lpips_loss
|
54 |
-
state_dict = super().state_dict(**kwargs)
|
55 |
-
for k in list(state_dict.keys()):
|
56 |
-
if 'lpips_loss' in k:
|
57 |
-
del state_dict[k]
|
58 |
-
return state_dict
|
59 |
-
|
60 |
-
|
61 |
-
def prepare_default_rays(self, device, elevation=0):
|
62 |
-
|
63 |
-
from kiui.cam import orbit_camera
|
64 |
-
from core.utils import get_rays
|
65 |
-
|
66 |
-
cam_poses = np.stack([
|
67 |
-
orbit_camera(elevation, 0, radius=self.opt.cam_radius),
|
68 |
-
orbit_camera(elevation, 90, radius=self.opt.cam_radius),
|
69 |
-
orbit_camera(elevation, 180, radius=self.opt.cam_radius),
|
70 |
-
orbit_camera(elevation, 270, radius=self.opt.cam_radius),
|
71 |
-
], axis=0) # [4, 4, 4]
|
72 |
-
cam_poses = torch.from_numpy(cam_poses)
|
73 |
-
|
74 |
-
rays_embeddings = []
|
75 |
-
for i in range(cam_poses.shape[0]):
|
76 |
-
rays_o, rays_d = get_rays(cam_poses[i], self.opt.input_size, self.opt.input_size, self.opt.fovy) # [h, w, 3]
|
77 |
-
rays_plucker = torch.cat([torch.cross(rays_o, rays_d, dim=-1), rays_d], dim=-1) # [h, w, 6]
|
78 |
-
rays_embeddings.append(rays_plucker)
|
79 |
-
|
80 |
-
## visualize rays for plotting figure
|
81 |
-
# kiui.vis.plot_image(rays_d * 0.5 + 0.5, save=True)
|
82 |
-
|
83 |
-
rays_embeddings = torch.stack(rays_embeddings, dim=0).permute(0, 3, 1, 2).contiguous().to(device) # [V, 6, h, w]
|
84 |
-
|
85 |
-
return rays_embeddings
|
86 |
-
|
87 |
-
|
88 |
-
def forward_gaussians(self, images):
|
89 |
-
# images: [B, 4, 9, H, W]
|
90 |
-
# return: Gaussians: [B, dim_t]
|
91 |
-
|
92 |
-
B, V, C, H, W = images.shape
|
93 |
-
images = images.view(B*V, C, H, W)
|
94 |
-
|
95 |
-
x = self.unet(images) # [B*4, 14, h, w]
|
96 |
-
x = self.conv(x) # [B*4, 14, h, w]
|
97 |
-
|
98 |
-
x = x.reshape(B, 4, 14, self.opt.splat_size, self.opt.splat_size)
|
99 |
-
|
100 |
-
## visualize multi-view gaussian features for plotting figure
|
101 |
-
# tmp_alpha = self.opacity_act(x[0, :, 3:4])
|
102 |
-
# tmp_img_rgb = self.rgb_act(x[0, :, 11:]) * tmp_alpha + (1 - tmp_alpha)
|
103 |
-
# tmp_img_pos = self.pos_act(x[0, :, 0:3]) * 0.5 + 0.5
|
104 |
-
# kiui.vis.plot_image(tmp_img_rgb, save=True)
|
105 |
-
# kiui.vis.plot_image(tmp_img_pos, save=True)
|
106 |
-
|
107 |
-
x = x.permute(0, 1, 3, 4, 2).reshape(B, -1, 14)
|
108 |
-
|
109 |
-
pos = self.pos_act(x[..., 0:3]) # [B, N, 3]
|
110 |
-
opacity = self.opacity_act(x[..., 3:4])
|
111 |
-
scale = self.scale_act(x[..., 4:7])
|
112 |
-
rotation = self.rot_act(x[..., 7:11])
|
113 |
-
rgbs = self.rgb_act(x[..., 11:])
|
114 |
-
|
115 |
-
rot_matrix = torch.tensor([[1.0, 0.0, 0.0, 0.0],
|
116 |
-
[0.0, -1.0, 0.0, 0.0],
|
117 |
-
[0.0, 0.0, -1.0, 0.0],
|
118 |
-
[0.0, 0.0, 0.0, 1.0]], dtype=torch.float32, device=images.device)
|
119 |
-
|
120 |
-
pos_4d = torch.cat([pos, torch.ones_like(pos[..., :1])], dim=-1)
|
121 |
-
pos = torch.matmul(pos_4d, rot_matrix) # [B, N, 4]
|
122 |
-
pos = pos[..., :3]
|
123 |
-
|
124 |
-
rotation = torch.matmul(rotation, rot_matrix)
|
125 |
-
|
126 |
-
gaussians = torch.cat([pos, opacity, scale, rotation, rgbs], dim=-1) # [B, N, 14]
|
127 |
-
|
128 |
-
return gaussians
|
129 |
-
|
130 |
-
|
131 |
-
def forward(self, data, step_ratio=1):
|
132 |
-
# data: output of the dataloader
|
133 |
-
# return: loss
|
134 |
-
|
135 |
-
results = {}
|
136 |
-
loss = 0
|
137 |
-
|
138 |
-
images = data['input'] # [B, 4, 9, h, W], input features
|
139 |
-
|
140 |
-
# use the first view to predict gaussians
|
141 |
-
gaussians = self.forward_gaussians(images) # [B, N, 14]
|
142 |
-
|
143 |
-
results['gaussians'] = gaussians
|
144 |
-
|
145 |
-
# random bg for training
|
146 |
-
if self.training:
|
147 |
-
bg_color = torch.rand(3, dtype=torch.float32, device=gaussians.device)
|
148 |
-
else:
|
149 |
-
bg_color = torch.ones(3, dtype=torch.float32, device=gaussians.device)
|
150 |
-
|
151 |
-
# use the other views for rendering and supervision
|
152 |
-
results = self.gs.render(gaussians, data['cam_view'], data['cam_view_proj'], data['cam_pos'], bg_color=bg_color)
|
153 |
-
pred_images = results['image'] # [B, V, C, output_size, output_size]
|
154 |
-
pred_alphas = results['alpha'] # [B, V, 1, output_size, output_size]
|
155 |
-
|
156 |
-
results['images_pred'] = pred_images
|
157 |
-
results['alphas_pred'] = pred_alphas
|
158 |
-
|
159 |
-
gt_images = data['images_output'] # [B, V, 3, output_size, output_size], ground-truth novel views
|
160 |
-
gt_masks = data['masks_output'] # [B, V, 1, output_size, output_size], ground-truth masks
|
161 |
-
|
162 |
-
gt_images = gt_images * gt_masks + bg_color.view(1, 1, 3, 1, 1) * (1 - gt_masks)
|
163 |
-
|
164 |
-
loss_mse = F.mse_loss(pred_images, gt_images) + F.mse_loss(pred_alphas, gt_masks)
|
165 |
-
loss = loss + loss_mse
|
166 |
-
|
167 |
-
if self.opt.lambda_lpips > 0:
|
168 |
-
loss_lpips = self.lpips_loss(
|
169 |
-
# gt_images.view(-1, 3, self.opt.output_size, self.opt.output_size) * 2 - 1,
|
170 |
-
# pred_images.view(-1, 3, self.opt.output_size, self.opt.output_size) * 2 - 1,
|
171 |
-
# downsampled to at most 256 to reduce memory cost
|
172 |
-
F.interpolate(gt_images.view(-1, 3, self.opt.output_size, self.opt.output_size) * 2 - 1, (256, 256), mode='bilinear', align_corners=False),
|
173 |
-
F.interpolate(pred_images.view(-1, 3, self.opt.output_size, self.opt.output_size) * 2 - 1, (256, 256), mode='bilinear', align_corners=False),
|
174 |
-
).mean()
|
175 |
-
results['loss_lpips'] = loss_lpips
|
176 |
-
loss = loss + self.opt.lambda_lpips * loss_lpips
|
177 |
-
|
178 |
-
results['loss'] = loss
|
179 |
-
|
180 |
-
# metric
|
181 |
-
with torch.no_grad():
|
182 |
-
psnr = -10 * torch.log10(torch.mean((pred_images.detach() - gt_images) ** 2))
|
183 |
-
results['psnr'] = psnr
|
184 |
-
|
185 |
-
return results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/options.py
DELETED
@@ -1,120 +0,0 @@
|
|
1 |
-
import tyro
|
2 |
-
from dataclasses import dataclass
|
3 |
-
from typing import Tuple, Literal, Dict, Optional
|
4 |
-
|
5 |
-
|
6 |
-
@dataclass
|
7 |
-
class Options:
|
8 |
-
### model
|
9 |
-
# Unet image input size
|
10 |
-
input_size: int = 256
|
11 |
-
# Unet definition
|
12 |
-
down_channels: Tuple[int] = (64, 128, 256, 512, 1024, 1024)
|
13 |
-
down_attention: Tuple[bool] = (False, False, False, True, True, True)
|
14 |
-
mid_attention: bool = True
|
15 |
-
up_channels: Tuple[int] = (1024, 1024, 512, 256)
|
16 |
-
up_attention: Tuple[bool] = (True, True, True, False)
|
17 |
-
# Unet output size, dependent on the input_size and U-Net structure!
|
18 |
-
splat_size: int = 64
|
19 |
-
# gaussian render size
|
20 |
-
output_size: int = 256
|
21 |
-
|
22 |
-
### dataset
|
23 |
-
# data mode (only support s3 now)
|
24 |
-
data_mode: Literal['s3'] = 's3'
|
25 |
-
# fovy of the dataset
|
26 |
-
fovy: float = 49.1
|
27 |
-
# camera near plane
|
28 |
-
znear: float = 0.5
|
29 |
-
# camera far plane
|
30 |
-
zfar: float = 2.5
|
31 |
-
# number of all views (input + output)
|
32 |
-
num_views: int = 12
|
33 |
-
# number of views
|
34 |
-
num_input_views: int = 4
|
35 |
-
# camera radius
|
36 |
-
cam_radius: float = 1.5 # to better use [-1, 1]^3 space
|
37 |
-
# num workers
|
38 |
-
num_workers: int = 8
|
39 |
-
|
40 |
-
### training
|
41 |
-
# workspace
|
42 |
-
workspace: str = './workspace'
|
43 |
-
# resume
|
44 |
-
resume: Optional[str] = None
|
45 |
-
# batch size (per-GPU)
|
46 |
-
batch_size: int = 8
|
47 |
-
# gradient accumulation
|
48 |
-
gradient_accumulation_steps: int = 1
|
49 |
-
# training epochs
|
50 |
-
num_epochs: int = 30
|
51 |
-
# lpips loss weight
|
52 |
-
lambda_lpips: float = 1.0
|
53 |
-
# gradient clip
|
54 |
-
gradient_clip: float = 1.0
|
55 |
-
# mixed precision
|
56 |
-
mixed_precision: str = 'bf16'
|
57 |
-
# learning rate
|
58 |
-
lr: float = 4e-4
|
59 |
-
# augmentation prob for grid distortion
|
60 |
-
prob_grid_distortion: float = 0.5
|
61 |
-
# augmentation prob for camera jitter
|
62 |
-
prob_cam_jitter: float = 0.5
|
63 |
-
|
64 |
-
### testing
|
65 |
-
# test image path
|
66 |
-
test_path: Optional[str] = None
|
67 |
-
|
68 |
-
### misc
|
69 |
-
# nvdiffrast backend setting
|
70 |
-
force_cuda_rast: bool = False
|
71 |
-
# render fancy video with gaussian scaling effect
|
72 |
-
fancy_video: bool = False
|
73 |
-
|
74 |
-
|
75 |
-
# all the default settings
|
76 |
-
config_defaults: Dict[str, Options] = {}
|
77 |
-
config_doc: Dict[str, str] = {}
|
78 |
-
|
79 |
-
config_doc['lrm'] = 'the default settings for LGM'
|
80 |
-
config_defaults['lrm'] = Options()
|
81 |
-
|
82 |
-
config_doc['small'] = 'small model with lower resolution Gaussians'
|
83 |
-
config_defaults['small'] = Options(
|
84 |
-
input_size=256,
|
85 |
-
splat_size=64,
|
86 |
-
output_size=256,
|
87 |
-
batch_size=8,
|
88 |
-
gradient_accumulation_steps=1,
|
89 |
-
mixed_precision='bf16',
|
90 |
-
)
|
91 |
-
|
92 |
-
config_doc['big'] = 'big model with higher resolution Gaussians'
|
93 |
-
config_defaults['big'] = Options(
|
94 |
-
input_size=256,
|
95 |
-
up_channels=(1024, 1024, 512, 256, 128), # one more decoder
|
96 |
-
up_attention=(True, True, True, False, False),
|
97 |
-
splat_size=128,
|
98 |
-
output_size=512, # render & supervise Gaussians at a higher resolution.
|
99 |
-
batch_size=8,
|
100 |
-
num_views=8,
|
101 |
-
gradient_accumulation_steps=1,
|
102 |
-
mixed_precision='bf16',
|
103 |
-
)
|
104 |
-
|
105 |
-
config_doc['tiny'] = 'tiny model for ablation'
|
106 |
-
config_defaults['tiny'] = Options(
|
107 |
-
input_size=256,
|
108 |
-
down_channels=(32, 64, 128, 256, 512),
|
109 |
-
down_attention=(False, False, False, False, True),
|
110 |
-
up_channels=(512, 256, 128),
|
111 |
-
up_attention=(True, False, False, False),
|
112 |
-
splat_size=64,
|
113 |
-
output_size=256,
|
114 |
-
batch_size=16,
|
115 |
-
num_views=8,
|
116 |
-
gradient_accumulation_steps=1,
|
117 |
-
mixed_precision='bf16',
|
118 |
-
)
|
119 |
-
|
120 |
-
AllConfigs = tyro.extras.subcommand_type_from_defaults(config_defaults, config_doc)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/provider_objaverse.py
DELETED
@@ -1,172 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
import cv2
|
3 |
-
import random
|
4 |
-
import numpy as np
|
5 |
-
|
6 |
-
import torch
|
7 |
-
import torch.nn as nn
|
8 |
-
import torch.nn.functional as F
|
9 |
-
import torchvision.transforms.functional as TF
|
10 |
-
from torch.utils.data import Dataset
|
11 |
-
|
12 |
-
import kiui
|
13 |
-
from core.options import Options
|
14 |
-
from core.utils import get_rays, grid_distortion, orbit_camera_jitter
|
15 |
-
|
16 |
-
IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
|
17 |
-
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)
|
18 |
-
|
19 |
-
|
20 |
-
class ObjaverseDataset(Dataset):
|
21 |
-
|
22 |
-
def _warn(self):
|
23 |
-
raise NotImplementedError('this dataset is just an example and cannot be used directly, you should modify it to your own setting! (search keyword TODO)')
|
24 |
-
|
25 |
-
def __init__(self, opt: Options, training=True):
|
26 |
-
|
27 |
-
self.opt = opt
|
28 |
-
self.training = training
|
29 |
-
|
30 |
-
# TODO: remove this barrier
|
31 |
-
self._warn()
|
32 |
-
|
33 |
-
# TODO: load the list of objects for training
|
34 |
-
self.items = []
|
35 |
-
with open('TODO: file containing the list', 'r') as f:
|
36 |
-
for line in f.readlines():
|
37 |
-
self.items.append(line.strip())
|
38 |
-
|
39 |
-
# naive split
|
40 |
-
if self.training:
|
41 |
-
self.items = self.items[:-self.opt.batch_size]
|
42 |
-
else:
|
43 |
-
self.items = self.items[-self.opt.batch_size:]
|
44 |
-
|
45 |
-
# default camera intrinsics
|
46 |
-
self.tan_half_fov = np.tan(0.5 * np.deg2rad(self.opt.fovy))
|
47 |
-
self.proj_matrix = torch.zeros(4, 4, dtype=torch.float32)
|
48 |
-
self.proj_matrix[0, 0] = 1 / self.tan_half_fov
|
49 |
-
self.proj_matrix[1, 1] = 1 / self.tan_half_fov
|
50 |
-
self.proj_matrix[2, 2] = (self.opt.zfar + self.opt.znear) / (self.opt.zfar - self.opt.znear)
|
51 |
-
self.proj_matrix[3, 2] = - (self.opt.zfar * self.opt.znear) / (self.opt.zfar - self.opt.znear)
|
52 |
-
self.proj_matrix[2, 3] = 1
|
53 |
-
|
54 |
-
|
55 |
-
def __len__(self):
|
56 |
-
return len(self.items)
|
57 |
-
|
58 |
-
def __getitem__(self, idx):
|
59 |
-
|
60 |
-
uid = self.items[idx]
|
61 |
-
results = {}
|
62 |
-
|
63 |
-
# load num_views images
|
64 |
-
images = []
|
65 |
-
masks = []
|
66 |
-
cam_poses = []
|
67 |
-
|
68 |
-
vid_cnt = 0
|
69 |
-
|
70 |
-
# TODO: choose views, based on your rendering settings
|
71 |
-
if self.training:
|
72 |
-
# input views are in (36, 72), other views are randomly selected
|
73 |
-
vids = np.random.permutation(np.arange(36, 73))[:self.opt.num_input_views].tolist() + np.random.permutation(100).tolist()
|
74 |
-
else:
|
75 |
-
# fixed views
|
76 |
-
vids = np.arange(36, 73, 4).tolist() + np.arange(100).tolist()
|
77 |
-
|
78 |
-
for vid in vids:
|
79 |
-
|
80 |
-
image_path = os.path.join(uid, 'rgb', f'{vid:03d}.png')
|
81 |
-
camera_path = os.path.join(uid, 'pose', f'{vid:03d}.txt')
|
82 |
-
|
83 |
-
try:
|
84 |
-
# TODO: load data (modify self.client here)
|
85 |
-
image = np.frombuffer(self.client.get(image_path), np.uint8)
|
86 |
-
image = torch.from_numpy(cv2.imdecode(image, cv2.IMREAD_UNCHANGED).astype(np.float32) / 255) # [512, 512, 4] in [0, 1]
|
87 |
-
c2w = [float(t) for t in self.client.get(camera_path).decode().strip().split(' ')]
|
88 |
-
c2w = torch.tensor(c2w, dtype=torch.float32).reshape(4, 4)
|
89 |
-
except Exception as e:
|
90 |
-
# print(f'[WARN] dataset {uid} {vid}: {e}')
|
91 |
-
continue
|
92 |
-
|
93 |
-
# TODO: you may have a different camera system
|
94 |
-
# blender world + opencv cam --> opengl world & cam
|
95 |
-
c2w[1] *= -1
|
96 |
-
c2w[[1, 2]] = c2w[[2, 1]]
|
97 |
-
c2w[:3, 1:3] *= -1 # invert up and forward direction
|
98 |
-
|
99 |
-
# scale up radius to fully use the [-1, 1]^3 space!
|
100 |
-
c2w[:3, 3] *= self.opt.cam_radius / 1.5 # 1.5 is the default scale
|
101 |
-
|
102 |
-
image = image.permute(2, 0, 1) # [4, 512, 512]
|
103 |
-
mask = image[3:4] # [1, 512, 512]
|
104 |
-
image = image[:3] * mask + (1 - mask) # [3, 512, 512], to white bg
|
105 |
-
image = image[[2,1,0]].contiguous() # bgr to rgb
|
106 |
-
|
107 |
-
images.append(image)
|
108 |
-
masks.append(mask.squeeze(0))
|
109 |
-
cam_poses.append(c2w)
|
110 |
-
|
111 |
-
vid_cnt += 1
|
112 |
-
if vid_cnt == self.opt.num_views:
|
113 |
-
break
|
114 |
-
|
115 |
-
if vid_cnt < self.opt.num_views:
|
116 |
-
print(f'[WARN] dataset {uid}: not enough valid views, only {vid_cnt} views found!')
|
117 |
-
n = self.opt.num_views - vid_cnt
|
118 |
-
images = images + [images[-1]] * n
|
119 |
-
masks = masks + [masks[-1]] * n
|
120 |
-
cam_poses = cam_poses + [cam_poses[-1]] * n
|
121 |
-
|
122 |
-
images = torch.stack(images, dim=0) # [V, C, H, W]
|
123 |
-
masks = torch.stack(masks, dim=0) # [V, H, W]
|
124 |
-
cam_poses = torch.stack(cam_poses, dim=0) # [V, 4, 4]
|
125 |
-
|
126 |
-
# normalized camera feats as in paper (transform the first pose to a fixed position)
|
127 |
-
transform = torch.tensor([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, self.opt.cam_radius], [0, 0, 0, 1]], dtype=torch.float32) @ torch.inverse(cam_poses[0])
|
128 |
-
cam_poses = transform.unsqueeze(0) @ cam_poses # [V, 4, 4]
|
129 |
-
|
130 |
-
images_input = F.interpolate(images[:self.opt.num_input_views].clone(), size=(self.opt.input_size, self.opt.input_size), mode='bilinear', align_corners=False) # [V, C, H, W]
|
131 |
-
cam_poses_input = cam_poses[:self.opt.num_input_views].clone()
|
132 |
-
|
133 |
-
# data augmentation
|
134 |
-
if self.training:
|
135 |
-
# apply random grid distortion to simulate 3D inconsistency
|
136 |
-
if random.random() < self.opt.prob_grid_distortion:
|
137 |
-
images_input[1:] = grid_distortion(images_input[1:])
|
138 |
-
# apply camera jittering (only to input!)
|
139 |
-
if random.random() < self.opt.prob_cam_jitter:
|
140 |
-
cam_poses_input[1:] = orbit_camera_jitter(cam_poses_input[1:])
|
141 |
-
|
142 |
-
images_input = TF.normalize(images_input, IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)
|
143 |
-
|
144 |
-
# resize render ground-truth images, range still in [0, 1]
|
145 |
-
results['images_output'] = F.interpolate(images, size=(self.opt.output_size, self.opt.output_size), mode='bilinear', align_corners=False) # [V, C, output_size, output_size]
|
146 |
-
results['masks_output'] = F.interpolate(masks.unsqueeze(1), size=(self.opt.output_size, self.opt.output_size), mode='bilinear', align_corners=False) # [V, 1, output_size, output_size]
|
147 |
-
|
148 |
-
# build rays for input views
|
149 |
-
rays_embeddings = []
|
150 |
-
for i in range(self.opt.num_input_views):
|
151 |
-
rays_o, rays_d = get_rays(cam_poses_input[i], self.opt.input_size, self.opt.input_size, self.opt.fovy) # [h, w, 3]
|
152 |
-
rays_plucker = torch.cat([torch.cross(rays_o, rays_d, dim=-1), rays_d], dim=-1) # [h, w, 6]
|
153 |
-
rays_embeddings.append(rays_plucker)
|
154 |
-
|
155 |
-
|
156 |
-
rays_embeddings = torch.stack(rays_embeddings, dim=0).permute(0, 3, 1, 2).contiguous() # [V, 6, h, w]
|
157 |
-
final_input = torch.cat([images_input, rays_embeddings], dim=1) # [V=4, 9, H, W]
|
158 |
-
results['input'] = final_input
|
159 |
-
|
160 |
-
# opengl to colmap camera for gaussian renderer
|
161 |
-
cam_poses[:, :3, 1:3] *= -1 # invert up & forward direction
|
162 |
-
|
163 |
-
# cameras needed by gaussian rasterizer
|
164 |
-
cam_view = torch.inverse(cam_poses).transpose(1, 2) # [V, 4, 4]
|
165 |
-
cam_view_proj = cam_view @ self.proj_matrix # [V, 4, 4]
|
166 |
-
cam_pos = - cam_poses[:, :3, 3] # [V, 3]
|
167 |
-
|
168 |
-
results['cam_view'] = cam_view
|
169 |
-
results['cam_view_proj'] = cam_view_proj
|
170 |
-
results['cam_pos'] = cam_pos
|
171 |
-
|
172 |
-
return results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/unet.py
DELETED
@@ -1,319 +0,0 @@
|
|
1 |
-
import torch
|
2 |
-
import torch.nn as nn
|
3 |
-
import torch.nn.functional as F
|
4 |
-
|
5 |
-
import numpy as np
|
6 |
-
from typing import Tuple, Optional, Literal
|
7 |
-
from functools import partial
|
8 |
-
|
9 |
-
from core.attention import MemEffAttention, MemEffCrossAttention
|
10 |
-
|
11 |
-
class MVAttention(nn.Module):
|
12 |
-
def __init__(
|
13 |
-
self,
|
14 |
-
dim: int,
|
15 |
-
num_heads: int = 8,
|
16 |
-
qkv_bias: bool = False,
|
17 |
-
proj_bias: bool = True,
|
18 |
-
attn_drop: float = 0.0,
|
19 |
-
proj_drop: float = 0.0,
|
20 |
-
groups: int = 32,
|
21 |
-
eps: float = 1e-5,
|
22 |
-
residual: bool = True,
|
23 |
-
skip_scale: float = 1,
|
24 |
-
num_frames: int = 4, # WARN: hardcoded!
|
25 |
-
):
|
26 |
-
super().__init__()
|
27 |
-
|
28 |
-
self.residual = residual
|
29 |
-
self.skip_scale = skip_scale
|
30 |
-
self.num_frames = num_frames
|
31 |
-
|
32 |
-
self.norm = nn.GroupNorm(num_groups=groups, num_channels=dim, eps=eps, affine=True)
|
33 |
-
self.attn = MemEffAttention(dim, num_heads, qkv_bias, proj_bias, attn_drop, proj_drop)
|
34 |
-
|
35 |
-
def forward(self, x):
|
36 |
-
# x: [B*V, C, H, W]
|
37 |
-
BV, C, H, W = x.shape
|
38 |
-
B = BV // self.num_frames # assert BV % self.num_frames == 0
|
39 |
-
|
40 |
-
res = x
|
41 |
-
x = self.norm(x)
|
42 |
-
|
43 |
-
x = x.reshape(B, self.num_frames, C, H, W).permute(0, 1, 3, 4, 2).reshape(B, -1, C)
|
44 |
-
x = self.attn(x)
|
45 |
-
x = x.reshape(B, self.num_frames, H, W, C).permute(0, 1, 4, 2, 3).reshape(BV, C, H, W)
|
46 |
-
|
47 |
-
if self.residual:
|
48 |
-
x = (x + res) * self.skip_scale
|
49 |
-
return x
|
50 |
-
|
51 |
-
class ResnetBlock(nn.Module):
|
52 |
-
def __init__(
|
53 |
-
self,
|
54 |
-
in_channels: int,
|
55 |
-
out_channels: int,
|
56 |
-
resample: Literal['default', 'up', 'down'] = 'default',
|
57 |
-
groups: int = 32,
|
58 |
-
eps: float = 1e-5,
|
59 |
-
skip_scale: float = 1, # multiplied to output
|
60 |
-
):
|
61 |
-
super().__init__()
|
62 |
-
|
63 |
-
self.in_channels = in_channels
|
64 |
-
self.out_channels = out_channels
|
65 |
-
self.skip_scale = skip_scale
|
66 |
-
|
67 |
-
self.norm1 = nn.GroupNorm(num_groups=groups, num_channels=in_channels, eps=eps, affine=True)
|
68 |
-
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1)
|
69 |
-
|
70 |
-
self.norm2 = nn.GroupNorm(num_groups=groups, num_channels=out_channels, eps=eps, affine=True)
|
71 |
-
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
|
72 |
-
|
73 |
-
self.act = F.silu
|
74 |
-
|
75 |
-
self.resample = None
|
76 |
-
if resample == 'up':
|
77 |
-
self.resample = partial(F.interpolate, scale_factor=2.0, mode="nearest")
|
78 |
-
elif resample == 'down':
|
79 |
-
self.resample = nn.AvgPool2d(kernel_size=2, stride=2)
|
80 |
-
|
81 |
-
self.shortcut = nn.Identity()
|
82 |
-
if self.in_channels != self.out_channels:
|
83 |
-
self.shortcut = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=True)
|
84 |
-
|
85 |
-
|
86 |
-
def forward(self, x):
|
87 |
-
res = x
|
88 |
-
|
89 |
-
x = self.norm1(x)
|
90 |
-
x = self.act(x)
|
91 |
-
|
92 |
-
if self.resample:
|
93 |
-
res = self.resample(res)
|
94 |
-
x = self.resample(x)
|
95 |
-
|
96 |
-
x = self.conv1(x)
|
97 |
-
x = self.norm2(x)
|
98 |
-
x = self.act(x)
|
99 |
-
x = self.conv2(x)
|
100 |
-
|
101 |
-
x = (x + self.shortcut(res)) * self.skip_scale
|
102 |
-
|
103 |
-
return x
|
104 |
-
|
105 |
-
class DownBlock(nn.Module):
|
106 |
-
def __init__(
|
107 |
-
self,
|
108 |
-
in_channels: int,
|
109 |
-
out_channels: int,
|
110 |
-
num_layers: int = 1,
|
111 |
-
downsample: bool = True,
|
112 |
-
attention: bool = True,
|
113 |
-
attention_heads: int = 16,
|
114 |
-
skip_scale: float = 1,
|
115 |
-
):
|
116 |
-
super().__init__()
|
117 |
-
|
118 |
-
nets = []
|
119 |
-
attns = []
|
120 |
-
for i in range(num_layers):
|
121 |
-
in_channels = in_channels if i == 0 else out_channels
|
122 |
-
nets.append(ResnetBlock(in_channels, out_channels, skip_scale=skip_scale))
|
123 |
-
if attention:
|
124 |
-
attns.append(MVAttention(out_channels, attention_heads, skip_scale=skip_scale))
|
125 |
-
else:
|
126 |
-
attns.append(None)
|
127 |
-
self.nets = nn.ModuleList(nets)
|
128 |
-
self.attns = nn.ModuleList(attns)
|
129 |
-
|
130 |
-
self.downsample = None
|
131 |
-
if downsample:
|
132 |
-
self.downsample = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=2, padding=1)
|
133 |
-
|
134 |
-
def forward(self, x):
|
135 |
-
xs = []
|
136 |
-
|
137 |
-
for attn, net in zip(self.attns, self.nets):
|
138 |
-
x = net(x)
|
139 |
-
if attn:
|
140 |
-
x = attn(x)
|
141 |
-
xs.append(x)
|
142 |
-
|
143 |
-
if self.downsample:
|
144 |
-
x = self.downsample(x)
|
145 |
-
xs.append(x)
|
146 |
-
|
147 |
-
return x, xs
|
148 |
-
|
149 |
-
|
150 |
-
class MidBlock(nn.Module):
|
151 |
-
def __init__(
|
152 |
-
self,
|
153 |
-
in_channels: int,
|
154 |
-
num_layers: int = 1,
|
155 |
-
attention: bool = True,
|
156 |
-
attention_heads: int = 16,
|
157 |
-
skip_scale: float = 1,
|
158 |
-
):
|
159 |
-
super().__init__()
|
160 |
-
|
161 |
-
nets = []
|
162 |
-
attns = []
|
163 |
-
# first layer
|
164 |
-
nets.append(ResnetBlock(in_channels, in_channels, skip_scale=skip_scale))
|
165 |
-
# more layers
|
166 |
-
for i in range(num_layers):
|
167 |
-
nets.append(ResnetBlock(in_channels, in_channels, skip_scale=skip_scale))
|
168 |
-
if attention:
|
169 |
-
attns.append(MVAttention(in_channels, attention_heads, skip_scale=skip_scale))
|
170 |
-
else:
|
171 |
-
attns.append(None)
|
172 |
-
self.nets = nn.ModuleList(nets)
|
173 |
-
self.attns = nn.ModuleList(attns)
|
174 |
-
|
175 |
-
def forward(self, x):
|
176 |
-
x = self.nets[0](x)
|
177 |
-
for attn, net in zip(self.attns, self.nets[1:]):
|
178 |
-
if attn:
|
179 |
-
x = attn(x)
|
180 |
-
x = net(x)
|
181 |
-
return x
|
182 |
-
|
183 |
-
|
184 |
-
class UpBlock(nn.Module):
|
185 |
-
def __init__(
|
186 |
-
self,
|
187 |
-
in_channels: int,
|
188 |
-
prev_out_channels: int,
|
189 |
-
out_channels: int,
|
190 |
-
num_layers: int = 1,
|
191 |
-
upsample: bool = True,
|
192 |
-
attention: bool = True,
|
193 |
-
attention_heads: int = 16,
|
194 |
-
skip_scale: float = 1,
|
195 |
-
):
|
196 |
-
super().__init__()
|
197 |
-
|
198 |
-
nets = []
|
199 |
-
attns = []
|
200 |
-
for i in range(num_layers):
|
201 |
-
cin = in_channels if i == 0 else out_channels
|
202 |
-
cskip = prev_out_channels if (i == num_layers - 1) else out_channels
|
203 |
-
|
204 |
-
nets.append(ResnetBlock(cin + cskip, out_channels, skip_scale=skip_scale))
|
205 |
-
if attention:
|
206 |
-
attns.append(MVAttention(out_channels, attention_heads, skip_scale=skip_scale))
|
207 |
-
else:
|
208 |
-
attns.append(None)
|
209 |
-
self.nets = nn.ModuleList(nets)
|
210 |
-
self.attns = nn.ModuleList(attns)
|
211 |
-
|
212 |
-
self.upsample = None
|
213 |
-
if upsample:
|
214 |
-
self.upsample = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
|
215 |
-
|
216 |
-
def forward(self, x, xs):
|
217 |
-
|
218 |
-
for attn, net in zip(self.attns, self.nets):
|
219 |
-
res_x = xs[-1]
|
220 |
-
xs = xs[:-1]
|
221 |
-
x = torch.cat([x, res_x], dim=1)
|
222 |
-
x = net(x)
|
223 |
-
if attn:
|
224 |
-
x = attn(x)
|
225 |
-
|
226 |
-
if self.upsample:
|
227 |
-
x = F.interpolate(x, scale_factor=2.0, mode='nearest')
|
228 |
-
x = self.upsample(x)
|
229 |
-
|
230 |
-
return x
|
231 |
-
|
232 |
-
|
233 |
-
# it could be asymmetric!
|
234 |
-
class UNet(nn.Module):
|
235 |
-
def __init__(
|
236 |
-
self,
|
237 |
-
in_channels: int = 3,
|
238 |
-
out_channels: int = 3,
|
239 |
-
down_channels: Tuple[int] = (64, 128, 256, 512, 1024),
|
240 |
-
down_attention: Tuple[bool] = (False, False, False, True, True),
|
241 |
-
mid_attention: bool = True,
|
242 |
-
up_channels: Tuple[int] = (1024, 512, 256),
|
243 |
-
up_attention: Tuple[bool] = (True, True, False),
|
244 |
-
layers_per_block: int = 2,
|
245 |
-
skip_scale: float = np.sqrt(0.5),
|
246 |
-
):
|
247 |
-
super().__init__()
|
248 |
-
|
249 |
-
# first
|
250 |
-
self.conv_in = nn.Conv2d(in_channels, down_channels[0], kernel_size=3, stride=1, padding=1)
|
251 |
-
|
252 |
-
# down
|
253 |
-
down_blocks = []
|
254 |
-
cout = down_channels[0]
|
255 |
-
for i in range(len(down_channels)):
|
256 |
-
cin = cout
|
257 |
-
cout = down_channels[i]
|
258 |
-
|
259 |
-
down_blocks.append(DownBlock(
|
260 |
-
cin, cout,
|
261 |
-
num_layers=layers_per_block,
|
262 |
-
downsample=(i != len(down_channels) - 1), # not final layer
|
263 |
-
attention=down_attention[i],
|
264 |
-
skip_scale=skip_scale,
|
265 |
-
))
|
266 |
-
self.down_blocks = nn.ModuleList(down_blocks)
|
267 |
-
|
268 |
-
# mid
|
269 |
-
self.mid_block = MidBlock(down_channels[-1], attention=mid_attention, skip_scale=skip_scale)
|
270 |
-
|
271 |
-
# up
|
272 |
-
up_blocks = []
|
273 |
-
cout = up_channels[0]
|
274 |
-
for i in range(len(up_channels)):
|
275 |
-
cin = cout
|
276 |
-
cout = up_channels[i]
|
277 |
-
cskip = down_channels[max(-2 - i, -len(down_channels))] # for assymetric
|
278 |
-
|
279 |
-
up_blocks.append(UpBlock(
|
280 |
-
cin, cskip, cout,
|
281 |
-
num_layers=layers_per_block + 1, # one more layer for up
|
282 |
-
upsample=(i != len(up_channels) - 1), # not final layer
|
283 |
-
attention=up_attention[i],
|
284 |
-
skip_scale=skip_scale,
|
285 |
-
))
|
286 |
-
self.up_blocks = nn.ModuleList(up_blocks)
|
287 |
-
|
288 |
-
# last
|
289 |
-
self.norm_out = nn.GroupNorm(num_channels=up_channels[-1], num_groups=32, eps=1e-5)
|
290 |
-
self.conv_out = nn.Conv2d(up_channels[-1], out_channels, kernel_size=3, stride=1, padding=1)
|
291 |
-
|
292 |
-
|
293 |
-
def forward(self, x):
|
294 |
-
# x: [B, Cin, H, W]
|
295 |
-
|
296 |
-
# first
|
297 |
-
x = self.conv_in(x)
|
298 |
-
|
299 |
-
# down
|
300 |
-
xss = [x]
|
301 |
-
for block in self.down_blocks:
|
302 |
-
x, xs = block(x)
|
303 |
-
xss.extend(xs)
|
304 |
-
|
305 |
-
# mid
|
306 |
-
x = self.mid_block(x)
|
307 |
-
|
308 |
-
# up
|
309 |
-
for block in self.up_blocks:
|
310 |
-
xs = xss[-len(block.nets):]
|
311 |
-
xss = xss[:-len(block.nets)]
|
312 |
-
x = block(x, xs)
|
313 |
-
|
314 |
-
# last
|
315 |
-
x = self.norm_out(x)
|
316 |
-
x = F.silu(x)
|
317 |
-
x = self.conv_out(x) # [B, Cout, H', W']
|
318 |
-
|
319 |
-
return x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core/utils.py
DELETED
@@ -1,109 +0,0 @@
|
|
1 |
-
import numpy as np
|
2 |
-
|
3 |
-
import torch
|
4 |
-
import torch.nn as nn
|
5 |
-
import torch.nn.functional as F
|
6 |
-
|
7 |
-
import roma
|
8 |
-
from kiui.op import safe_normalize
|
9 |
-
|
10 |
-
def get_rays(pose, h, w, fovy, opengl=True):
|
11 |
-
|
12 |
-
x, y = torch.meshgrid(
|
13 |
-
torch.arange(w, device=pose.device),
|
14 |
-
torch.arange(h, device=pose.device),
|
15 |
-
indexing="xy",
|
16 |
-
)
|
17 |
-
x = x.flatten()
|
18 |
-
y = y.flatten()
|
19 |
-
|
20 |
-
cx = w * 0.5
|
21 |
-
cy = h * 0.5
|
22 |
-
|
23 |
-
focal = h * 0.5 / np.tan(0.5 * np.deg2rad(fovy))
|
24 |
-
|
25 |
-
camera_dirs = F.pad(
|
26 |
-
torch.stack(
|
27 |
-
[
|
28 |
-
(x - cx + 0.5) / focal,
|
29 |
-
(y - cy + 0.5) / focal * (-1.0 if opengl else 1.0),
|
30 |
-
],
|
31 |
-
dim=-1,
|
32 |
-
),
|
33 |
-
(0, 1),
|
34 |
-
value=(-1.0 if opengl else 1.0),
|
35 |
-
) # [hw, 3]
|
36 |
-
|
37 |
-
rays_d = camera_dirs @ pose[:3, :3].transpose(0, 1) # [hw, 3]
|
38 |
-
rays_o = pose[:3, 3].unsqueeze(0).expand_as(rays_d) # [hw, 3]
|
39 |
-
|
40 |
-
rays_o = rays_o.view(h, w, 3)
|
41 |
-
rays_d = safe_normalize(rays_d).view(h, w, 3)
|
42 |
-
|
43 |
-
return rays_o, rays_d
|
44 |
-
|
45 |
-
def orbit_camera_jitter(poses, strength=0.1):
|
46 |
-
# poses: [B, 4, 4], assume orbit camera in opengl format
|
47 |
-
# random orbital rotate
|
48 |
-
|
49 |
-
B = poses.shape[0]
|
50 |
-
rotvec_x = poses[:, :3, 1] * strength * np.pi * (torch.rand(B, 1, device=poses.device) * 2 - 1)
|
51 |
-
rotvec_y = poses[:, :3, 0] * strength * np.pi / 2 * (torch.rand(B, 1, device=poses.device) * 2 - 1)
|
52 |
-
|
53 |
-
rot = roma.rotvec_to_rotmat(rotvec_x) @ roma.rotvec_to_rotmat(rotvec_y)
|
54 |
-
R = rot @ poses[:, :3, :3]
|
55 |
-
T = rot @ poses[:, :3, 3:]
|
56 |
-
|
57 |
-
new_poses = poses.clone()
|
58 |
-
new_poses[:, :3, :3] = R
|
59 |
-
new_poses[:, :3, 3:] = T
|
60 |
-
|
61 |
-
return new_poses
|
62 |
-
|
63 |
-
def grid_distortion(images, strength=0.5):
|
64 |
-
# images: [B, C, H, W]
|
65 |
-
# num_steps: int, grid resolution for distortion
|
66 |
-
# strength: float in [0, 1], strength of distortion
|
67 |
-
|
68 |
-
B, C, H, W = images.shape
|
69 |
-
|
70 |
-
num_steps = np.random.randint(8, 17)
|
71 |
-
grid_steps = torch.linspace(-1, 1, num_steps)
|
72 |
-
|
73 |
-
# have to loop batch...
|
74 |
-
grids = []
|
75 |
-
for b in range(B):
|
76 |
-
# construct displacement
|
77 |
-
x_steps = torch.linspace(0, 1, num_steps) # [num_steps], inclusive
|
78 |
-
x_steps = (x_steps + strength * (torch.rand_like(x_steps) - 0.5) / (num_steps - 1)).clamp(0, 1) # perturb
|
79 |
-
x_steps = (x_steps * W).long() # [num_steps]
|
80 |
-
x_steps[0] = 0
|
81 |
-
x_steps[-1] = W
|
82 |
-
xs = []
|
83 |
-
for i in range(num_steps - 1):
|
84 |
-
xs.append(torch.linspace(grid_steps[i], grid_steps[i + 1], x_steps[i + 1] - x_steps[i]))
|
85 |
-
xs = torch.cat(xs, dim=0) # [W]
|
86 |
-
|
87 |
-
y_steps = torch.linspace(0, 1, num_steps) # [num_steps], inclusive
|
88 |
-
y_steps = (y_steps + strength * (torch.rand_like(y_steps) - 0.5) / (num_steps - 1)).clamp(0, 1) # perturb
|
89 |
-
y_steps = (y_steps * H).long() # [num_steps]
|
90 |
-
y_steps[0] = 0
|
91 |
-
y_steps[-1] = H
|
92 |
-
ys = []
|
93 |
-
for i in range(num_steps - 1):
|
94 |
-
ys.append(torch.linspace(grid_steps[i], grid_steps[i + 1], y_steps[i + 1] - y_steps[i]))
|
95 |
-
ys = torch.cat(ys, dim=0) # [H]
|
96 |
-
|
97 |
-
# construct grid
|
98 |
-
grid_x, grid_y = torch.meshgrid(xs, ys, indexing='xy') # [H, W]
|
99 |
-
grid = torch.stack([grid_x, grid_y], dim=-1) # [H, W, 2]
|
100 |
-
|
101 |
-
grids.append(grid)
|
102 |
-
|
103 |
-
grids = torch.stack(grids, dim=0).to(images.device) # [B, H, W, 2]
|
104 |
-
|
105 |
-
# grid sample
|
106 |
-
images = F.grid_sample(images, grids, align_corners=False)
|
107 |
-
|
108 |
-
return images
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
Subproject commit d986da0d4cf2dfeb43b9a379b6e9fa0a7f3f7eea
|
diff-gaussian-rasterization/.gitignore
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
build/
|
2 |
-
diff_gaussian_rasterization.egg-info/
|
3 |
-
dist/
|
4 |
-
|
5 |
-
__pycache__
|
6 |
-
|
7 |
-
*.so
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/.gitmodules
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
[submodule "third_party/glm"]
|
2 |
-
path = third_party/glm
|
3 |
-
url = https://github.com/g-truc/glm.git
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/CMakeLists.txt
DELETED
@@ -1,36 +0,0 @@
|
|
1 |
-
#
|
2 |
-
# Copyright (C) 2023, Inria
|
3 |
-
# GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
# All rights reserved.
|
5 |
-
#
|
6 |
-
# This software is free for non-commercial, research and evaluation use
|
7 |
-
# under the terms of the LICENSE.md file.
|
8 |
-
#
|
9 |
-
# For inquiries contact george.drettakis@inria.fr
|
10 |
-
#
|
11 |
-
|
12 |
-
cmake_minimum_required(VERSION 3.20)
|
13 |
-
|
14 |
-
project(DiffRast LANGUAGES CUDA CXX)
|
15 |
-
|
16 |
-
set(CMAKE_CXX_STANDARD 17)
|
17 |
-
set(CMAKE_CXX_EXTENSIONS OFF)
|
18 |
-
set(CMAKE_CUDA_STANDARD 17)
|
19 |
-
|
20 |
-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
21 |
-
|
22 |
-
add_library(CudaRasterizer
|
23 |
-
cuda_rasterizer/backward.h
|
24 |
-
cuda_rasterizer/backward.cu
|
25 |
-
cuda_rasterizer/forward.h
|
26 |
-
cuda_rasterizer/forward.cu
|
27 |
-
cuda_rasterizer/auxiliary.h
|
28 |
-
cuda_rasterizer/rasterizer_impl.cu
|
29 |
-
cuda_rasterizer/rasterizer_impl.h
|
30 |
-
cuda_rasterizer/rasterizer.h
|
31 |
-
)
|
32 |
-
|
33 |
-
set_target_properties(CudaRasterizer PROPERTIES CUDA_ARCHITECTURES "75;86")
|
34 |
-
|
35 |
-
target_include_directories(CudaRasterizer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/cuda_rasterizer)
|
36 |
-
target_include_directories(CudaRasterizer PRIVATE third_party/glm ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/LICENSE.md
DELETED
@@ -1,83 +0,0 @@
|
|
1 |
-
Gaussian-Splatting License
|
2 |
-
===========================
|
3 |
-
|
4 |
-
**Inria** and **the Max Planck Institut for Informatik (MPII)** hold all the ownership rights on the *Software* named **gaussian-splatting**.
|
5 |
-
The *Software* is in the process of being registered with the Agence pour la Protection des
|
6 |
-
Programmes (APP).
|
7 |
-
|
8 |
-
The *Software* is still being developed by the *Licensor*.
|
9 |
-
|
10 |
-
*Licensor*'s goal is to allow the research community to use, test and evaluate
|
11 |
-
the *Software*.
|
12 |
-
|
13 |
-
## 1. Definitions
|
14 |
-
|
15 |
-
*Licensee* means any person or entity that uses the *Software* and distributes
|
16 |
-
its *Work*.
|
17 |
-
|
18 |
-
*Licensor* means the owners of the *Software*, i.e Inria and MPII
|
19 |
-
|
20 |
-
*Software* means the original work of authorship made available under this
|
21 |
-
License ie gaussian-splatting.
|
22 |
-
|
23 |
-
*Work* means the *Software* and any additions to or derivative works of the
|
24 |
-
*Software* that are made available under this License.
|
25 |
-
|
26 |
-
|
27 |
-
## 2. Purpose
|
28 |
-
This license is intended to define the rights granted to the *Licensee* by
|
29 |
-
Licensors under the *Software*.
|
30 |
-
|
31 |
-
## 3. Rights granted
|
32 |
-
|
33 |
-
For the above reasons Licensors have decided to distribute the *Software*.
|
34 |
-
Licensors grant non-exclusive rights to use the *Software* for research purposes
|
35 |
-
to research users (both academic and industrial), free of charge, without right
|
36 |
-
to sublicense.. The *Software* may be used "non-commercially", i.e., for research
|
37 |
-
and/or evaluation purposes only.
|
38 |
-
|
39 |
-
Subject to the terms and conditions of this License, you are granted a
|
40 |
-
non-exclusive, royalty-free, license to reproduce, prepare derivative works of,
|
41 |
-
publicly display, publicly perform and distribute its *Work* and any resulting
|
42 |
-
derivative works in any form.
|
43 |
-
|
44 |
-
## 4. Limitations
|
45 |
-
|
46 |
-
**4.1 Redistribution.** You may reproduce or distribute the *Work* only if (a) you do
|
47 |
-
so under this License, (b) you include a complete copy of this License with
|
48 |
-
your distribution, and (c) you retain without modification any copyright,
|
49 |
-
patent, trademark, or attribution notices that are present in the *Work*.
|
50 |
-
|
51 |
-
**4.2 Derivative Works.** You may specify that additional or different terms apply
|
52 |
-
to the use, reproduction, and distribution of your derivative works of the *Work*
|
53 |
-
("Your Terms") only if (a) Your Terms provide that the use limitation in
|
54 |
-
Section 2 applies to your derivative works, and (b) you identify the specific
|
55 |
-
derivative works that are subject to Your Terms. Notwithstanding Your Terms,
|
56 |
-
this License (including the redistribution requirements in Section 3.1) will
|
57 |
-
continue to apply to the *Work* itself.
|
58 |
-
|
59 |
-
**4.3** Any other use without of prior consent of Licensors is prohibited. Research
|
60 |
-
users explicitly acknowledge having received from Licensors all information
|
61 |
-
allowing to appreciate the adequacy between of the *Software* and their needs and
|
62 |
-
to undertake all necessary precautions for its execution and use.
|
63 |
-
|
64 |
-
**4.4** The *Software* is provided both as a compiled library file and as source
|
65 |
-
code. In case of using the *Software* for a publication or other results obtained
|
66 |
-
through the use of the *Software*, users are strongly encouraged to cite the
|
67 |
-
corresponding publications as explained in the documentation of the *Software*.
|
68 |
-
|
69 |
-
## 5. Disclaimer
|
70 |
-
|
71 |
-
THE USER CANNOT USE, EXPLOIT OR DISTRIBUTE THE *SOFTWARE* FOR COMMERCIAL PURPOSES
|
72 |
-
WITHOUT PRIOR AND EXPLICIT CONSENT OF LICENSORS. YOU MUST CONTACT INRIA FOR ANY
|
73 |
-
UNAUTHORIZED USE: stip-sophia.transfert@inria.fr . ANY SUCH ACTION WILL
|
74 |
-
CONSTITUTE A FORGERY. THIS *SOFTWARE* IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES
|
75 |
-
OF ANY NATURE AND ANY EXPRESS OR IMPLIED WARRANTIES, WITH REGARDS TO COMMERCIAL
|
76 |
-
USE, PROFESSIONNAL USE, LEGAL OR NOT, OR OTHER, OR COMMERCIALISATION OR
|
77 |
-
ADAPTATION. UNLESS EXPLICITLY PROVIDED BY LAW, IN NO EVENT, SHALL INRIA OR THE
|
78 |
-
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
79 |
-
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
80 |
-
GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
81 |
-
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
82 |
-
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING FROM, OUT OF OR
|
83 |
-
IN CONNECTION WITH THE *SOFTWARE* OR THE USE OR OTHER DEALINGS IN THE *SOFTWARE*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/README.md
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
# Differential Gaussian Rasterization
|
2 |
-
|
3 |
-
**NOTE**: this is a modified version to support depth & alpha rendering (both forward and backward) from the [original repository](https://github.com/graphdeco-inria/diff-gaussian-rasterization).
|
4 |
-
|
5 |
-
```python
|
6 |
-
rendered_image, radii, rendered_depth, rendered_alpha = rasterizer(
|
7 |
-
means3D=means3D,
|
8 |
-
means2D=means2D,
|
9 |
-
shs=shs,
|
10 |
-
colors_precomp=colors_precomp,
|
11 |
-
opacities=opacity,
|
12 |
-
scales=scales,
|
13 |
-
rotations=rotations,
|
14 |
-
cov3D_precomp=cov3D_precomp,
|
15 |
-
)
|
16 |
-
```
|
17 |
-
|
18 |
-
|
19 |
-
Used as the rasterization engine for the paper "3D Gaussian Splatting for Real-Time Rendering of Radiance Fields". If you can make use of it in your own research, please be so kind to cite us.
|
20 |
-
|
21 |
-
<section class="section" id="BibTeX">
|
22 |
-
<div class="container is-max-desktop content">
|
23 |
-
<h2 class="title">BibTeX</h2>
|
24 |
-
<pre><code>@Article{kerbl3Dgaussians,
|
25 |
-
author = {Kerbl, Bernhard and Kopanas, Georgios and Leimk{\"u}hler, Thomas and Drettakis, George},
|
26 |
-
title = {3D Gaussian Splatting for Real-Time Radiance Field Rendering},
|
27 |
-
journal = {ACM Transactions on Graphics},
|
28 |
-
number = {4},
|
29 |
-
volume = {42},
|
30 |
-
month = {July},
|
31 |
-
year = {2023},
|
32 |
-
url = {https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/}
|
33 |
-
}</code></pre>
|
34 |
-
</div>
|
35 |
-
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/auxiliary.h
DELETED
@@ -1,175 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#ifndef CUDA_RASTERIZER_AUXILIARY_H_INCLUDED
|
13 |
-
#define CUDA_RASTERIZER_AUXILIARY_H_INCLUDED
|
14 |
-
|
15 |
-
#include "config.h"
|
16 |
-
#include "stdio.h"
|
17 |
-
|
18 |
-
#define BLOCK_SIZE (BLOCK_X * BLOCK_Y)
|
19 |
-
#define NUM_WARPS (BLOCK_SIZE/32)
|
20 |
-
|
21 |
-
// Spherical harmonics coefficients
|
22 |
-
__device__ const float SH_C0 = 0.28209479177387814f;
|
23 |
-
__device__ const float SH_C1 = 0.4886025119029199f;
|
24 |
-
__device__ const float SH_C2[] = {
|
25 |
-
1.0925484305920792f,
|
26 |
-
-1.0925484305920792f,
|
27 |
-
0.31539156525252005f,
|
28 |
-
-1.0925484305920792f,
|
29 |
-
0.5462742152960396f
|
30 |
-
};
|
31 |
-
__device__ const float SH_C3[] = {
|
32 |
-
-0.5900435899266435f,
|
33 |
-
2.890611442640554f,
|
34 |
-
-0.4570457994644658f,
|
35 |
-
0.3731763325901154f,
|
36 |
-
-0.4570457994644658f,
|
37 |
-
1.445305721320277f,
|
38 |
-
-0.5900435899266435f
|
39 |
-
};
|
40 |
-
|
41 |
-
__forceinline__ __device__ float ndc2Pix(float v, int S)
|
42 |
-
{
|
43 |
-
return ((v + 1.0) * S - 1.0) * 0.5;
|
44 |
-
}
|
45 |
-
|
46 |
-
__forceinline__ __device__ void getRect(const float2 p, int max_radius, uint2& rect_min, uint2& rect_max, dim3 grid)
|
47 |
-
{
|
48 |
-
rect_min = {
|
49 |
-
min(grid.x, max((int)0, (int)((p.x - max_radius) / BLOCK_X))),
|
50 |
-
min(grid.y, max((int)0, (int)((p.y - max_radius) / BLOCK_Y)))
|
51 |
-
};
|
52 |
-
rect_max = {
|
53 |
-
min(grid.x, max((int)0, (int)((p.x + max_radius + BLOCK_X - 1) / BLOCK_X))),
|
54 |
-
min(grid.y, max((int)0, (int)((p.y + max_radius + BLOCK_Y - 1) / BLOCK_Y)))
|
55 |
-
};
|
56 |
-
}
|
57 |
-
|
58 |
-
__forceinline__ __device__ float3 transformPoint4x3(const float3& p, const float* matrix)
|
59 |
-
{
|
60 |
-
float3 transformed = {
|
61 |
-
matrix[0] * p.x + matrix[4] * p.y + matrix[8] * p.z + matrix[12],
|
62 |
-
matrix[1] * p.x + matrix[5] * p.y + matrix[9] * p.z + matrix[13],
|
63 |
-
matrix[2] * p.x + matrix[6] * p.y + matrix[10] * p.z + matrix[14],
|
64 |
-
};
|
65 |
-
return transformed;
|
66 |
-
}
|
67 |
-
|
68 |
-
__forceinline__ __device__ float4 transformPoint4x4(const float3& p, const float* matrix)
|
69 |
-
{
|
70 |
-
float4 transformed = {
|
71 |
-
matrix[0] * p.x + matrix[4] * p.y + matrix[8] * p.z + matrix[12],
|
72 |
-
matrix[1] * p.x + matrix[5] * p.y + matrix[9] * p.z + matrix[13],
|
73 |
-
matrix[2] * p.x + matrix[6] * p.y + matrix[10] * p.z + matrix[14],
|
74 |
-
matrix[3] * p.x + matrix[7] * p.y + matrix[11] * p.z + matrix[15]
|
75 |
-
};
|
76 |
-
return transformed;
|
77 |
-
}
|
78 |
-
|
79 |
-
__forceinline__ __device__ float3 transformVec4x3(const float3& p, const float* matrix)
|
80 |
-
{
|
81 |
-
float3 transformed = {
|
82 |
-
matrix[0] * p.x + matrix[4] * p.y + matrix[8] * p.z,
|
83 |
-
matrix[1] * p.x + matrix[5] * p.y + matrix[9] * p.z,
|
84 |
-
matrix[2] * p.x + matrix[6] * p.y + matrix[10] * p.z,
|
85 |
-
};
|
86 |
-
return transformed;
|
87 |
-
}
|
88 |
-
|
89 |
-
__forceinline__ __device__ float3 transformVec4x3Transpose(const float3& p, const float* matrix)
|
90 |
-
{
|
91 |
-
float3 transformed = {
|
92 |
-
matrix[0] * p.x + matrix[1] * p.y + matrix[2] * p.z,
|
93 |
-
matrix[4] * p.x + matrix[5] * p.y + matrix[6] * p.z,
|
94 |
-
matrix[8] * p.x + matrix[9] * p.y + matrix[10] * p.z,
|
95 |
-
};
|
96 |
-
return transformed;
|
97 |
-
}
|
98 |
-
|
99 |
-
__forceinline__ __device__ float dnormvdz(float3 v, float3 dv)
|
100 |
-
{
|
101 |
-
float sum2 = v.x * v.x + v.y * v.y + v.z * v.z;
|
102 |
-
float invsum32 = 1.0f / sqrt(sum2 * sum2 * sum2);
|
103 |
-
float dnormvdz = (-v.x * v.z * dv.x - v.y * v.z * dv.y + (sum2 - v.z * v.z) * dv.z) * invsum32;
|
104 |
-
return dnormvdz;
|
105 |
-
}
|
106 |
-
|
107 |
-
__forceinline__ __device__ float3 dnormvdv(float3 v, float3 dv)
|
108 |
-
{
|
109 |
-
float sum2 = v.x * v.x + v.y * v.y + v.z * v.z;
|
110 |
-
float invsum32 = 1.0f / sqrt(sum2 * sum2 * sum2);
|
111 |
-
|
112 |
-
float3 dnormvdv;
|
113 |
-
dnormvdv.x = ((+sum2 - v.x * v.x) * dv.x - v.y * v.x * dv.y - v.z * v.x * dv.z) * invsum32;
|
114 |
-
dnormvdv.y = (-v.x * v.y * dv.x + (sum2 - v.y * v.y) * dv.y - v.z * v.y * dv.z) * invsum32;
|
115 |
-
dnormvdv.z = (-v.x * v.z * dv.x - v.y * v.z * dv.y + (sum2 - v.z * v.z) * dv.z) * invsum32;
|
116 |
-
return dnormvdv;
|
117 |
-
}
|
118 |
-
|
119 |
-
__forceinline__ __device__ float4 dnormvdv(float4 v, float4 dv)
|
120 |
-
{
|
121 |
-
float sum2 = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
|
122 |
-
float invsum32 = 1.0f / sqrt(sum2 * sum2 * sum2);
|
123 |
-
|
124 |
-
float4 vdv = { v.x * dv.x, v.y * dv.y, v.z * dv.z, v.w * dv.w };
|
125 |
-
float vdv_sum = vdv.x + vdv.y + vdv.z + vdv.w;
|
126 |
-
float4 dnormvdv;
|
127 |
-
dnormvdv.x = ((sum2 - v.x * v.x) * dv.x - v.x * (vdv_sum - vdv.x)) * invsum32;
|
128 |
-
dnormvdv.y = ((sum2 - v.y * v.y) * dv.y - v.y * (vdv_sum - vdv.y)) * invsum32;
|
129 |
-
dnormvdv.z = ((sum2 - v.z * v.z) * dv.z - v.z * (vdv_sum - vdv.z)) * invsum32;
|
130 |
-
dnormvdv.w = ((sum2 - v.w * v.w) * dv.w - v.w * (vdv_sum - vdv.w)) * invsum32;
|
131 |
-
return dnormvdv;
|
132 |
-
}
|
133 |
-
|
134 |
-
__forceinline__ __device__ float sigmoid(float x)
|
135 |
-
{
|
136 |
-
return 1.0f / (1.0f + expf(-x));
|
137 |
-
}
|
138 |
-
|
139 |
-
__forceinline__ __device__ bool in_frustum(int idx,
|
140 |
-
const float* orig_points,
|
141 |
-
const float* viewmatrix,
|
142 |
-
const float* projmatrix,
|
143 |
-
bool prefiltered,
|
144 |
-
float3& p_view)
|
145 |
-
{
|
146 |
-
float3 p_orig = { orig_points[3 * idx], orig_points[3 * idx + 1], orig_points[3 * idx + 2] };
|
147 |
-
|
148 |
-
// Bring points to screen space
|
149 |
-
float4 p_hom = transformPoint4x4(p_orig, projmatrix);
|
150 |
-
float p_w = 1.0f / (p_hom.w + 0.0000001f);
|
151 |
-
float3 p_proj = { p_hom.x * p_w, p_hom.y * p_w, p_hom.z * p_w };
|
152 |
-
p_view = transformPoint4x3(p_orig, viewmatrix);
|
153 |
-
|
154 |
-
if (p_view.z <= 0.2f)// || ((p_proj.x < -1.3 || p_proj.x > 1.3 || p_proj.y < -1.3 || p_proj.y > 1.3)))
|
155 |
-
{
|
156 |
-
if (prefiltered)
|
157 |
-
{
|
158 |
-
printf("Point is filtered although prefiltered is set. This shouldn't happen!");
|
159 |
-
__trap();
|
160 |
-
}
|
161 |
-
return false;
|
162 |
-
}
|
163 |
-
return true;
|
164 |
-
}
|
165 |
-
|
166 |
-
#define CHECK_CUDA(A, debug) \
|
167 |
-
A; if(debug) { \
|
168 |
-
auto ret = cudaDeviceSynchronize(); \
|
169 |
-
if (ret != cudaSuccess) { \
|
170 |
-
std::cerr << "\n[CUDA ERROR] in " << __FILE__ << "\nLine " << __LINE__ << ": " << cudaGetErrorString(ret); \
|
171 |
-
throw std::runtime_error(cudaGetErrorString(ret)); \
|
172 |
-
} \
|
173 |
-
}
|
174 |
-
|
175 |
-
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/backward.cu
DELETED
@@ -1,712 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#include "backward.h"
|
13 |
-
#include "auxiliary.h"
|
14 |
-
#include <cooperative_groups.h>
|
15 |
-
#include <cooperative_groups/reduce.h>
|
16 |
-
namespace cg = cooperative_groups;
|
17 |
-
|
18 |
-
// Backward pass for conversion of spherical harmonics to RGB for
|
19 |
-
// each Gaussian.
|
20 |
-
__device__ void computeColorFromSH(int idx, int deg, int max_coeffs, const glm::vec3* means, glm::vec3 campos, const float* shs, const bool* clamped, const glm::vec3* dL_dcolor, glm::vec3* dL_dmeans, glm::vec3* dL_dshs)
|
21 |
-
{
|
22 |
-
// Compute intermediate values, as it is done during forward
|
23 |
-
glm::vec3 pos = means[idx];
|
24 |
-
glm::vec3 dir_orig = pos - campos;
|
25 |
-
glm::vec3 dir = dir_orig / glm::length(dir_orig);
|
26 |
-
|
27 |
-
glm::vec3* sh = ((glm::vec3*)shs) + idx * max_coeffs;
|
28 |
-
|
29 |
-
// Use PyTorch rule for clamping: if clamping was applied,
|
30 |
-
// gradient becomes 0.
|
31 |
-
glm::vec3 dL_dRGB = dL_dcolor[idx];
|
32 |
-
dL_dRGB.x *= clamped[3 * idx + 0] ? 0 : 1;
|
33 |
-
dL_dRGB.y *= clamped[3 * idx + 1] ? 0 : 1;
|
34 |
-
dL_dRGB.z *= clamped[3 * idx + 2] ? 0 : 1;
|
35 |
-
|
36 |
-
glm::vec3 dRGBdx(0, 0, 0);
|
37 |
-
glm::vec3 dRGBdy(0, 0, 0);
|
38 |
-
glm::vec3 dRGBdz(0, 0, 0);
|
39 |
-
float x = dir.x;
|
40 |
-
float y = dir.y;
|
41 |
-
float z = dir.z;
|
42 |
-
|
43 |
-
// Target location for this Gaussian to write SH gradients to
|
44 |
-
glm::vec3* dL_dsh = dL_dshs + idx * max_coeffs;
|
45 |
-
|
46 |
-
// No tricks here, just high school-level calculus.
|
47 |
-
float dRGBdsh0 = SH_C0;
|
48 |
-
dL_dsh[0] = dRGBdsh0 * dL_dRGB;
|
49 |
-
if (deg > 0)
|
50 |
-
{
|
51 |
-
float dRGBdsh1 = -SH_C1 * y;
|
52 |
-
float dRGBdsh2 = SH_C1 * z;
|
53 |
-
float dRGBdsh3 = -SH_C1 * x;
|
54 |
-
dL_dsh[1] = dRGBdsh1 * dL_dRGB;
|
55 |
-
dL_dsh[2] = dRGBdsh2 * dL_dRGB;
|
56 |
-
dL_dsh[3] = dRGBdsh3 * dL_dRGB;
|
57 |
-
|
58 |
-
dRGBdx = -SH_C1 * sh[3];
|
59 |
-
dRGBdy = -SH_C1 * sh[1];
|
60 |
-
dRGBdz = SH_C1 * sh[2];
|
61 |
-
|
62 |
-
if (deg > 1)
|
63 |
-
{
|
64 |
-
float xx = x * x, yy = y * y, zz = z * z;
|
65 |
-
float xy = x * y, yz = y * z, xz = x * z;
|
66 |
-
|
67 |
-
float dRGBdsh4 = SH_C2[0] * xy;
|
68 |
-
float dRGBdsh5 = SH_C2[1] * yz;
|
69 |
-
float dRGBdsh6 = SH_C2[2] * (2.f * zz - xx - yy);
|
70 |
-
float dRGBdsh7 = SH_C2[3] * xz;
|
71 |
-
float dRGBdsh8 = SH_C2[4] * (xx - yy);
|
72 |
-
dL_dsh[4] = dRGBdsh4 * dL_dRGB;
|
73 |
-
dL_dsh[5] = dRGBdsh5 * dL_dRGB;
|
74 |
-
dL_dsh[6] = dRGBdsh6 * dL_dRGB;
|
75 |
-
dL_dsh[7] = dRGBdsh7 * dL_dRGB;
|
76 |
-
dL_dsh[8] = dRGBdsh8 * dL_dRGB;
|
77 |
-
|
78 |
-
dRGBdx += SH_C2[0] * y * sh[4] + SH_C2[2] * 2.f * -x * sh[6] + SH_C2[3] * z * sh[7] + SH_C2[4] * 2.f * x * sh[8];
|
79 |
-
dRGBdy += SH_C2[0] * x * sh[4] + SH_C2[1] * z * sh[5] + SH_C2[2] * 2.f * -y * sh[6] + SH_C2[4] * 2.f * -y * sh[8];
|
80 |
-
dRGBdz += SH_C2[1] * y * sh[5] + SH_C2[2] * 2.f * 2.f * z * sh[6] + SH_C2[3] * x * sh[7];
|
81 |
-
|
82 |
-
if (deg > 2)
|
83 |
-
{
|
84 |
-
float dRGBdsh9 = SH_C3[0] * y * (3.f * xx - yy);
|
85 |
-
float dRGBdsh10 = SH_C3[1] * xy * z;
|
86 |
-
float dRGBdsh11 = SH_C3[2] * y * (4.f * zz - xx - yy);
|
87 |
-
float dRGBdsh12 = SH_C3[3] * z * (2.f * zz - 3.f * xx - 3.f * yy);
|
88 |
-
float dRGBdsh13 = SH_C3[4] * x * (4.f * zz - xx - yy);
|
89 |
-
float dRGBdsh14 = SH_C3[5] * z * (xx - yy);
|
90 |
-
float dRGBdsh15 = SH_C3[6] * x * (xx - 3.f * yy);
|
91 |
-
dL_dsh[9] = dRGBdsh9 * dL_dRGB;
|
92 |
-
dL_dsh[10] = dRGBdsh10 * dL_dRGB;
|
93 |
-
dL_dsh[11] = dRGBdsh11 * dL_dRGB;
|
94 |
-
dL_dsh[12] = dRGBdsh12 * dL_dRGB;
|
95 |
-
dL_dsh[13] = dRGBdsh13 * dL_dRGB;
|
96 |
-
dL_dsh[14] = dRGBdsh14 * dL_dRGB;
|
97 |
-
dL_dsh[15] = dRGBdsh15 * dL_dRGB;
|
98 |
-
|
99 |
-
dRGBdx += (
|
100 |
-
SH_C3[0] * sh[9] * 3.f * 2.f * xy +
|
101 |
-
SH_C3[1] * sh[10] * yz +
|
102 |
-
SH_C3[2] * sh[11] * -2.f * xy +
|
103 |
-
SH_C3[3] * sh[12] * -3.f * 2.f * xz +
|
104 |
-
SH_C3[4] * sh[13] * (-3.f * xx + 4.f * zz - yy) +
|
105 |
-
SH_C3[5] * sh[14] * 2.f * xz +
|
106 |
-
SH_C3[6] * sh[15] * 3.f * (xx - yy));
|
107 |
-
|
108 |
-
dRGBdy += (
|
109 |
-
SH_C3[0] * sh[9] * 3.f * (xx - yy) +
|
110 |
-
SH_C3[1] * sh[10] * xz +
|
111 |
-
SH_C3[2] * sh[11] * (-3.f * yy + 4.f * zz - xx) +
|
112 |
-
SH_C3[3] * sh[12] * -3.f * 2.f * yz +
|
113 |
-
SH_C3[4] * sh[13] * -2.f * xy +
|
114 |
-
SH_C3[5] * sh[14] * -2.f * yz +
|
115 |
-
SH_C3[6] * sh[15] * -3.f * 2.f * xy);
|
116 |
-
|
117 |
-
dRGBdz += (
|
118 |
-
SH_C3[1] * sh[10] * xy +
|
119 |
-
SH_C3[2] * sh[11] * 4.f * 2.f * yz +
|
120 |
-
SH_C3[3] * sh[12] * 3.f * (2.f * zz - xx - yy) +
|
121 |
-
SH_C3[4] * sh[13] * 4.f * 2.f * xz +
|
122 |
-
SH_C3[5] * sh[14] * (xx - yy));
|
123 |
-
}
|
124 |
-
}
|
125 |
-
}
|
126 |
-
|
127 |
-
// The view direction is an input to the computation. View direction
|
128 |
-
// is influenced by the Gaussian's mean, so SHs gradients
|
129 |
-
// must propagate back into 3D position.
|
130 |
-
glm::vec3 dL_ddir(glm::dot(dRGBdx, dL_dRGB), glm::dot(dRGBdy, dL_dRGB), glm::dot(dRGBdz, dL_dRGB));
|
131 |
-
|
132 |
-
// Account for normalization of direction
|
133 |
-
float3 dL_dmean = dnormvdv(float3{ dir_orig.x, dir_orig.y, dir_orig.z }, float3{ dL_ddir.x, dL_ddir.y, dL_ddir.z });
|
134 |
-
|
135 |
-
// Gradients of loss w.r.t. Gaussian means, but only the portion
|
136 |
-
// that is caused because the mean affects the view-dependent color.
|
137 |
-
// Additional mean gradient is accumulated in below methods.
|
138 |
-
dL_dmeans[idx] += glm::vec3(dL_dmean.x, dL_dmean.y, dL_dmean.z);
|
139 |
-
}
|
140 |
-
|
141 |
-
// Backward version of INVERSE 2D covariance matrix computation
|
142 |
-
// (due to length launched as separate kernel before other
|
143 |
-
// backward steps contained in preprocess)
|
144 |
-
__global__ void computeCov2DCUDA(int P,
|
145 |
-
const float3* means,
|
146 |
-
const int* radii,
|
147 |
-
const float* cov3Ds,
|
148 |
-
const float h_x, float h_y,
|
149 |
-
const float tan_fovx, float tan_fovy,
|
150 |
-
const float* view_matrix,
|
151 |
-
const float* dL_dconics,
|
152 |
-
float3* dL_dmeans,
|
153 |
-
float* dL_dcov)
|
154 |
-
{
|
155 |
-
auto idx = cg::this_grid().thread_rank();
|
156 |
-
if (idx >= P || !(radii[idx] > 0))
|
157 |
-
return;
|
158 |
-
|
159 |
-
// Reading location of 3D covariance for this Gaussian
|
160 |
-
const float* cov3D = cov3Ds + 6 * idx;
|
161 |
-
|
162 |
-
// Fetch gradients, recompute 2D covariance and relevant
|
163 |
-
// intermediate forward results needed in the backward.
|
164 |
-
float3 mean = means[idx];
|
165 |
-
float3 dL_dconic = { dL_dconics[4 * idx], dL_dconics[4 * idx + 1], dL_dconics[4 * idx + 3] };
|
166 |
-
float3 t = transformPoint4x3(mean, view_matrix);
|
167 |
-
|
168 |
-
const float limx = 1.3f * tan_fovx;
|
169 |
-
const float limy = 1.3f * tan_fovy;
|
170 |
-
const float txtz = t.x / t.z;
|
171 |
-
const float tytz = t.y / t.z;
|
172 |
-
t.x = min(limx, max(-limx, txtz)) * t.z;
|
173 |
-
t.y = min(limy, max(-limy, tytz)) * t.z;
|
174 |
-
|
175 |
-
const float x_grad_mul = txtz < -limx || txtz > limx ? 0 : 1;
|
176 |
-
const float y_grad_mul = tytz < -limy || tytz > limy ? 0 : 1;
|
177 |
-
|
178 |
-
glm::mat3 J = glm::mat3(h_x / t.z, 0.0f, -(h_x * t.x) / (t.z * t.z),
|
179 |
-
0.0f, h_y / t.z, -(h_y * t.y) / (t.z * t.z),
|
180 |
-
0, 0, 0);
|
181 |
-
|
182 |
-
glm::mat3 W = glm::mat3(
|
183 |
-
view_matrix[0], view_matrix[4], view_matrix[8],
|
184 |
-
view_matrix[1], view_matrix[5], view_matrix[9],
|
185 |
-
view_matrix[2], view_matrix[6], view_matrix[10]);
|
186 |
-
|
187 |
-
glm::mat3 Vrk = glm::mat3(
|
188 |
-
cov3D[0], cov3D[1], cov3D[2],
|
189 |
-
cov3D[1], cov3D[3], cov3D[4],
|
190 |
-
cov3D[2], cov3D[4], cov3D[5]);
|
191 |
-
|
192 |
-
glm::mat3 T = W * J;
|
193 |
-
|
194 |
-
glm::mat3 cov2D = glm::transpose(T) * glm::transpose(Vrk) * T;
|
195 |
-
|
196 |
-
// Use helper variables for 2D covariance entries. More compact.
|
197 |
-
float a = cov2D[0][0] += 0.3f;
|
198 |
-
float b = cov2D[0][1];
|
199 |
-
float c = cov2D[1][1] += 0.3f;
|
200 |
-
|
201 |
-
float denom = a * c - b * b;
|
202 |
-
float dL_da = 0, dL_db = 0, dL_dc = 0;
|
203 |
-
float denom2inv = 1.0f / ((denom * denom) + 0.0000001f);
|
204 |
-
|
205 |
-
if (denom2inv != 0)
|
206 |
-
{
|
207 |
-
// Gradients of loss w.r.t. entries of 2D covariance matrix,
|
208 |
-
// given gradients of loss w.r.t. conic matrix (inverse covariance matrix).
|
209 |
-
// e.g., dL / da = dL / d_conic_a * d_conic_a / d_a
|
210 |
-
dL_da = denom2inv * (-c * c * dL_dconic.x + 2 * b * c * dL_dconic.y + (denom - a * c) * dL_dconic.z);
|
211 |
-
dL_dc = denom2inv * (-a * a * dL_dconic.z + 2 * a * b * dL_dconic.y + (denom - a * c) * dL_dconic.x);
|
212 |
-
dL_db = denom2inv * 2 * (b * c * dL_dconic.x - (denom + 2 * b * b) * dL_dconic.y + a * b * dL_dconic.z);
|
213 |
-
|
214 |
-
// Gradients of loss L w.r.t. each 3D covariance matrix (Vrk) entry,
|
215 |
-
// given gradients w.r.t. 2D covariance matrix (diagonal).
|
216 |
-
// cov2D = transpose(T) * transpose(Vrk) * T;
|
217 |
-
dL_dcov[6 * idx + 0] = (T[0][0] * T[0][0] * dL_da + T[0][0] * T[1][0] * dL_db + T[1][0] * T[1][0] * dL_dc);
|
218 |
-
dL_dcov[6 * idx + 3] = (T[0][1] * T[0][1] * dL_da + T[0][1] * T[1][1] * dL_db + T[1][1] * T[1][1] * dL_dc);
|
219 |
-
dL_dcov[6 * idx + 5] = (T[0][2] * T[0][2] * dL_da + T[0][2] * T[1][2] * dL_db + T[1][2] * T[1][2] * dL_dc);
|
220 |
-
|
221 |
-
// Gradients of loss L w.r.t. each 3D covariance matrix (Vrk) entry,
|
222 |
-
// given gradients w.r.t. 2D covariance matrix (off-diagonal).
|
223 |
-
// Off-diagonal elements appear twice --> double the gradient.
|
224 |
-
// cov2D = transpose(T) * transpose(Vrk) * T;
|
225 |
-
dL_dcov[6 * idx + 1] = 2 * T[0][0] * T[0][1] * dL_da + (T[0][0] * T[1][1] + T[0][1] * T[1][0]) * dL_db + 2 * T[1][0] * T[1][1] * dL_dc;
|
226 |
-
dL_dcov[6 * idx + 2] = 2 * T[0][0] * T[0][2] * dL_da + (T[0][0] * T[1][2] + T[0][2] * T[1][0]) * dL_db + 2 * T[1][0] * T[1][2] * dL_dc;
|
227 |
-
dL_dcov[6 * idx + 4] = 2 * T[0][2] * T[0][1] * dL_da + (T[0][1] * T[1][2] + T[0][2] * T[1][1]) * dL_db + 2 * T[1][1] * T[1][2] * dL_dc;
|
228 |
-
}
|
229 |
-
else
|
230 |
-
{
|
231 |
-
for (int i = 0; i < 6; i++)
|
232 |
-
dL_dcov[6 * idx + i] = 0;
|
233 |
-
}
|
234 |
-
|
235 |
-
// Gradients of loss w.r.t. upper 2x3 portion of intermediate matrix T
|
236 |
-
// cov2D = transpose(T) * transpose(Vrk) * T;
|
237 |
-
float dL_dT00 = 2 * (T[0][0] * Vrk[0][0] + T[0][1] * Vrk[0][1] + T[0][2] * Vrk[0][2]) * dL_da +
|
238 |
-
(T[1][0] * Vrk[0][0] + T[1][1] * Vrk[0][1] + T[1][2] * Vrk[0][2]) * dL_db;
|
239 |
-
float dL_dT01 = 2 * (T[0][0] * Vrk[1][0] + T[0][1] * Vrk[1][1] + T[0][2] * Vrk[1][2]) * dL_da +
|
240 |
-
(T[1][0] * Vrk[1][0] + T[1][1] * Vrk[1][1] + T[1][2] * Vrk[1][2]) * dL_db;
|
241 |
-
float dL_dT02 = 2 * (T[0][0] * Vrk[2][0] + T[0][1] * Vrk[2][1] + T[0][2] * Vrk[2][2]) * dL_da +
|
242 |
-
(T[1][0] * Vrk[2][0] + T[1][1] * Vrk[2][1] + T[1][2] * Vrk[2][2]) * dL_db;
|
243 |
-
float dL_dT10 = 2 * (T[1][0] * Vrk[0][0] + T[1][1] * Vrk[0][1] + T[1][2] * Vrk[0][2]) * dL_dc +
|
244 |
-
(T[0][0] * Vrk[0][0] + T[0][1] * Vrk[0][1] + T[0][2] * Vrk[0][2]) * dL_db;
|
245 |
-
float dL_dT11 = 2 * (T[1][0] * Vrk[1][0] + T[1][1] * Vrk[1][1] + T[1][2] * Vrk[1][2]) * dL_dc +
|
246 |
-
(T[0][0] * Vrk[1][0] + T[0][1] * Vrk[1][1] + T[0][2] * Vrk[1][2]) * dL_db;
|
247 |
-
float dL_dT12 = 2 * (T[1][0] * Vrk[2][0] + T[1][1] * Vrk[2][1] + T[1][2] * Vrk[2][2]) * dL_dc +
|
248 |
-
(T[0][0] * Vrk[2][0] + T[0][1] * Vrk[2][1] + T[0][2] * Vrk[2][2]) * dL_db;
|
249 |
-
|
250 |
-
// Gradients of loss w.r.t. upper 3x2 non-zero entries of Jacobian matrix
|
251 |
-
// T = W * J
|
252 |
-
float dL_dJ00 = W[0][0] * dL_dT00 + W[0][1] * dL_dT01 + W[0][2] * dL_dT02;
|
253 |
-
float dL_dJ02 = W[2][0] * dL_dT00 + W[2][1] * dL_dT01 + W[2][2] * dL_dT02;
|
254 |
-
float dL_dJ11 = W[1][0] * dL_dT10 + W[1][1] * dL_dT11 + W[1][2] * dL_dT12;
|
255 |
-
float dL_dJ12 = W[2][0] * dL_dT10 + W[2][1] * dL_dT11 + W[2][2] * dL_dT12;
|
256 |
-
|
257 |
-
float tz = 1.f / t.z;
|
258 |
-
float tz2 = tz * tz;
|
259 |
-
float tz3 = tz2 * tz;
|
260 |
-
|
261 |
-
// Gradients of loss w.r.t. transformed Gaussian mean t
|
262 |
-
float dL_dtx = x_grad_mul * -h_x * tz2 * dL_dJ02;
|
263 |
-
float dL_dty = y_grad_mul * -h_y * tz2 * dL_dJ12;
|
264 |
-
float dL_dtz = -h_x * tz2 * dL_dJ00 - h_y * tz2 * dL_dJ11 + (2 * h_x * t.x) * tz3 * dL_dJ02 + (2 * h_y * t.y) * tz3 * dL_dJ12;
|
265 |
-
|
266 |
-
// Account for transformation of mean to t
|
267 |
-
// t = transformPoint4x3(mean, view_matrix);
|
268 |
-
float3 dL_dmean = transformVec4x3Transpose({ dL_dtx, dL_dty, dL_dtz }, view_matrix);
|
269 |
-
|
270 |
-
// Gradients of loss w.r.t. Gaussian means, but only the portion
|
271 |
-
// that is caused because the mean affects the covariance matrix.
|
272 |
-
// Additional mean gradient is accumulated in BACKWARD::preprocess.
|
273 |
-
dL_dmeans[idx] = dL_dmean;
|
274 |
-
}
|
275 |
-
|
276 |
-
// Backward pass for the conversion of scale and rotation to a
|
277 |
-
// 3D covariance matrix for each Gaussian.
|
278 |
-
__device__ void computeCov3D(int idx, const glm::vec3 scale, float mod, const glm::vec4 rot, const float* dL_dcov3Ds, glm::vec3* dL_dscales, glm::vec4* dL_drots)
|
279 |
-
{
|
280 |
-
// Recompute (intermediate) results for the 3D covariance computation.
|
281 |
-
glm::vec4 q = rot;// / glm::length(rot);
|
282 |
-
float r = q.x;
|
283 |
-
float x = q.y;
|
284 |
-
float y = q.z;
|
285 |
-
float z = q.w;
|
286 |
-
|
287 |
-
glm::mat3 R = glm::mat3(
|
288 |
-
1.f - 2.f * (y * y + z * z), 2.f * (x * y - r * z), 2.f * (x * z + r * y),
|
289 |
-
2.f * (x * y + r * z), 1.f - 2.f * (x * x + z * z), 2.f * (y * z - r * x),
|
290 |
-
2.f * (x * z - r * y), 2.f * (y * z + r * x), 1.f - 2.f * (x * x + y * y)
|
291 |
-
);
|
292 |
-
|
293 |
-
glm::mat3 S = glm::mat3(1.0f);
|
294 |
-
|
295 |
-
glm::vec3 s = mod * scale;
|
296 |
-
S[0][0] = s.x;
|
297 |
-
S[1][1] = s.y;
|
298 |
-
S[2][2] = s.z;
|
299 |
-
|
300 |
-
glm::mat3 M = S * R;
|
301 |
-
|
302 |
-
const float* dL_dcov3D = dL_dcov3Ds + 6 * idx;
|
303 |
-
|
304 |
-
glm::vec3 dunc(dL_dcov3D[0], dL_dcov3D[3], dL_dcov3D[5]);
|
305 |
-
glm::vec3 ounc = 0.5f * glm::vec3(dL_dcov3D[1], dL_dcov3D[2], dL_dcov3D[4]);
|
306 |
-
|
307 |
-
// Convert per-element covariance loss gradients to matrix form
|
308 |
-
glm::mat3 dL_dSigma = glm::mat3(
|
309 |
-
dL_dcov3D[0], 0.5f * dL_dcov3D[1], 0.5f * dL_dcov3D[2],
|
310 |
-
0.5f * dL_dcov3D[1], dL_dcov3D[3], 0.5f * dL_dcov3D[4],
|
311 |
-
0.5f * dL_dcov3D[2], 0.5f * dL_dcov3D[4], dL_dcov3D[5]
|
312 |
-
);
|
313 |
-
|
314 |
-
// Compute loss gradient w.r.t. matrix M
|
315 |
-
// dSigma_dM = 2 * M
|
316 |
-
glm::mat3 dL_dM = 2.0f * M * dL_dSigma;
|
317 |
-
|
318 |
-
glm::mat3 Rt = glm::transpose(R);
|
319 |
-
glm::mat3 dL_dMt = glm::transpose(dL_dM);
|
320 |
-
|
321 |
-
// Gradients of loss w.r.t. scale
|
322 |
-
glm::vec3* dL_dscale = dL_dscales + idx;
|
323 |
-
dL_dscale->x = glm::dot(Rt[0], dL_dMt[0]);
|
324 |
-
dL_dscale->y = glm::dot(Rt[1], dL_dMt[1]);
|
325 |
-
dL_dscale->z = glm::dot(Rt[2], dL_dMt[2]);
|
326 |
-
|
327 |
-
dL_dMt[0] *= s.x;
|
328 |
-
dL_dMt[1] *= s.y;
|
329 |
-
dL_dMt[2] *= s.z;
|
330 |
-
|
331 |
-
// Gradients of loss w.r.t. normalized quaternion
|
332 |
-
glm::vec4 dL_dq;
|
333 |
-
dL_dq.x = 2 * z * (dL_dMt[0][1] - dL_dMt[1][0]) + 2 * y * (dL_dMt[2][0] - dL_dMt[0][2]) + 2 * x * (dL_dMt[1][2] - dL_dMt[2][1]);
|
334 |
-
dL_dq.y = 2 * y * (dL_dMt[1][0] + dL_dMt[0][1]) + 2 * z * (dL_dMt[2][0] + dL_dMt[0][2]) + 2 * r * (dL_dMt[1][2] - dL_dMt[2][1]) - 4 * x * (dL_dMt[2][2] + dL_dMt[1][1]);
|
335 |
-
dL_dq.z = 2 * x * (dL_dMt[1][0] + dL_dMt[0][1]) + 2 * r * (dL_dMt[2][0] - dL_dMt[0][2]) + 2 * z * (dL_dMt[1][2] + dL_dMt[2][1]) - 4 * y * (dL_dMt[2][2] + dL_dMt[0][0]);
|
336 |
-
dL_dq.w = 2 * r * (dL_dMt[0][1] - dL_dMt[1][0]) + 2 * x * (dL_dMt[2][0] + dL_dMt[0][2]) + 2 * y * (dL_dMt[1][2] + dL_dMt[2][1]) - 4 * z * (dL_dMt[1][1] + dL_dMt[0][0]);
|
337 |
-
|
338 |
-
// Gradients of loss w.r.t. unnormalized quaternion
|
339 |
-
float4* dL_drot = (float4*)(dL_drots + idx);
|
340 |
-
*dL_drot = float4{ dL_dq.x, dL_dq.y, dL_dq.z, dL_dq.w };//dnormvdv(float4{ rot.x, rot.y, rot.z, rot.w }, float4{ dL_dq.x, dL_dq.y, dL_dq.z, dL_dq.w });
|
341 |
-
}
|
342 |
-
|
343 |
-
// Backward pass of the preprocessing steps, except
|
344 |
-
// for the covariance computation and inversion
|
345 |
-
// (those are handled by a previous kernel call)
|
346 |
-
template<int C>
|
347 |
-
__global__ void preprocessCUDA(
|
348 |
-
int P, int D, int M,
|
349 |
-
const float3* means,
|
350 |
-
const int* radii,
|
351 |
-
const float* shs,
|
352 |
-
const bool* clamped,
|
353 |
-
const glm::vec3* scales,
|
354 |
-
const glm::vec4* rotations,
|
355 |
-
const float scale_modifier,
|
356 |
-
const float* view,
|
357 |
-
const float* proj,
|
358 |
-
const glm::vec3* campos,
|
359 |
-
const float3* dL_dmean2D,
|
360 |
-
glm::vec3* dL_dmeans,
|
361 |
-
float* dL_dcolor,
|
362 |
-
float* dL_ddepth,
|
363 |
-
float* dL_dcov3D,
|
364 |
-
float* dL_dsh,
|
365 |
-
glm::vec3* dL_dscale,
|
366 |
-
glm::vec4* dL_drot)
|
367 |
-
{
|
368 |
-
auto idx = cg::this_grid().thread_rank();
|
369 |
-
if (idx >= P || !(radii[idx] > 0))
|
370 |
-
return;
|
371 |
-
|
372 |
-
float3 m = means[idx];
|
373 |
-
|
374 |
-
// Taking care of gradients from the screenspace points
|
375 |
-
float4 m_hom = transformPoint4x4(m, proj);
|
376 |
-
float m_w = 1.0f / (m_hom.w + 0.0000001f);
|
377 |
-
|
378 |
-
// Compute loss gradient w.r.t. 3D means due to gradients of 2D means
|
379 |
-
// from rendering procedure
|
380 |
-
glm::vec3 dL_dmean;
|
381 |
-
float mul1 = (proj[0] * m.x + proj[4] * m.y + proj[8] * m.z + proj[12]) * m_w * m_w;
|
382 |
-
float mul2 = (proj[1] * m.x + proj[5] * m.y + proj[9] * m.z + proj[13]) * m_w * m_w;
|
383 |
-
dL_dmean.x = (proj[0] * m_w - proj[3] * mul1) * dL_dmean2D[idx].x + (proj[1] * m_w - proj[3] * mul2) * dL_dmean2D[idx].y;
|
384 |
-
dL_dmean.y = (proj[4] * m_w - proj[7] * mul1) * dL_dmean2D[idx].x + (proj[5] * m_w - proj[7] * mul2) * dL_dmean2D[idx].y;
|
385 |
-
dL_dmean.z = (proj[8] * m_w - proj[11] * mul1) * dL_dmean2D[idx].x + (proj[9] * m_w - proj[11] * mul2) * dL_dmean2D[idx].y;
|
386 |
-
|
387 |
-
// That's the second part of the mean gradient. Previous computation
|
388 |
-
// of cov2D and following SH conversion also affects it.
|
389 |
-
dL_dmeans[idx] += dL_dmean;
|
390 |
-
|
391 |
-
// the w must be equal to 1 for view^T * [x,y,z,1]
|
392 |
-
float3 m_view = transformPoint4x3(m, view);
|
393 |
-
|
394 |
-
// Compute loss gradient w.r.t. 3D means due to gradients of depth
|
395 |
-
// from rendering procedure
|
396 |
-
glm::vec3 dL_dmean2;
|
397 |
-
float mul3 = view[2] * m.x + view[6] * m.y + view[10] * m.z + view[14];
|
398 |
-
dL_dmean2.x = (view[2] - view[3] * mul3) * dL_ddepth[idx];
|
399 |
-
dL_dmean2.y = (view[6] - view[7] * mul3) * dL_ddepth[idx];
|
400 |
-
dL_dmean2.z = (view[10] - view[11] * mul3) * dL_ddepth[idx];
|
401 |
-
|
402 |
-
// That's the third part of the mean gradient.
|
403 |
-
dL_dmeans[idx] += dL_dmean2;
|
404 |
-
|
405 |
-
// Compute gradient updates due to computing colors from SHs
|
406 |
-
if (shs)
|
407 |
-
computeColorFromSH(idx, D, M, (glm::vec3*)means, *campos, shs, clamped, (glm::vec3*)dL_dcolor, (glm::vec3*)dL_dmeans, (glm::vec3*)dL_dsh);
|
408 |
-
|
409 |
-
// Compute gradient updates due to computing covariance from scale/rotation
|
410 |
-
if (scales)
|
411 |
-
computeCov3D(idx, scales[idx], scale_modifier, rotations[idx], dL_dcov3D, dL_dscale, dL_drot);
|
412 |
-
}
|
413 |
-
|
414 |
-
// Backward version of the rendering procedure.
|
415 |
-
template <uint32_t C>
|
416 |
-
__global__ void __launch_bounds__(BLOCK_X * BLOCK_Y)
|
417 |
-
renderCUDA(
|
418 |
-
const uint2* __restrict__ ranges,
|
419 |
-
const uint32_t* __restrict__ point_list,
|
420 |
-
int W, int H,
|
421 |
-
const float* __restrict__ bg_color,
|
422 |
-
const float2* __restrict__ points_xy_image,
|
423 |
-
const float4* __restrict__ conic_opacity,
|
424 |
-
const float* __restrict__ colors,
|
425 |
-
const float* __restrict__ depths,
|
426 |
-
const float* __restrict__ alphas,
|
427 |
-
const uint32_t* __restrict__ n_contrib,
|
428 |
-
const float* __restrict__ dL_dpixels,
|
429 |
-
const float* __restrict__ dL_dpixel_depths,
|
430 |
-
const float* __restrict__ dL_dalphas,
|
431 |
-
float3* __restrict__ dL_dmean2D,
|
432 |
-
float4* __restrict__ dL_dconic2D,
|
433 |
-
float* __restrict__ dL_dopacity,
|
434 |
-
float* __restrict__ dL_dcolors,
|
435 |
-
float* __restrict__ dL_ddepths
|
436 |
-
)
|
437 |
-
{
|
438 |
-
// We rasterize again. Compute necessary block info.
|
439 |
-
auto block = cg::this_thread_block();
|
440 |
-
const uint32_t horizontal_blocks = (W + BLOCK_X - 1) / BLOCK_X;
|
441 |
-
const uint2 pix_min = { block.group_index().x * BLOCK_X, block.group_index().y * BLOCK_Y };
|
442 |
-
const uint2 pix_max = { min(pix_min.x + BLOCK_X, W), min(pix_min.y + BLOCK_Y , H) };
|
443 |
-
const uint2 pix = { pix_min.x + block.thread_index().x, pix_min.y + block.thread_index().y };
|
444 |
-
const uint32_t pix_id = W * pix.y + pix.x;
|
445 |
-
const float2 pixf = { (float)pix.x, (float)pix.y };
|
446 |
-
|
447 |
-
const bool inside = pix.x < W&& pix.y < H;
|
448 |
-
const uint2 range = ranges[block.group_index().y * horizontal_blocks + block.group_index().x];
|
449 |
-
|
450 |
-
const int rounds = ((range.y - range.x + BLOCK_SIZE - 1) / BLOCK_SIZE);
|
451 |
-
|
452 |
-
bool done = !inside;
|
453 |
-
int toDo = range.y - range.x;
|
454 |
-
|
455 |
-
__shared__ int collected_id[BLOCK_SIZE];
|
456 |
-
__shared__ float2 collected_xy[BLOCK_SIZE];
|
457 |
-
__shared__ float4 collected_conic_opacity[BLOCK_SIZE];
|
458 |
-
__shared__ float collected_colors[C * BLOCK_SIZE];
|
459 |
-
__shared__ float collected_depths[BLOCK_SIZE];
|
460 |
-
|
461 |
-
// In the forward, we stored the final value for T, the
|
462 |
-
// product of all (1 - alpha) factors.
|
463 |
-
const float T_final = inside ? (1 - alphas[pix_id]) : 0;
|
464 |
-
float T = T_final;
|
465 |
-
|
466 |
-
// We start from the back. The ID of the last contributing
|
467 |
-
// Gaussian is known from each pixel from the forward.
|
468 |
-
uint32_t contributor = toDo;
|
469 |
-
const int last_contributor = inside ? n_contrib[pix_id] : 0;
|
470 |
-
|
471 |
-
float accum_rec[C] = { 0 };
|
472 |
-
float dL_dpixel[C];
|
473 |
-
float accum_depth_rec = 0;
|
474 |
-
float dL_dpixel_depth;
|
475 |
-
float accum_alpha_rec = 0;
|
476 |
-
float dL_dalpha;
|
477 |
-
if (inside) {
|
478 |
-
for (int i = 0; i < C; i++)
|
479 |
-
dL_dpixel[i] = dL_dpixels[i * H * W + pix_id];
|
480 |
-
dL_dpixel_depth = dL_dpixel_depths[pix_id];
|
481 |
-
dL_dalpha = dL_dalphas[pix_id];
|
482 |
-
}
|
483 |
-
|
484 |
-
float last_alpha = 0;
|
485 |
-
float last_color[C] = { 0 };
|
486 |
-
float last_depth = 0;
|
487 |
-
|
488 |
-
// Gradient of pixel coordinate w.r.t. normalized
|
489 |
-
// screen-space viewport corrdinates (-1 to 1)
|
490 |
-
const float ddelx_dx = 0.5 * W;
|
491 |
-
const float ddely_dy = 0.5 * H;
|
492 |
-
|
493 |
-
// Traverse all Gaussians
|
494 |
-
for (int i = 0; i < rounds; i++, toDo -= BLOCK_SIZE)
|
495 |
-
{
|
496 |
-
// Load auxiliary data into shared memory, start in the BACK
|
497 |
-
// and load them in revers order.
|
498 |
-
block.sync();
|
499 |
-
const int progress = i * BLOCK_SIZE + block.thread_rank();
|
500 |
-
if (range.x + progress < range.y)
|
501 |
-
{
|
502 |
-
const int coll_id = point_list[range.y - progress - 1];
|
503 |
-
collected_id[block.thread_rank()] = coll_id;
|
504 |
-
collected_xy[block.thread_rank()] = points_xy_image[coll_id];
|
505 |
-
collected_conic_opacity[block.thread_rank()] = conic_opacity[coll_id];
|
506 |
-
for (int i = 0; i < C; i++)
|
507 |
-
collected_colors[i * BLOCK_SIZE + block.thread_rank()] = colors[coll_id * C + i];
|
508 |
-
collected_depths[block.thread_rank()] = depths[coll_id];
|
509 |
-
}
|
510 |
-
block.sync();
|
511 |
-
|
512 |
-
// Iterate over Gaussians
|
513 |
-
for (int j = 0; !done && j < min(BLOCK_SIZE, toDo); j++)
|
514 |
-
{
|
515 |
-
// Keep track of current Gaussian ID. Skip, if this one
|
516 |
-
// is behind the last contributor for this pixel.
|
517 |
-
contributor--;
|
518 |
-
if (contributor >= last_contributor)
|
519 |
-
continue;
|
520 |
-
|
521 |
-
// Compute blending values, as before.
|
522 |
-
const float2 xy = collected_xy[j];
|
523 |
-
const float2 d = { xy.x - pixf.x, xy.y - pixf.y };
|
524 |
-
const float4 con_o = collected_conic_opacity[j];
|
525 |
-
const float power = -0.5f * (con_o.x * d.x * d.x + con_o.z * d.y * d.y) - con_o.y * d.x * d.y;
|
526 |
-
if (power > 0.0f)
|
527 |
-
continue;
|
528 |
-
|
529 |
-
const float G = exp(power);
|
530 |
-
const float alpha = min(0.99f, con_o.w * G);
|
531 |
-
if (alpha < 1.0f / 255.0f)
|
532 |
-
continue;
|
533 |
-
|
534 |
-
T = T / (1.f - alpha);
|
535 |
-
const float dchannel_dcolor = alpha * T;
|
536 |
-
const float dpixel_depth_ddepth = alpha * T;
|
537 |
-
|
538 |
-
// Propagate gradients to per-Gaussian colors and keep
|
539 |
-
// gradients w.r.t. alpha (blending factor for a Gaussian/pixel
|
540 |
-
// pair).
|
541 |
-
float dL_dopa = 0.0f;
|
542 |
-
const int global_id = collected_id[j];
|
543 |
-
for (int ch = 0; ch < C; ch++)
|
544 |
-
{
|
545 |
-
const float c = collected_colors[ch * BLOCK_SIZE + j];
|
546 |
-
// Update last color (to be used in the next iteration)
|
547 |
-
accum_rec[ch] = last_alpha * last_color[ch] + (1.f - last_alpha) * accum_rec[ch];
|
548 |
-
last_color[ch] = c;
|
549 |
-
|
550 |
-
const float dL_dchannel = dL_dpixel[ch];
|
551 |
-
dL_dopa += (c - accum_rec[ch]) * dL_dchannel;
|
552 |
-
// Update the gradients w.r.t. color of the Gaussian.
|
553 |
-
// Atomic, since this pixel is just one of potentially
|
554 |
-
// many that were affected by this Gaussian.
|
555 |
-
atomicAdd(&(dL_dcolors[global_id * C + ch]), dchannel_dcolor * dL_dchannel);
|
556 |
-
}
|
557 |
-
|
558 |
-
// Propagate gradients from pixel depth to opacity
|
559 |
-
const float c_d = collected_depths[j];
|
560 |
-
accum_depth_rec = last_alpha * last_depth + (1.f - last_alpha) * accum_depth_rec;
|
561 |
-
last_depth = c_d;
|
562 |
-
dL_dopa += (c_d - accum_depth_rec) * dL_dpixel_depth;
|
563 |
-
atomicAdd(&(dL_ddepths[global_id]), dpixel_depth_ddepth * dL_dpixel_depth);
|
564 |
-
|
565 |
-
// Propagate gradients from pixel alpha (weights_sum) to opacity
|
566 |
-
accum_alpha_rec = last_alpha + (1.f - last_alpha) * accum_alpha_rec;
|
567 |
-
dL_dopa += (1 - accum_alpha_rec) * dL_dalpha; //- (alpha - accum_alpha_rec) * dL_dalpha;
|
568 |
-
|
569 |
-
dL_dopa *= T;
|
570 |
-
// Update last alpha (to be used in the next iteration)
|
571 |
-
last_alpha = alpha;
|
572 |
-
|
573 |
-
// Account for fact that alpha also influences how much of
|
574 |
-
// the background color is added if nothing left to blend
|
575 |
-
float bg_dot_dpixel = 0;
|
576 |
-
for (int i = 0; i < C; i++)
|
577 |
-
bg_dot_dpixel += bg_color[i] * dL_dpixel[i];
|
578 |
-
dL_dopa += (-T_final / (1.f - alpha)) * bg_dot_dpixel;
|
579 |
-
|
580 |
-
|
581 |
-
// Helpful reusable temporary variables
|
582 |
-
const float dL_dG = con_o.w * dL_dopa;
|
583 |
-
const float gdx = G * d.x;
|
584 |
-
const float gdy = G * d.y;
|
585 |
-
const float dG_ddelx = -gdx * con_o.x - gdy * con_o.y;
|
586 |
-
const float dG_ddely = -gdy * con_o.z - gdx * con_o.y;
|
587 |
-
|
588 |
-
// Update gradients w.r.t. 2D mean position of the Gaussian
|
589 |
-
atomicAdd(&dL_dmean2D[global_id].x, dL_dG * dG_ddelx * ddelx_dx);
|
590 |
-
atomicAdd(&dL_dmean2D[global_id].y, dL_dG * dG_ddely * ddely_dy);
|
591 |
-
|
592 |
-
// Update gradients w.r.t. 2D covariance (2x2 matrix, symmetric)
|
593 |
-
atomicAdd(&dL_dconic2D[global_id].x, -0.5f * gdx * d.x * dL_dG);
|
594 |
-
atomicAdd(&dL_dconic2D[global_id].y, -0.5f * gdx * d.y * dL_dG);
|
595 |
-
atomicAdd(&dL_dconic2D[global_id].w, -0.5f * gdy * d.y * dL_dG);
|
596 |
-
|
597 |
-
// Update gradients w.r.t. opacity of the Gaussian
|
598 |
-
atomicAdd(&(dL_dopacity[global_id]), G * dL_dopa);
|
599 |
-
}
|
600 |
-
}
|
601 |
-
}
|
602 |
-
|
603 |
-
void BACKWARD::preprocess(
|
604 |
-
int P, int D, int M,
|
605 |
-
const float3* means3D,
|
606 |
-
const int* radii,
|
607 |
-
const float* shs,
|
608 |
-
const bool* clamped,
|
609 |
-
const glm::vec3* scales,
|
610 |
-
const glm::vec4* rotations,
|
611 |
-
const float scale_modifier,
|
612 |
-
const float* cov3Ds,
|
613 |
-
const float* viewmatrix,
|
614 |
-
const float* projmatrix,
|
615 |
-
const float focal_x, float focal_y,
|
616 |
-
const float tan_fovx, float tan_fovy,
|
617 |
-
const glm::vec3* campos,
|
618 |
-
const float3* dL_dmean2D,
|
619 |
-
const float* dL_dconic,
|
620 |
-
glm::vec3* dL_dmean3D,
|
621 |
-
float* dL_dcolor,
|
622 |
-
float* dL_ddepth,
|
623 |
-
float* dL_dcov3D,
|
624 |
-
float* dL_dsh,
|
625 |
-
glm::vec3* dL_dscale,
|
626 |
-
glm::vec4* dL_drot)
|
627 |
-
{
|
628 |
-
// Propagate gradients for the path of 2D conic matrix computation.
|
629 |
-
// Somewhat long, thus it is its own kernel rather than being part of
|
630 |
-
// "preprocess". When done, loss gradient w.r.t. 3D means has been
|
631 |
-
// modified and gradient w.r.t. 3D covariance matrix has been computed.
|
632 |
-
computeCov2DCUDA << <(P + 255) / 256, 256 >> > (
|
633 |
-
P,
|
634 |
-
means3D,
|
635 |
-
radii,
|
636 |
-
cov3Ds,
|
637 |
-
focal_x,
|
638 |
-
focal_y,
|
639 |
-
tan_fovx,
|
640 |
-
tan_fovy,
|
641 |
-
viewmatrix,
|
642 |
-
dL_dconic,
|
643 |
-
(float3*)dL_dmean3D,
|
644 |
-
dL_dcov3D);
|
645 |
-
|
646 |
-
// Propagate gradients for remaining steps: finish 3D mean gradients,
|
647 |
-
// propagate color gradients to SH (if desireD), propagate 3D covariance
|
648 |
-
// matrix gradients to scale and rotation.
|
649 |
-
preprocessCUDA<NUM_CHANNELS> << < (P + 255) / 256, 256 >> > (
|
650 |
-
P, D, M,
|
651 |
-
(float3*)means3D,
|
652 |
-
radii,
|
653 |
-
shs,
|
654 |
-
clamped,
|
655 |
-
(glm::vec3*)scales,
|
656 |
-
(glm::vec4*)rotations,
|
657 |
-
scale_modifier,
|
658 |
-
viewmatrix,
|
659 |
-
projmatrix,
|
660 |
-
campos,
|
661 |
-
(float3*)dL_dmean2D,
|
662 |
-
(glm::vec3*)dL_dmean3D,
|
663 |
-
dL_dcolor,
|
664 |
-
dL_ddepth,
|
665 |
-
dL_dcov3D,
|
666 |
-
dL_dsh,
|
667 |
-
dL_dscale,
|
668 |
-
dL_drot);
|
669 |
-
}
|
670 |
-
|
671 |
-
void BACKWARD::render(
|
672 |
-
const dim3 grid, const dim3 block,
|
673 |
-
const uint2* ranges,
|
674 |
-
const uint32_t* point_list,
|
675 |
-
int W, int H,
|
676 |
-
const float* bg_color,
|
677 |
-
const float2* means2D,
|
678 |
-
const float4* conic_opacity,
|
679 |
-
const float* colors,
|
680 |
-
const float* depths,
|
681 |
-
const float* alphas,
|
682 |
-
const uint32_t* n_contrib,
|
683 |
-
const float* dL_dpixels,
|
684 |
-
const float* dL_dpixel_depths,
|
685 |
-
const float* dL_dalphas,
|
686 |
-
float3* dL_dmean2D,
|
687 |
-
float4* dL_dconic2D,
|
688 |
-
float* dL_dopacity,
|
689 |
-
float* dL_dcolors,
|
690 |
-
float* dL_ddepths)
|
691 |
-
{
|
692 |
-
renderCUDA<NUM_CHANNELS> << <grid, block >> >(
|
693 |
-
ranges,
|
694 |
-
point_list,
|
695 |
-
W, H,
|
696 |
-
bg_color,
|
697 |
-
means2D,
|
698 |
-
conic_opacity,
|
699 |
-
colors,
|
700 |
-
depths,
|
701 |
-
alphas,
|
702 |
-
n_contrib,
|
703 |
-
dL_dpixels,
|
704 |
-
dL_dpixel_depths,
|
705 |
-
dL_dalphas,
|
706 |
-
dL_dmean2D,
|
707 |
-
dL_dconic2D,
|
708 |
-
dL_dopacity,
|
709 |
-
dL_dcolors,
|
710 |
-
dL_ddepths
|
711 |
-
);
|
712 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/backward.h
DELETED
@@ -1,70 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#ifndef CUDA_RASTERIZER_BACKWARD_H_INCLUDED
|
13 |
-
#define CUDA_RASTERIZER_BACKWARD_H_INCLUDED
|
14 |
-
|
15 |
-
#include <cuda.h>
|
16 |
-
#include "cuda_runtime.h"
|
17 |
-
#include "device_launch_parameters.h"
|
18 |
-
#define GLM_FORCE_CUDA
|
19 |
-
#include <glm/glm.hpp>
|
20 |
-
|
21 |
-
namespace BACKWARD
|
22 |
-
{
|
23 |
-
void render(
|
24 |
-
const dim3 grid, dim3 block,
|
25 |
-
const uint2* ranges,
|
26 |
-
const uint32_t* point_list,
|
27 |
-
int W, int H,
|
28 |
-
const float* bg_color,
|
29 |
-
const float2* means2D,
|
30 |
-
const float4* conic_opacity,
|
31 |
-
const float* colors,
|
32 |
-
const float* depths,
|
33 |
-
const float* alphas,
|
34 |
-
const uint32_t* n_contrib,
|
35 |
-
const float* dL_dpixels,
|
36 |
-
const float* dL_dpixel_depths,
|
37 |
-
const float* dL_dalphas,
|
38 |
-
float3* dL_dmean2D,
|
39 |
-
float4* dL_dconic2D,
|
40 |
-
float* dL_dopacity,
|
41 |
-
float* dL_dcolors,
|
42 |
-
float* dL_ddepths);
|
43 |
-
|
44 |
-
void preprocess(
|
45 |
-
int P, int D, int M,
|
46 |
-
const float3* means,
|
47 |
-
const int* radii,
|
48 |
-
const float* shs,
|
49 |
-
const bool* clamped,
|
50 |
-
const glm::vec3* scales,
|
51 |
-
const glm::vec4* rotations,
|
52 |
-
const float scale_modifier,
|
53 |
-
const float* cov3Ds,
|
54 |
-
const float* view,
|
55 |
-
const float* proj,
|
56 |
-
const float focal_x, float focal_y,
|
57 |
-
const float tan_fovx, float tan_fovy,
|
58 |
-
const glm::vec3* campos,
|
59 |
-
const float3* dL_dmean2D,
|
60 |
-
const float* dL_dconics,
|
61 |
-
glm::vec3* dL_dmeans,
|
62 |
-
float* dL_dcolor,
|
63 |
-
float* dL_ddepth,
|
64 |
-
float* dL_dcov3D,
|
65 |
-
float* dL_dsh,
|
66 |
-
glm::vec3* dL_dscale,
|
67 |
-
glm::vec4* dL_drot);
|
68 |
-
}
|
69 |
-
|
70 |
-
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/config.h
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#ifndef CUDA_RASTERIZER_CONFIG_H_INCLUDED
|
13 |
-
#define CUDA_RASTERIZER_CONFIG_H_INCLUDED
|
14 |
-
|
15 |
-
#define NUM_CHANNELS 3 // Default 3, RGB
|
16 |
-
#define BLOCK_X 16
|
17 |
-
#define BLOCK_Y 16
|
18 |
-
|
19 |
-
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/forward.cu
DELETED
@@ -1,466 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#include "forward.h"
|
13 |
-
#include "auxiliary.h"
|
14 |
-
#include <cooperative_groups.h>
|
15 |
-
#include <cooperative_groups/reduce.h>
|
16 |
-
namespace cg = cooperative_groups;
|
17 |
-
|
18 |
-
// Forward method for converting the input spherical harmonics
|
19 |
-
// coefficients of each Gaussian to a simple RGB color.
|
20 |
-
__device__ glm::vec3 computeColorFromSH(int idx, int deg, int max_coeffs, const glm::vec3* means, glm::vec3 campos, const float* shs, bool* clamped)
|
21 |
-
{
|
22 |
-
// The implementation is loosely based on code for
|
23 |
-
// "Differentiable Point-Based Radiance Fields for
|
24 |
-
// Efficient View Synthesis" by Zhang et al. (2022)
|
25 |
-
glm::vec3 pos = means[idx];
|
26 |
-
glm::vec3 dir = pos - campos;
|
27 |
-
dir = dir / glm::length(dir);
|
28 |
-
|
29 |
-
glm::vec3* sh = ((glm::vec3*)shs) + idx * max_coeffs;
|
30 |
-
glm::vec3 result = SH_C0 * sh[0];
|
31 |
-
|
32 |
-
if (deg > 0)
|
33 |
-
{
|
34 |
-
float x = dir.x;
|
35 |
-
float y = dir.y;
|
36 |
-
float z = dir.z;
|
37 |
-
result = result - SH_C1 * y * sh[1] + SH_C1 * z * sh[2] - SH_C1 * x * sh[3];
|
38 |
-
|
39 |
-
if (deg > 1)
|
40 |
-
{
|
41 |
-
float xx = x * x, yy = y * y, zz = z * z;
|
42 |
-
float xy = x * y, yz = y * z, xz = x * z;
|
43 |
-
result = result +
|
44 |
-
SH_C2[0] * xy * sh[4] +
|
45 |
-
SH_C2[1] * yz * sh[5] +
|
46 |
-
SH_C2[2] * (2.0f * zz - xx - yy) * sh[6] +
|
47 |
-
SH_C2[3] * xz * sh[7] +
|
48 |
-
SH_C2[4] * (xx - yy) * sh[8];
|
49 |
-
|
50 |
-
if (deg > 2)
|
51 |
-
{
|
52 |
-
result = result +
|
53 |
-
SH_C3[0] * y * (3.0f * xx - yy) * sh[9] +
|
54 |
-
SH_C3[1] * xy * z * sh[10] +
|
55 |
-
SH_C3[2] * y * (4.0f * zz - xx - yy) * sh[11] +
|
56 |
-
SH_C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * sh[12] +
|
57 |
-
SH_C3[4] * x * (4.0f * zz - xx - yy) * sh[13] +
|
58 |
-
SH_C3[5] * z * (xx - yy) * sh[14] +
|
59 |
-
SH_C3[6] * x * (xx - 3.0f * yy) * sh[15];
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
63 |
-
result += 0.5f;
|
64 |
-
|
65 |
-
// RGB colors are clamped to positive values. If values are
|
66 |
-
// clamped, we need to keep track of this for the backward pass.
|
67 |
-
clamped[3 * idx + 0] = (result.x < 0);
|
68 |
-
clamped[3 * idx + 1] = (result.y < 0);
|
69 |
-
clamped[3 * idx + 2] = (result.z < 0);
|
70 |
-
return glm::max(result, 0.0f);
|
71 |
-
}
|
72 |
-
|
73 |
-
// Forward version of 2D covariance matrix computation
|
74 |
-
__device__ float3 computeCov2D(const float3& mean, float focal_x, float focal_y, float tan_fovx, float tan_fovy, const float* cov3D, const float* viewmatrix)
|
75 |
-
{
|
76 |
-
// The following models the steps outlined by equations 29
|
77 |
-
// and 31 in "EWA Splatting" (Zwicker et al., 2002).
|
78 |
-
// Additionally considers aspect / scaling of viewport.
|
79 |
-
// Transposes used to account for row-/column-major conventions.
|
80 |
-
float3 t = transformPoint4x3(mean, viewmatrix);
|
81 |
-
|
82 |
-
const float limx = 1.3f * tan_fovx;
|
83 |
-
const float limy = 1.3f * tan_fovy;
|
84 |
-
const float txtz = t.x / t.z;
|
85 |
-
const float tytz = t.y / t.z;
|
86 |
-
t.x = min(limx, max(-limx, txtz)) * t.z;
|
87 |
-
t.y = min(limy, max(-limy, tytz)) * t.z;
|
88 |
-
|
89 |
-
glm::mat3 J = glm::mat3(
|
90 |
-
focal_x / t.z, 0.0f, -(focal_x * t.x) / (t.z * t.z),
|
91 |
-
0.0f, focal_y / t.z, -(focal_y * t.y) / (t.z * t.z),
|
92 |
-
0, 0, 0);
|
93 |
-
|
94 |
-
glm::mat3 W = glm::mat3(
|
95 |
-
viewmatrix[0], viewmatrix[4], viewmatrix[8],
|
96 |
-
viewmatrix[1], viewmatrix[5], viewmatrix[9],
|
97 |
-
viewmatrix[2], viewmatrix[6], viewmatrix[10]);
|
98 |
-
|
99 |
-
glm::mat3 T = W * J;
|
100 |
-
|
101 |
-
glm::mat3 Vrk = glm::mat3(
|
102 |
-
cov3D[0], cov3D[1], cov3D[2],
|
103 |
-
cov3D[1], cov3D[3], cov3D[4],
|
104 |
-
cov3D[2], cov3D[4], cov3D[5]);
|
105 |
-
|
106 |
-
glm::mat3 cov = glm::transpose(T) * glm::transpose(Vrk) * T;
|
107 |
-
|
108 |
-
// Apply low-pass filter: every Gaussian should be at least
|
109 |
-
// one pixel wide/high. Discard 3rd row and column.
|
110 |
-
cov[0][0] += 0.3f;
|
111 |
-
cov[1][1] += 0.3f;
|
112 |
-
return { float(cov[0][0]), float(cov[0][1]), float(cov[1][1]) };
|
113 |
-
}
|
114 |
-
|
115 |
-
// Forward method for converting scale and rotation properties of each
|
116 |
-
// Gaussian to a 3D covariance matrix in world space. Also takes care
|
117 |
-
// of quaternion normalization.
|
118 |
-
__device__ void computeCov3D(const glm::vec3 scale, float mod, const glm::vec4 rot, float* cov3D)
|
119 |
-
{
|
120 |
-
// Create scaling matrix
|
121 |
-
glm::mat3 S = glm::mat3(1.0f);
|
122 |
-
S[0][0] = mod * scale.x;
|
123 |
-
S[1][1] = mod * scale.y;
|
124 |
-
S[2][2] = mod * scale.z;
|
125 |
-
|
126 |
-
// Normalize quaternion to get valid rotation
|
127 |
-
glm::vec4 q = rot;// / glm::length(rot);
|
128 |
-
float r = q.x;
|
129 |
-
float x = q.y;
|
130 |
-
float y = q.z;
|
131 |
-
float z = q.w;
|
132 |
-
|
133 |
-
// Compute rotation matrix from quaternion
|
134 |
-
glm::mat3 R = glm::mat3(
|
135 |
-
1.f - 2.f * (y * y + z * z), 2.f * (x * y - r * z), 2.f * (x * z + r * y),
|
136 |
-
2.f * (x * y + r * z), 1.f - 2.f * (x * x + z * z), 2.f * (y * z - r * x),
|
137 |
-
2.f * (x * z - r * y), 2.f * (y * z + r * x), 1.f - 2.f * (x * x + y * y)
|
138 |
-
);
|
139 |
-
|
140 |
-
glm::mat3 M = S * R;
|
141 |
-
|
142 |
-
// Compute 3D world covariance matrix Sigma
|
143 |
-
glm::mat3 Sigma = glm::transpose(M) * M;
|
144 |
-
|
145 |
-
// Covariance is symmetric, only store upper right
|
146 |
-
cov3D[0] = Sigma[0][0];
|
147 |
-
cov3D[1] = Sigma[0][1];
|
148 |
-
cov3D[2] = Sigma[0][2];
|
149 |
-
cov3D[3] = Sigma[1][1];
|
150 |
-
cov3D[4] = Sigma[1][2];
|
151 |
-
cov3D[5] = Sigma[2][2];
|
152 |
-
}
|
153 |
-
|
154 |
-
// Perform initial steps for each Gaussian prior to rasterization.
|
155 |
-
template<int C>
|
156 |
-
__global__ void preprocessCUDA(int P, int D, int M,
|
157 |
-
const float* orig_points,
|
158 |
-
const glm::vec3* scales,
|
159 |
-
const float scale_modifier,
|
160 |
-
const glm::vec4* rotations,
|
161 |
-
const float* opacities,
|
162 |
-
const float* shs,
|
163 |
-
bool* clamped,
|
164 |
-
const float* cov3D_precomp,
|
165 |
-
const float* colors_precomp,
|
166 |
-
const float* viewmatrix,
|
167 |
-
const float* projmatrix,
|
168 |
-
const glm::vec3* cam_pos,
|
169 |
-
const int W, int H,
|
170 |
-
const float tan_fovx, float tan_fovy,
|
171 |
-
const float focal_x, float focal_y,
|
172 |
-
int* radii,
|
173 |
-
float2* points_xy_image,
|
174 |
-
float* depths,
|
175 |
-
float* cov3Ds,
|
176 |
-
float* rgb,
|
177 |
-
float4* conic_opacity,
|
178 |
-
const dim3 grid,
|
179 |
-
uint32_t* tiles_touched,
|
180 |
-
bool prefiltered)
|
181 |
-
{
|
182 |
-
auto idx = cg::this_grid().thread_rank();
|
183 |
-
if (idx >= P)
|
184 |
-
return;
|
185 |
-
|
186 |
-
// Initialize radius and touched tiles to 0. If this isn't changed,
|
187 |
-
// this Gaussian will not be processed further.
|
188 |
-
radii[idx] = 0;
|
189 |
-
tiles_touched[idx] = 0;
|
190 |
-
|
191 |
-
// Perform near culling, quit if outside.
|
192 |
-
float3 p_view;
|
193 |
-
if (!in_frustum(idx, orig_points, viewmatrix, projmatrix, prefiltered, p_view))
|
194 |
-
return;
|
195 |
-
|
196 |
-
// Transform point by projecting
|
197 |
-
float3 p_orig = { orig_points[3 * idx], orig_points[3 * idx + 1], orig_points[3 * idx + 2] };
|
198 |
-
float4 p_hom = transformPoint4x4(p_orig, projmatrix);
|
199 |
-
float p_w = 1.0f / (p_hom.w + 0.0000001f);
|
200 |
-
float3 p_proj = { p_hom.x * p_w, p_hom.y * p_w, p_hom.z * p_w };
|
201 |
-
|
202 |
-
// If 3D covariance matrix is precomputed, use it, otherwise compute
|
203 |
-
// from scaling and rotation parameters.
|
204 |
-
const float* cov3D;
|
205 |
-
if (cov3D_precomp != nullptr)
|
206 |
-
{
|
207 |
-
cov3D = cov3D_precomp + idx * 6;
|
208 |
-
}
|
209 |
-
else
|
210 |
-
{
|
211 |
-
computeCov3D(scales[idx], scale_modifier, rotations[idx], cov3Ds + idx * 6);
|
212 |
-
cov3D = cov3Ds + idx * 6;
|
213 |
-
}
|
214 |
-
|
215 |
-
// Compute 2D screen-space covariance matrix
|
216 |
-
float3 cov = computeCov2D(p_orig, focal_x, focal_y, tan_fovx, tan_fovy, cov3D, viewmatrix);
|
217 |
-
|
218 |
-
// Invert covariance (EWA algorithm)
|
219 |
-
float det = (cov.x * cov.z - cov.y * cov.y);
|
220 |
-
if (det == 0.0f)
|
221 |
-
return;
|
222 |
-
float det_inv = 1.f / det;
|
223 |
-
float3 conic = { cov.z * det_inv, -cov.y * det_inv, cov.x * det_inv };
|
224 |
-
|
225 |
-
// Compute extent in screen space (by finding eigenvalues of
|
226 |
-
// 2D covariance matrix). Use extent to compute a bounding rectangle
|
227 |
-
// of screen-space tiles that this Gaussian overlaps with. Quit if
|
228 |
-
// rectangle covers 0 tiles.
|
229 |
-
float mid = 0.5f * (cov.x + cov.z);
|
230 |
-
float lambda1 = mid + sqrt(max(0.1f, mid * mid - det));
|
231 |
-
float lambda2 = mid - sqrt(max(0.1f, mid * mid - det));
|
232 |
-
float my_radius = ceil(3.f * sqrt(max(lambda1, lambda2)));
|
233 |
-
float2 point_image = { ndc2Pix(p_proj.x, W), ndc2Pix(p_proj.y, H) };
|
234 |
-
uint2 rect_min, rect_max;
|
235 |
-
getRect(point_image, my_radius, rect_min, rect_max, grid);
|
236 |
-
if ((rect_max.x - rect_min.x) * (rect_max.y - rect_min.y) == 0)
|
237 |
-
return;
|
238 |
-
|
239 |
-
// If colors have been precomputed, use them, otherwise convert
|
240 |
-
// spherical harmonics coefficients to RGB color.
|
241 |
-
if (colors_precomp == nullptr)
|
242 |
-
{
|
243 |
-
glm::vec3 result = computeColorFromSH(idx, D, M, (glm::vec3*)orig_points, *cam_pos, shs, clamped);
|
244 |
-
rgb[idx * C + 0] = result.x;
|
245 |
-
rgb[idx * C + 1] = result.y;
|
246 |
-
rgb[idx * C + 2] = result.z;
|
247 |
-
}
|
248 |
-
|
249 |
-
// Store some useful helper data for the next steps.
|
250 |
-
depths[idx] = p_view.z;
|
251 |
-
radii[idx] = my_radius;
|
252 |
-
points_xy_image[idx] = point_image;
|
253 |
-
// Inverse 2D covariance and opacity neatly pack into one float4
|
254 |
-
conic_opacity[idx] = { conic.x, conic.y, conic.z, opacities[idx] };
|
255 |
-
tiles_touched[idx] = (rect_max.y - rect_min.y) * (rect_max.x - rect_min.x);
|
256 |
-
}
|
257 |
-
|
258 |
-
// Main rasterization method. Collaboratively works on one tile per
|
259 |
-
// block, each thread treats one pixel. Alternates between fetching
|
260 |
-
// and rasterizing data.
|
261 |
-
template <uint32_t CHANNELS>
|
262 |
-
__global__ void __launch_bounds__(BLOCK_X * BLOCK_Y)
|
263 |
-
renderCUDA(
|
264 |
-
const uint2* __restrict__ ranges,
|
265 |
-
const uint32_t* __restrict__ point_list,
|
266 |
-
int W, int H,
|
267 |
-
const float2* __restrict__ points_xy_image,
|
268 |
-
const float* __restrict__ features,
|
269 |
-
const float* __restrict__ depths,
|
270 |
-
const float4* __restrict__ conic_opacity,
|
271 |
-
float* __restrict__ out_alpha,
|
272 |
-
uint32_t* __restrict__ n_contrib,
|
273 |
-
const float* __restrict__ bg_color,
|
274 |
-
float* __restrict__ out_color,
|
275 |
-
float* __restrict__ out_depth)
|
276 |
-
{
|
277 |
-
// Identify current tile and associated min/max pixel range.
|
278 |
-
auto block = cg::this_thread_block();
|
279 |
-
uint32_t horizontal_blocks = (W + BLOCK_X - 1) / BLOCK_X;
|
280 |
-
uint2 pix_min = { block.group_index().x * BLOCK_X, block.group_index().y * BLOCK_Y };
|
281 |
-
uint2 pix_max = { min(pix_min.x + BLOCK_X, W), min(pix_min.y + BLOCK_Y , H) };
|
282 |
-
uint2 pix = { pix_min.x + block.thread_index().x, pix_min.y + block.thread_index().y };
|
283 |
-
uint32_t pix_id = W * pix.y + pix.x;
|
284 |
-
float2 pixf = { (float)pix.x, (float)pix.y };
|
285 |
-
|
286 |
-
// Check if this thread is associated with a valid pixel or outside.
|
287 |
-
bool inside = pix.x < W&& pix.y < H;
|
288 |
-
// Done threads can help with fetching, but don't rasterize
|
289 |
-
bool done = !inside;
|
290 |
-
|
291 |
-
// Load start/end range of IDs to process in bit sorted list.
|
292 |
-
uint2 range = ranges[block.group_index().y * horizontal_blocks + block.group_index().x];
|
293 |
-
const int rounds = ((range.y - range.x + BLOCK_SIZE - 1) / BLOCK_SIZE);
|
294 |
-
int toDo = range.y - range.x;
|
295 |
-
|
296 |
-
// Allocate storage for batches of collectively fetched data.
|
297 |
-
__shared__ int collected_id[BLOCK_SIZE];
|
298 |
-
__shared__ float2 collected_xy[BLOCK_SIZE];
|
299 |
-
__shared__ float4 collected_conic_opacity[BLOCK_SIZE];
|
300 |
-
|
301 |
-
// Initialize helper variables
|
302 |
-
float T = 1.0f;
|
303 |
-
uint32_t contributor = 0;
|
304 |
-
uint32_t last_contributor = 0;
|
305 |
-
float C[CHANNELS] = { 0 };
|
306 |
-
float weight = 0;
|
307 |
-
float D = 0;
|
308 |
-
|
309 |
-
// Iterate over batches until all done or range is complete
|
310 |
-
for (int i = 0; i < rounds; i++, toDo -= BLOCK_SIZE)
|
311 |
-
{
|
312 |
-
// End if entire block votes that it is done rasterizing
|
313 |
-
int num_done = __syncthreads_count(done);
|
314 |
-
if (num_done == BLOCK_SIZE)
|
315 |
-
break;
|
316 |
-
|
317 |
-
// Collectively fetch per-Gaussian data from global to shared
|
318 |
-
int progress = i * BLOCK_SIZE + block.thread_rank();
|
319 |
-
if (range.x + progress < range.y)
|
320 |
-
{
|
321 |
-
int coll_id = point_list[range.x + progress];
|
322 |
-
collected_id[block.thread_rank()] = coll_id;
|
323 |
-
collected_xy[block.thread_rank()] = points_xy_image[coll_id];
|
324 |
-
collected_conic_opacity[block.thread_rank()] = conic_opacity[coll_id];
|
325 |
-
}
|
326 |
-
block.sync();
|
327 |
-
|
328 |
-
// Iterate over current batch
|
329 |
-
for (int j = 0; !done && j < min(BLOCK_SIZE, toDo); j++)
|
330 |
-
{
|
331 |
-
// Keep track of current position in range
|
332 |
-
contributor++;
|
333 |
-
|
334 |
-
// Resample using conic matrix (cf. "Surface
|
335 |
-
// Splatting" by Zwicker et al., 2001)
|
336 |
-
float2 xy = collected_xy[j];
|
337 |
-
float2 d = { xy.x - pixf.x, xy.y - pixf.y };
|
338 |
-
float4 con_o = collected_conic_opacity[j];
|
339 |
-
float power = -0.5f * (con_o.x * d.x * d.x + con_o.z * d.y * d.y) - con_o.y * d.x * d.y;
|
340 |
-
if (power > 0.0f)
|
341 |
-
continue;
|
342 |
-
|
343 |
-
// Eq. (2) from 3D Gaussian splatting paper.
|
344 |
-
// Obtain alpha by multiplying with Gaussian opacity
|
345 |
-
// and its exponential falloff from mean.
|
346 |
-
// Avoid numerical instabilities (see paper appendix).
|
347 |
-
float alpha = min(0.99f, con_o.w * exp(power));
|
348 |
-
if (alpha < 1.0f / 255.0f)
|
349 |
-
continue;
|
350 |
-
float test_T = T * (1 - alpha);
|
351 |
-
if (test_T < 0.0001f)
|
352 |
-
{
|
353 |
-
done = true;
|
354 |
-
continue;
|
355 |
-
}
|
356 |
-
|
357 |
-
// Eq. (3) from 3D Gaussian splatting paper.
|
358 |
-
for (int ch = 0; ch < CHANNELS; ch++)
|
359 |
-
C[ch] += features[collected_id[j] * CHANNELS + ch] * alpha * T;
|
360 |
-
weight += alpha * T;
|
361 |
-
D += depths[collected_id[j]] * alpha * T;
|
362 |
-
|
363 |
-
T = test_T;
|
364 |
-
|
365 |
-
// Keep track of last range entry to update this
|
366 |
-
// pixel.
|
367 |
-
last_contributor = contributor;
|
368 |
-
}
|
369 |
-
}
|
370 |
-
|
371 |
-
// All threads that treat valid pixel write out their final
|
372 |
-
// rendering data to the frame and auxiliary buffers.
|
373 |
-
if (inside)
|
374 |
-
{
|
375 |
-
n_contrib[pix_id] = last_contributor;
|
376 |
-
for (int ch = 0; ch < CHANNELS; ch++)
|
377 |
-
out_color[ch * H * W + pix_id] = C[ch] + T * bg_color[ch];
|
378 |
-
out_alpha[pix_id] = weight; //1 - T;
|
379 |
-
out_depth[pix_id] = D;
|
380 |
-
}
|
381 |
-
}
|
382 |
-
|
383 |
-
void FORWARD::render(
|
384 |
-
const dim3 grid, dim3 block,
|
385 |
-
const uint2* ranges,
|
386 |
-
const uint32_t* point_list,
|
387 |
-
int W, int H,
|
388 |
-
const float2* means2D,
|
389 |
-
const float* colors,
|
390 |
-
const float* depths,
|
391 |
-
const float4* conic_opacity,
|
392 |
-
float* out_alpha,
|
393 |
-
uint32_t* n_contrib,
|
394 |
-
const float* bg_color,
|
395 |
-
float* out_color,
|
396 |
-
float* out_depth)
|
397 |
-
{
|
398 |
-
renderCUDA<NUM_CHANNELS> << <grid, block >> > (
|
399 |
-
ranges,
|
400 |
-
point_list,
|
401 |
-
W, H,
|
402 |
-
means2D,
|
403 |
-
colors,
|
404 |
-
depths,
|
405 |
-
conic_opacity,
|
406 |
-
out_alpha,
|
407 |
-
n_contrib,
|
408 |
-
bg_color,
|
409 |
-
out_color,
|
410 |
-
out_depth);
|
411 |
-
}
|
412 |
-
|
413 |
-
void FORWARD::preprocess(int P, int D, int M,
|
414 |
-
const float* means3D,
|
415 |
-
const glm::vec3* scales,
|
416 |
-
const float scale_modifier,
|
417 |
-
const glm::vec4* rotations,
|
418 |
-
const float* opacities,
|
419 |
-
const float* shs,
|
420 |
-
bool* clamped,
|
421 |
-
const float* cov3D_precomp,
|
422 |
-
const float* colors_precomp,
|
423 |
-
const float* viewmatrix,
|
424 |
-
const float* projmatrix,
|
425 |
-
const glm::vec3* cam_pos,
|
426 |
-
const int W, int H,
|
427 |
-
const float focal_x, float focal_y,
|
428 |
-
const float tan_fovx, float tan_fovy,
|
429 |
-
int* radii,
|
430 |
-
float2* means2D,
|
431 |
-
float* depths,
|
432 |
-
float* cov3Ds,
|
433 |
-
float* rgb,
|
434 |
-
float4* conic_opacity,
|
435 |
-
const dim3 grid,
|
436 |
-
uint32_t* tiles_touched,
|
437 |
-
bool prefiltered)
|
438 |
-
{
|
439 |
-
preprocessCUDA<NUM_CHANNELS> << <(P + 255) / 256, 256 >> > (
|
440 |
-
P, D, M,
|
441 |
-
means3D,
|
442 |
-
scales,
|
443 |
-
scale_modifier,
|
444 |
-
rotations,
|
445 |
-
opacities,
|
446 |
-
shs,
|
447 |
-
clamped,
|
448 |
-
cov3D_precomp,
|
449 |
-
colors_precomp,
|
450 |
-
viewmatrix,
|
451 |
-
projmatrix,
|
452 |
-
cam_pos,
|
453 |
-
W, H,
|
454 |
-
tan_fovx, tan_fovy,
|
455 |
-
focal_x, focal_y,
|
456 |
-
radii,
|
457 |
-
means2D,
|
458 |
-
depths,
|
459 |
-
cov3Ds,
|
460 |
-
rgb,
|
461 |
-
conic_opacity,
|
462 |
-
grid,
|
463 |
-
tiles_touched,
|
464 |
-
prefiltered
|
465 |
-
);
|
466 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/forward.h
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#ifndef CUDA_RASTERIZER_FORWARD_H_INCLUDED
|
13 |
-
#define CUDA_RASTERIZER_FORWARD_H_INCLUDED
|
14 |
-
|
15 |
-
#include <cuda.h>
|
16 |
-
#include "cuda_runtime.h"
|
17 |
-
#include "device_launch_parameters.h"
|
18 |
-
#define GLM_FORCE_CUDA
|
19 |
-
#include <glm/glm.hpp>
|
20 |
-
|
21 |
-
namespace FORWARD
|
22 |
-
{
|
23 |
-
// Perform initial steps for each Gaussian prior to rasterization.
|
24 |
-
void preprocess(int P, int D, int M,
|
25 |
-
const float* orig_points,
|
26 |
-
const glm::vec3* scales,
|
27 |
-
const float scale_modifier,
|
28 |
-
const glm::vec4* rotations,
|
29 |
-
const float* opacities,
|
30 |
-
const float* shs,
|
31 |
-
bool* clamped,
|
32 |
-
const float* cov3D_precomp,
|
33 |
-
const float* colors_precomp,
|
34 |
-
const float* viewmatrix,
|
35 |
-
const float* projmatrix,
|
36 |
-
const glm::vec3* cam_pos,
|
37 |
-
const int W, int H,
|
38 |
-
const float focal_x, float focal_y,
|
39 |
-
const float tan_fovx, float tan_fovy,
|
40 |
-
int* radii,
|
41 |
-
float2* points_xy_image,
|
42 |
-
float* depths,
|
43 |
-
float* cov3Ds,
|
44 |
-
float* colors,
|
45 |
-
float4* conic_opacity,
|
46 |
-
const dim3 grid,
|
47 |
-
uint32_t* tiles_touched,
|
48 |
-
bool prefiltered);
|
49 |
-
|
50 |
-
// Main rasterization method.
|
51 |
-
void render(
|
52 |
-
const dim3 grid, dim3 block,
|
53 |
-
const uint2* ranges,
|
54 |
-
const uint32_t* point_list,
|
55 |
-
int W, int H,
|
56 |
-
const float2* points_xy_image,
|
57 |
-
const float* features,
|
58 |
-
const float* depths,
|
59 |
-
const float4* conic_opacity,
|
60 |
-
float* out_alpha,
|
61 |
-
uint32_t* n_contrib,
|
62 |
-
const float* bg_color,
|
63 |
-
float* out_color,
|
64 |
-
float* out_depth);
|
65 |
-
}
|
66 |
-
|
67 |
-
|
68 |
-
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/rasterizer.h
DELETED
@@ -1,94 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#ifndef CUDA_RASTERIZER_H_INCLUDED
|
13 |
-
#define CUDA_RASTERIZER_H_INCLUDED
|
14 |
-
|
15 |
-
#include <vector>
|
16 |
-
#include <functional>
|
17 |
-
|
18 |
-
namespace CudaRasterizer
|
19 |
-
{
|
20 |
-
class Rasterizer
|
21 |
-
{
|
22 |
-
public:
|
23 |
-
|
24 |
-
static void markVisible(
|
25 |
-
int P,
|
26 |
-
float* means3D,
|
27 |
-
float* viewmatrix,
|
28 |
-
float* projmatrix,
|
29 |
-
bool* present);
|
30 |
-
|
31 |
-
static int forward(
|
32 |
-
std::function<char* (size_t)> geometryBuffer,
|
33 |
-
std::function<char* (size_t)> binningBuffer,
|
34 |
-
std::function<char* (size_t)> imageBuffer,
|
35 |
-
const int P, int D, int M,
|
36 |
-
const float* background,
|
37 |
-
const int width, int height,
|
38 |
-
const float* means3D,
|
39 |
-
const float* shs,
|
40 |
-
const float* colors_precomp,
|
41 |
-
const float* opacities,
|
42 |
-
const float* scales,
|
43 |
-
const float scale_modifier,
|
44 |
-
const float* rotations,
|
45 |
-
const float* cov3D_precomp,
|
46 |
-
const float* viewmatrix,
|
47 |
-
const float* projmatrix,
|
48 |
-
const float* cam_pos,
|
49 |
-
const float tan_fovx, float tan_fovy,
|
50 |
-
const bool prefiltered,
|
51 |
-
float* out_color,
|
52 |
-
float* out_depth,
|
53 |
-
float* out_alpha,
|
54 |
-
int* radii = nullptr,
|
55 |
-
bool debug = false);
|
56 |
-
|
57 |
-
static void backward(
|
58 |
-
const int P, int D, int M, int R,
|
59 |
-
const float* background,
|
60 |
-
const int width, int height,
|
61 |
-
const float* means3D,
|
62 |
-
const float* shs,
|
63 |
-
const float* colors_precomp,
|
64 |
-
const float* alphas,
|
65 |
-
const float* scales,
|
66 |
-
const float scale_modifier,
|
67 |
-
const float* rotations,
|
68 |
-
const float* cov3D_precomp,
|
69 |
-
const float* viewmatrix,
|
70 |
-
const float* projmatrix,
|
71 |
-
const float* campos,
|
72 |
-
const float tan_fovx, float tan_fovy,
|
73 |
-
const int* radii,
|
74 |
-
char* geom_buffer,
|
75 |
-
char* binning_buffer,
|
76 |
-
char* image_buffer,
|
77 |
-
const float* dL_dpix,
|
78 |
-
const float* dL_dpix_depth,
|
79 |
-
const float* dL_dalphas,
|
80 |
-
float* dL_dmean2D,
|
81 |
-
float* dL_dconic,
|
82 |
-
float* dL_dopacity,
|
83 |
-
float* dL_dcolor,
|
84 |
-
float* dL_ddepth,
|
85 |
-
float* dL_dmean3D,
|
86 |
-
float* dL_dcov3D,
|
87 |
-
float* dL_dsh,
|
88 |
-
float* dL_dscale,
|
89 |
-
float* dL_drot,
|
90 |
-
bool debug);
|
91 |
-
};
|
92 |
-
};
|
93 |
-
|
94 |
-
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/rasterizer_impl.cu
DELETED
@@ -1,447 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#include "rasterizer_impl.h"
|
13 |
-
#include <iostream>
|
14 |
-
#include <fstream>
|
15 |
-
#include <algorithm>
|
16 |
-
#include <numeric>
|
17 |
-
#include <cuda.h>
|
18 |
-
#include "cuda_runtime.h"
|
19 |
-
#include "device_launch_parameters.h"
|
20 |
-
#include <cub/cub.cuh>
|
21 |
-
#include <cub/device/device_radix_sort.cuh>
|
22 |
-
#define GLM_FORCE_CUDA
|
23 |
-
#include <glm/glm.hpp>
|
24 |
-
|
25 |
-
#include <cooperative_groups.h>
|
26 |
-
#include <cooperative_groups/reduce.h>
|
27 |
-
namespace cg = cooperative_groups;
|
28 |
-
|
29 |
-
#include "auxiliary.h"
|
30 |
-
#include "forward.h"
|
31 |
-
#include "backward.h"
|
32 |
-
|
33 |
-
// Helper function to find the next-highest bit of the MSB
|
34 |
-
// on the CPU.
|
35 |
-
uint32_t getHigherMsb(uint32_t n)
|
36 |
-
{
|
37 |
-
uint32_t msb = sizeof(n) * 4;
|
38 |
-
uint32_t step = msb;
|
39 |
-
while (step > 1)
|
40 |
-
{
|
41 |
-
step /= 2;
|
42 |
-
if (n >> msb)
|
43 |
-
msb += step;
|
44 |
-
else
|
45 |
-
msb -= step;
|
46 |
-
}
|
47 |
-
if (n >> msb)
|
48 |
-
msb++;
|
49 |
-
return msb;
|
50 |
-
}
|
51 |
-
|
52 |
-
// Wrapper method to call auxiliary coarse frustum containment test.
|
53 |
-
// Mark all Gaussians that pass it.
|
54 |
-
__global__ void checkFrustum(int P,
|
55 |
-
const float* orig_points,
|
56 |
-
const float* viewmatrix,
|
57 |
-
const float* projmatrix,
|
58 |
-
bool* present)
|
59 |
-
{
|
60 |
-
auto idx = cg::this_grid().thread_rank();
|
61 |
-
if (idx >= P)
|
62 |
-
return;
|
63 |
-
|
64 |
-
float3 p_view;
|
65 |
-
present[idx] = in_frustum(idx, orig_points, viewmatrix, projmatrix, false, p_view);
|
66 |
-
}
|
67 |
-
|
68 |
-
// Generates one key/value pair for all Gaussian / tile overlaps.
|
69 |
-
// Run once per Gaussian (1:N mapping).
|
70 |
-
__global__ void duplicateWithKeys(
|
71 |
-
int P,
|
72 |
-
const float2* points_xy,
|
73 |
-
const float* depths,
|
74 |
-
const uint32_t* offsets,
|
75 |
-
uint64_t* gaussian_keys_unsorted,
|
76 |
-
uint32_t* gaussian_values_unsorted,
|
77 |
-
int* radii,
|
78 |
-
dim3 grid)
|
79 |
-
{
|
80 |
-
auto idx = cg::this_grid().thread_rank();
|
81 |
-
if (idx >= P)
|
82 |
-
return;
|
83 |
-
|
84 |
-
// Generate no key/value pair for invisible Gaussians
|
85 |
-
if (radii[idx] > 0)
|
86 |
-
{
|
87 |
-
// Find this Gaussian's offset in buffer for writing keys/values.
|
88 |
-
uint32_t off = (idx == 0) ? 0 : offsets[idx - 1];
|
89 |
-
uint2 rect_min, rect_max;
|
90 |
-
|
91 |
-
getRect(points_xy[idx], radii[idx], rect_min, rect_max, grid);
|
92 |
-
|
93 |
-
// For each tile that the bounding rect overlaps, emit a
|
94 |
-
// key/value pair. The key is | tile ID | depth |,
|
95 |
-
// and the value is the ID of the Gaussian. Sorting the values
|
96 |
-
// with this key yields Gaussian IDs in a list, such that they
|
97 |
-
// are first sorted by tile and then by depth.
|
98 |
-
for (int y = rect_min.y; y < rect_max.y; y++)
|
99 |
-
{
|
100 |
-
for (int x = rect_min.x; x < rect_max.x; x++)
|
101 |
-
{
|
102 |
-
uint64_t key = y * grid.x + x;
|
103 |
-
key <<= 32;
|
104 |
-
key |= *((uint32_t*)&depths[idx]);
|
105 |
-
gaussian_keys_unsorted[off] = key;
|
106 |
-
gaussian_values_unsorted[off] = idx;
|
107 |
-
off++;
|
108 |
-
}
|
109 |
-
}
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
// Check keys to see if it is at the start/end of one tile's range in
|
114 |
-
// the full sorted list. If yes, write start/end of this tile.
|
115 |
-
// Run once per instanced (duplicated) Gaussian ID.
|
116 |
-
__global__ void identifyTileRanges(int L, uint64_t* point_list_keys, uint2* ranges)
|
117 |
-
{
|
118 |
-
auto idx = cg::this_grid().thread_rank();
|
119 |
-
if (idx >= L)
|
120 |
-
return;
|
121 |
-
|
122 |
-
// Read tile ID from key. Update start/end of tile range if at limit.
|
123 |
-
uint64_t key = point_list_keys[idx];
|
124 |
-
uint32_t currtile = key >> 32;
|
125 |
-
if (idx == 0)
|
126 |
-
ranges[currtile].x = 0;
|
127 |
-
else
|
128 |
-
{
|
129 |
-
uint32_t prevtile = point_list_keys[idx - 1] >> 32;
|
130 |
-
if (currtile != prevtile)
|
131 |
-
{
|
132 |
-
ranges[prevtile].y = idx;
|
133 |
-
ranges[currtile].x = idx;
|
134 |
-
}
|
135 |
-
}
|
136 |
-
if (idx == L - 1)
|
137 |
-
ranges[currtile].y = L;
|
138 |
-
}
|
139 |
-
|
140 |
-
// Mark Gaussians as visible/invisible, based on view frustum testing
|
141 |
-
void CudaRasterizer::Rasterizer::markVisible(
|
142 |
-
int P,
|
143 |
-
float* means3D,
|
144 |
-
float* viewmatrix,
|
145 |
-
float* projmatrix,
|
146 |
-
bool* present)
|
147 |
-
{
|
148 |
-
checkFrustum << <(P + 255) / 256, 256 >> > (
|
149 |
-
P,
|
150 |
-
means3D,
|
151 |
-
viewmatrix, projmatrix,
|
152 |
-
present);
|
153 |
-
}
|
154 |
-
|
155 |
-
CudaRasterizer::GeometryState CudaRasterizer::GeometryState::fromChunk(char*& chunk, size_t P)
|
156 |
-
{
|
157 |
-
GeometryState geom;
|
158 |
-
obtain(chunk, geom.depths, P, 128);
|
159 |
-
obtain(chunk, geom.clamped, P * 3, 128);
|
160 |
-
obtain(chunk, geom.internal_radii, P, 128);
|
161 |
-
obtain(chunk, geom.means2D, P, 128);
|
162 |
-
obtain(chunk, geom.cov3D, P * 6, 128);
|
163 |
-
obtain(chunk, geom.conic_opacity, P, 128);
|
164 |
-
obtain(chunk, geom.rgb, P * 3, 128);
|
165 |
-
obtain(chunk, geom.tiles_touched, P, 128);
|
166 |
-
cub::DeviceScan::InclusiveSum(nullptr, geom.scan_size, geom.tiles_touched, geom.tiles_touched, P);
|
167 |
-
obtain(chunk, geom.scanning_space, geom.scan_size, 128);
|
168 |
-
obtain(chunk, geom.point_offsets, P, 128);
|
169 |
-
return geom;
|
170 |
-
}
|
171 |
-
|
172 |
-
CudaRasterizer::ImageState CudaRasterizer::ImageState::fromChunk(char*& chunk, size_t N)
|
173 |
-
{
|
174 |
-
ImageState img;
|
175 |
-
obtain(chunk, img.n_contrib, N, 128);
|
176 |
-
obtain(chunk, img.ranges, N, 128);
|
177 |
-
return img;
|
178 |
-
}
|
179 |
-
|
180 |
-
CudaRasterizer::BinningState CudaRasterizer::BinningState::fromChunk(char*& chunk, size_t P)
|
181 |
-
{
|
182 |
-
BinningState binning;
|
183 |
-
obtain(chunk, binning.point_list, P, 128);
|
184 |
-
obtain(chunk, binning.point_list_unsorted, P, 128);
|
185 |
-
obtain(chunk, binning.point_list_keys, P, 128);
|
186 |
-
obtain(chunk, binning.point_list_keys_unsorted, P, 128);
|
187 |
-
cub::DeviceRadixSort::SortPairs(
|
188 |
-
nullptr, binning.sorting_size,
|
189 |
-
binning.point_list_keys_unsorted, binning.point_list_keys,
|
190 |
-
binning.point_list_unsorted, binning.point_list, P);
|
191 |
-
obtain(chunk, binning.list_sorting_space, binning.sorting_size, 128);
|
192 |
-
return binning;
|
193 |
-
}
|
194 |
-
|
195 |
-
// Forward rendering procedure for differentiable rasterization
|
196 |
-
// of Gaussians.
|
197 |
-
int CudaRasterizer::Rasterizer::forward(
|
198 |
-
std::function<char* (size_t)> geometryBuffer,
|
199 |
-
std::function<char* (size_t)> binningBuffer,
|
200 |
-
std::function<char* (size_t)> imageBuffer,
|
201 |
-
const int P, int D, int M,
|
202 |
-
const float* background,
|
203 |
-
const int width, int height,
|
204 |
-
const float* means3D,
|
205 |
-
const float* shs,
|
206 |
-
const float* colors_precomp,
|
207 |
-
const float* opacities,
|
208 |
-
const float* scales,
|
209 |
-
const float scale_modifier,
|
210 |
-
const float* rotations,
|
211 |
-
const float* cov3D_precomp,
|
212 |
-
const float* viewmatrix,
|
213 |
-
const float* projmatrix,
|
214 |
-
const float* cam_pos,
|
215 |
-
const float tan_fovx, float tan_fovy,
|
216 |
-
const bool prefiltered,
|
217 |
-
float* out_color,
|
218 |
-
float* out_depth,
|
219 |
-
float* out_alpha,
|
220 |
-
int* radii,
|
221 |
-
bool debug)
|
222 |
-
{
|
223 |
-
const float focal_y = height / (2.0f * tan_fovy);
|
224 |
-
const float focal_x = width / (2.0f * tan_fovx);
|
225 |
-
|
226 |
-
size_t chunk_size = required<GeometryState>(P);
|
227 |
-
char* chunkptr = geometryBuffer(chunk_size);
|
228 |
-
GeometryState geomState = GeometryState::fromChunk(chunkptr, P);
|
229 |
-
|
230 |
-
if (radii == nullptr)
|
231 |
-
{
|
232 |
-
radii = geomState.internal_radii;
|
233 |
-
}
|
234 |
-
|
235 |
-
dim3 tile_grid((width + BLOCK_X - 1) / BLOCK_X, (height + BLOCK_Y - 1) / BLOCK_Y, 1);
|
236 |
-
dim3 block(BLOCK_X, BLOCK_Y, 1);
|
237 |
-
|
238 |
-
// Dynamically resize image-based auxiliary buffers during training
|
239 |
-
size_t img_chunk_size = required<ImageState>(width * height);
|
240 |
-
char* img_chunkptr = imageBuffer(img_chunk_size);
|
241 |
-
ImageState imgState = ImageState::fromChunk(img_chunkptr, width * height);
|
242 |
-
|
243 |
-
if (NUM_CHANNELS != 3 && colors_precomp == nullptr)
|
244 |
-
{
|
245 |
-
throw std::runtime_error("For non-RGB, provide precomputed Gaussian colors!");
|
246 |
-
}
|
247 |
-
|
248 |
-
// Run preprocessing per-Gaussian (transformation, bounding, conversion of SHs to RGB)
|
249 |
-
CHECK_CUDA(FORWARD::preprocess(
|
250 |
-
P, D, M,
|
251 |
-
means3D,
|
252 |
-
(glm::vec3*)scales,
|
253 |
-
scale_modifier,
|
254 |
-
(glm::vec4*)rotations,
|
255 |
-
opacities,
|
256 |
-
shs,
|
257 |
-
geomState.clamped,
|
258 |
-
cov3D_precomp,
|
259 |
-
colors_precomp,
|
260 |
-
viewmatrix, projmatrix,
|
261 |
-
(glm::vec3*)cam_pos,
|
262 |
-
width, height,
|
263 |
-
focal_x, focal_y,
|
264 |
-
tan_fovx, tan_fovy,
|
265 |
-
radii,
|
266 |
-
geomState.means2D,
|
267 |
-
geomState.depths,
|
268 |
-
geomState.cov3D,
|
269 |
-
geomState.rgb,
|
270 |
-
geomState.conic_opacity,
|
271 |
-
tile_grid,
|
272 |
-
geomState.tiles_touched,
|
273 |
-
prefiltered
|
274 |
-
), debug)
|
275 |
-
|
276 |
-
// Compute prefix sum over full list of touched tile counts by Gaussians
|
277 |
-
// E.g., [2, 3, 0, 2, 1] -> [2, 5, 5, 7, 8]
|
278 |
-
CHECK_CUDA(cub::DeviceScan::InclusiveSum(geomState.scanning_space, geomState.scan_size, geomState.tiles_touched, geomState.point_offsets, P), debug)
|
279 |
-
|
280 |
-
// Retrieve total number of Gaussian instances to launch and resize aux buffers
|
281 |
-
int num_rendered;
|
282 |
-
CHECK_CUDA(cudaMemcpy(&num_rendered, geomState.point_offsets + P - 1, sizeof(int), cudaMemcpyDeviceToHost), debug);
|
283 |
-
|
284 |
-
size_t binning_chunk_size = required<BinningState>(num_rendered);
|
285 |
-
char* binning_chunkptr = binningBuffer(binning_chunk_size);
|
286 |
-
BinningState binningState = BinningState::fromChunk(binning_chunkptr, num_rendered);
|
287 |
-
|
288 |
-
// For each instance to be rendered, produce adequate [ tile | depth ] key
|
289 |
-
// and corresponding dublicated Gaussian indices to be sorted
|
290 |
-
duplicateWithKeys << <(P + 255) / 256, 256 >> > (
|
291 |
-
P,
|
292 |
-
geomState.means2D,
|
293 |
-
geomState.depths,
|
294 |
-
geomState.point_offsets,
|
295 |
-
binningState.point_list_keys_unsorted,
|
296 |
-
binningState.point_list_unsorted,
|
297 |
-
radii,
|
298 |
-
tile_grid)
|
299 |
-
CHECK_CUDA(, debug)
|
300 |
-
|
301 |
-
int bit = getHigherMsb(tile_grid.x * tile_grid.y);
|
302 |
-
|
303 |
-
// Sort complete list of (duplicated) Gaussian indices by keys
|
304 |
-
CHECK_CUDA(cub::DeviceRadixSort::SortPairs(
|
305 |
-
binningState.list_sorting_space,
|
306 |
-
binningState.sorting_size,
|
307 |
-
binningState.point_list_keys_unsorted, binningState.point_list_keys,
|
308 |
-
binningState.point_list_unsorted, binningState.point_list,
|
309 |
-
num_rendered, 0, 32 + bit), debug)
|
310 |
-
|
311 |
-
CHECK_CUDA(cudaMemset(imgState.ranges, 0, tile_grid.x * tile_grid.y * sizeof(uint2)), debug);
|
312 |
-
|
313 |
-
// Identify start and end of per-tile workloads in sorted list
|
314 |
-
if (num_rendered > 0)
|
315 |
-
identifyTileRanges << <(num_rendered + 255) / 256, 256 >> > (
|
316 |
-
num_rendered,
|
317 |
-
binningState.point_list_keys,
|
318 |
-
imgState.ranges);
|
319 |
-
CHECK_CUDA(, debug);
|
320 |
-
|
321 |
-
// Let each tile blend its range of Gaussians independently in parallel
|
322 |
-
const float* feature_ptr = colors_precomp != nullptr ? colors_precomp : geomState.rgb;
|
323 |
-
CHECK_CUDA(FORWARD::render(
|
324 |
-
tile_grid, block,
|
325 |
-
imgState.ranges,
|
326 |
-
binningState.point_list,
|
327 |
-
width, height,
|
328 |
-
geomState.means2D,
|
329 |
-
feature_ptr,
|
330 |
-
geomState.depths,
|
331 |
-
geomState.conic_opacity,
|
332 |
-
out_alpha,
|
333 |
-
imgState.n_contrib,
|
334 |
-
background,
|
335 |
-
out_color,
|
336 |
-
out_depth), debug);
|
337 |
-
|
338 |
-
return num_rendered;
|
339 |
-
}
|
340 |
-
|
341 |
-
// Produce necessary gradients for optimization, corresponding
|
342 |
-
// to forward render pass
|
343 |
-
void CudaRasterizer::Rasterizer::backward(
|
344 |
-
const int P, int D, int M, int R,
|
345 |
-
const float* background,
|
346 |
-
const int width, int height,
|
347 |
-
const float* means3D,
|
348 |
-
const float* shs,
|
349 |
-
const float* colors_precomp,
|
350 |
-
const float* alphas,
|
351 |
-
const float* scales,
|
352 |
-
const float scale_modifier,
|
353 |
-
const float* rotations,
|
354 |
-
const float* cov3D_precomp,
|
355 |
-
const float* viewmatrix,
|
356 |
-
const float* projmatrix,
|
357 |
-
const float* campos,
|
358 |
-
const float tan_fovx, float tan_fovy,
|
359 |
-
const int* radii,
|
360 |
-
char* geom_buffer,
|
361 |
-
char* binning_buffer,
|
362 |
-
char* img_buffer,
|
363 |
-
const float* dL_dpix,
|
364 |
-
const float* dL_dpix_depth,
|
365 |
-
const float* dL_dalphas,
|
366 |
-
float* dL_dmean2D,
|
367 |
-
float* dL_dconic,
|
368 |
-
float* dL_dopacity,
|
369 |
-
float* dL_dcolor,
|
370 |
-
float* dL_ddepth,
|
371 |
-
float* dL_dmean3D,
|
372 |
-
float* dL_dcov3D,
|
373 |
-
float* dL_dsh,
|
374 |
-
float* dL_dscale,
|
375 |
-
float* dL_drot,
|
376 |
-
bool debug)
|
377 |
-
{
|
378 |
-
GeometryState geomState = GeometryState::fromChunk(geom_buffer, P);
|
379 |
-
BinningState binningState = BinningState::fromChunk(binning_buffer, R);
|
380 |
-
ImageState imgState = ImageState::fromChunk(img_buffer, width * height);
|
381 |
-
|
382 |
-
if (radii == nullptr)
|
383 |
-
{
|
384 |
-
radii = geomState.internal_radii;
|
385 |
-
}
|
386 |
-
|
387 |
-
const float focal_y = height / (2.0f * tan_fovy);
|
388 |
-
const float focal_x = width / (2.0f * tan_fovx);
|
389 |
-
|
390 |
-
const dim3 tile_grid((width + BLOCK_X - 1) / BLOCK_X, (height + BLOCK_Y - 1) / BLOCK_Y, 1);
|
391 |
-
const dim3 block(BLOCK_X, BLOCK_Y, 1);
|
392 |
-
|
393 |
-
// Compute loss gradients w.r.t. 2D mean position, conic matrix,
|
394 |
-
// opacity and RGB of Gaussians from per-pixel loss gradients.
|
395 |
-
// If we were given precomputed colors and not SHs, use them.
|
396 |
-
const float* color_ptr = (colors_precomp != nullptr) ? colors_precomp : geomState.rgb;
|
397 |
-
const float* depth_ptr = geomState.depths;
|
398 |
-
CHECK_CUDA(BACKWARD::render(
|
399 |
-
tile_grid,
|
400 |
-
block,
|
401 |
-
imgState.ranges,
|
402 |
-
binningState.point_list,
|
403 |
-
width, height,
|
404 |
-
background,
|
405 |
-
geomState.means2D,
|
406 |
-
geomState.conic_opacity,
|
407 |
-
color_ptr,
|
408 |
-
depth_ptr,
|
409 |
-
alphas,
|
410 |
-
imgState.n_contrib,
|
411 |
-
dL_dpix,
|
412 |
-
dL_dpix_depth,
|
413 |
-
dL_dalphas,
|
414 |
-
(float3*)dL_dmean2D,
|
415 |
-
(float4*)dL_dconic,
|
416 |
-
dL_dopacity,
|
417 |
-
dL_dcolor,
|
418 |
-
dL_ddepth), debug)
|
419 |
-
|
420 |
-
// Take care of the rest of preprocessing. Was the precomputed covariance
|
421 |
-
// given to us or a scales/rot pair? If precomputed, pass that. If not,
|
422 |
-
// use the one we computed ourselves.
|
423 |
-
const float* cov3D_ptr = (cov3D_precomp != nullptr) ? cov3D_precomp : geomState.cov3D;
|
424 |
-
CHECK_CUDA(BACKWARD::preprocess(P, D, M,
|
425 |
-
(float3*)means3D,
|
426 |
-
radii,
|
427 |
-
shs,
|
428 |
-
geomState.clamped,
|
429 |
-
(glm::vec3*)scales,
|
430 |
-
(glm::vec4*)rotations,
|
431 |
-
scale_modifier,
|
432 |
-
cov3D_ptr,
|
433 |
-
viewmatrix,
|
434 |
-
projmatrix,
|
435 |
-
focal_x, focal_y,
|
436 |
-
tan_fovx, tan_fovy,
|
437 |
-
(glm::vec3*)campos,
|
438 |
-
(float3*)dL_dmean2D,
|
439 |
-
dL_dconic,
|
440 |
-
(glm::vec3*)dL_dmean3D,
|
441 |
-
dL_dcolor,
|
442 |
-
dL_ddepth,
|
443 |
-
dL_dcov3D,
|
444 |
-
dL_dsh,
|
445 |
-
(glm::vec3*)dL_dscale,
|
446 |
-
(glm::vec4*)dL_drot), debug)
|
447 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/cuda_rasterizer/rasterizer_impl.h
DELETED
@@ -1,73 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#pragma once
|
13 |
-
|
14 |
-
#include <iostream>
|
15 |
-
#include <vector>
|
16 |
-
#include "rasterizer.h"
|
17 |
-
#include <cuda_runtime_api.h>
|
18 |
-
|
19 |
-
namespace CudaRasterizer
|
20 |
-
{
|
21 |
-
template <typename T>
|
22 |
-
static void obtain(char*& chunk, T*& ptr, std::size_t count, std::size_t alignment)
|
23 |
-
{
|
24 |
-
std::size_t offset = (reinterpret_cast<std::uintptr_t>(chunk) + alignment - 1) & ~(alignment - 1);
|
25 |
-
ptr = reinterpret_cast<T*>(offset);
|
26 |
-
chunk = reinterpret_cast<char*>(ptr + count);
|
27 |
-
}
|
28 |
-
|
29 |
-
struct GeometryState
|
30 |
-
{
|
31 |
-
size_t scan_size;
|
32 |
-
float* depths;
|
33 |
-
char* scanning_space;
|
34 |
-
bool* clamped;
|
35 |
-
int* internal_radii;
|
36 |
-
float2* means2D;
|
37 |
-
float* cov3D;
|
38 |
-
float4* conic_opacity;
|
39 |
-
float* rgb;
|
40 |
-
uint32_t* point_offsets;
|
41 |
-
uint32_t* tiles_touched;
|
42 |
-
|
43 |
-
static GeometryState fromChunk(char*& chunk, size_t P);
|
44 |
-
};
|
45 |
-
|
46 |
-
struct ImageState
|
47 |
-
{
|
48 |
-
uint2* ranges;
|
49 |
-
uint32_t* n_contrib;
|
50 |
-
|
51 |
-
static ImageState fromChunk(char*& chunk, size_t N);
|
52 |
-
};
|
53 |
-
|
54 |
-
struct BinningState
|
55 |
-
{
|
56 |
-
size_t sorting_size;
|
57 |
-
uint64_t* point_list_keys_unsorted;
|
58 |
-
uint64_t* point_list_keys;
|
59 |
-
uint32_t* point_list_unsorted;
|
60 |
-
uint32_t* point_list;
|
61 |
-
char* list_sorting_space;
|
62 |
-
|
63 |
-
static BinningState fromChunk(char*& chunk, size_t P);
|
64 |
-
};
|
65 |
-
|
66 |
-
template<typename T>
|
67 |
-
size_t required(size_t P)
|
68 |
-
{
|
69 |
-
char* size = nullptr;
|
70 |
-
T::fromChunk(size, P);
|
71 |
-
return ((size_t)size) + 128;
|
72 |
-
}
|
73 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/diff_gaussian_rasterization/__init__.py
DELETED
@@ -1,224 +0,0 @@
|
|
1 |
-
#
|
2 |
-
# Copyright (C) 2023, Inria
|
3 |
-
# GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
# All rights reserved.
|
5 |
-
#
|
6 |
-
# This software is free for non-commercial, research and evaluation use
|
7 |
-
# under the terms of the LICENSE.md file.
|
8 |
-
#
|
9 |
-
# For inquiries contact george.drettakis@inria.fr
|
10 |
-
#
|
11 |
-
|
12 |
-
from typing import NamedTuple
|
13 |
-
import torch.nn as nn
|
14 |
-
import torch
|
15 |
-
from . import _C
|
16 |
-
|
17 |
-
def cpu_deep_copy_tuple(input_tuple):
|
18 |
-
copied_tensors = [item.cpu().clone() if isinstance(item, torch.Tensor) else item for item in input_tuple]
|
19 |
-
return tuple(copied_tensors)
|
20 |
-
|
21 |
-
def rasterize_gaussians(
|
22 |
-
means3D,
|
23 |
-
means2D,
|
24 |
-
sh,
|
25 |
-
colors_precomp,
|
26 |
-
opacities,
|
27 |
-
scales,
|
28 |
-
rotations,
|
29 |
-
cov3Ds_precomp,
|
30 |
-
raster_settings,
|
31 |
-
):
|
32 |
-
return _RasterizeGaussians.apply(
|
33 |
-
means3D,
|
34 |
-
means2D,
|
35 |
-
sh,
|
36 |
-
colors_precomp,
|
37 |
-
opacities,
|
38 |
-
scales,
|
39 |
-
rotations,
|
40 |
-
cov3Ds_precomp,
|
41 |
-
raster_settings,
|
42 |
-
)
|
43 |
-
|
44 |
-
class _RasterizeGaussians(torch.autograd.Function):
|
45 |
-
@staticmethod
|
46 |
-
def forward(
|
47 |
-
ctx,
|
48 |
-
means3D,
|
49 |
-
means2D,
|
50 |
-
sh,
|
51 |
-
colors_precomp,
|
52 |
-
opacities,
|
53 |
-
scales,
|
54 |
-
rotations,
|
55 |
-
cov3Ds_precomp,
|
56 |
-
raster_settings,
|
57 |
-
):
|
58 |
-
|
59 |
-
# Restructure arguments the way that the C++ lib expects them
|
60 |
-
args = (
|
61 |
-
raster_settings.bg,
|
62 |
-
means3D,
|
63 |
-
colors_precomp,
|
64 |
-
opacities,
|
65 |
-
scales,
|
66 |
-
rotations,
|
67 |
-
raster_settings.scale_modifier,
|
68 |
-
cov3Ds_precomp,
|
69 |
-
raster_settings.viewmatrix,
|
70 |
-
raster_settings.projmatrix,
|
71 |
-
raster_settings.tanfovx,
|
72 |
-
raster_settings.tanfovy,
|
73 |
-
raster_settings.image_height,
|
74 |
-
raster_settings.image_width,
|
75 |
-
sh,
|
76 |
-
raster_settings.sh_degree,
|
77 |
-
raster_settings.campos,
|
78 |
-
raster_settings.prefiltered,
|
79 |
-
raster_settings.debug
|
80 |
-
)
|
81 |
-
|
82 |
-
# Invoke C++/CUDA rasterizer
|
83 |
-
if raster_settings.debug:
|
84 |
-
cpu_args = cpu_deep_copy_tuple(args) # Copy them before they can be corrupted
|
85 |
-
try:
|
86 |
-
num_rendered, color, depth, alpha, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)
|
87 |
-
except Exception as ex:
|
88 |
-
torch.save(cpu_args, "snapshot_fw.dump")
|
89 |
-
print("\nAn error occured in forward. Please forward snapshot_fw.dump for debugging.")
|
90 |
-
raise ex
|
91 |
-
else:
|
92 |
-
num_rendered, color, depth, alpha, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)
|
93 |
-
|
94 |
-
# Keep relevant tensors for backward
|
95 |
-
ctx.raster_settings = raster_settings
|
96 |
-
ctx.num_rendered = num_rendered
|
97 |
-
ctx.save_for_backward(colors_precomp, means3D, scales, rotations, cov3Ds_precomp, radii, sh, geomBuffer, binningBuffer, imgBuffer, alpha)
|
98 |
-
return color, radii, depth, alpha
|
99 |
-
|
100 |
-
@staticmethod
|
101 |
-
def backward(ctx, grad_color, grad_radii, grad_depth, grad_alpha):
|
102 |
-
|
103 |
-
# Restore necessary values from context
|
104 |
-
num_rendered = ctx.num_rendered
|
105 |
-
raster_settings = ctx.raster_settings
|
106 |
-
colors_precomp, means3D, scales, rotations, cov3Ds_precomp, radii, sh, geomBuffer, binningBuffer, imgBuffer, alpha = ctx.saved_tensors
|
107 |
-
|
108 |
-
# Restructure args as C++ method expects them
|
109 |
-
args = (raster_settings.bg,
|
110 |
-
means3D,
|
111 |
-
radii,
|
112 |
-
colors_precomp,
|
113 |
-
scales,
|
114 |
-
rotations,
|
115 |
-
raster_settings.scale_modifier,
|
116 |
-
cov3Ds_precomp,
|
117 |
-
raster_settings.viewmatrix,
|
118 |
-
raster_settings.projmatrix,
|
119 |
-
raster_settings.tanfovx,
|
120 |
-
raster_settings.tanfovy,
|
121 |
-
grad_color,
|
122 |
-
grad_depth,
|
123 |
-
grad_alpha,
|
124 |
-
sh,
|
125 |
-
raster_settings.sh_degree,
|
126 |
-
raster_settings.campos,
|
127 |
-
geomBuffer,
|
128 |
-
num_rendered,
|
129 |
-
binningBuffer,
|
130 |
-
imgBuffer,
|
131 |
-
alpha,
|
132 |
-
raster_settings.debug)
|
133 |
-
|
134 |
-
# Compute gradients for relevant tensors by invoking backward method
|
135 |
-
if raster_settings.debug:
|
136 |
-
cpu_args = cpu_deep_copy_tuple(args) # Copy them before they can be corrupted
|
137 |
-
try:
|
138 |
-
grad_means2D, grad_colors_precomp, grad_opacities, grad_means3D, grad_cov3Ds_precomp, grad_sh, grad_scales, grad_rotations = _C.rasterize_gaussians_backward(*args)
|
139 |
-
except Exception as ex:
|
140 |
-
torch.save(cpu_args, "snapshot_bw.dump")
|
141 |
-
print("\nAn error occured in backward. Writing snapshot_bw.dump for debugging.\n")
|
142 |
-
raise ex
|
143 |
-
else:
|
144 |
-
grad_means2D, grad_colors_precomp, grad_opacities, grad_means3D, grad_cov3Ds_precomp, grad_sh, grad_scales, grad_rotations = _C.rasterize_gaussians_backward(*args)
|
145 |
-
|
146 |
-
grads = (
|
147 |
-
grad_means3D,
|
148 |
-
grad_means2D,
|
149 |
-
grad_sh,
|
150 |
-
grad_colors_precomp,
|
151 |
-
grad_opacities,
|
152 |
-
grad_scales,
|
153 |
-
grad_rotations,
|
154 |
-
grad_cov3Ds_precomp,
|
155 |
-
None,
|
156 |
-
)
|
157 |
-
|
158 |
-
return grads
|
159 |
-
|
160 |
-
class GaussianRasterizationSettings(NamedTuple):
|
161 |
-
image_height: int
|
162 |
-
image_width: int
|
163 |
-
tanfovx : float
|
164 |
-
tanfovy : float
|
165 |
-
bg : torch.Tensor
|
166 |
-
scale_modifier : float
|
167 |
-
viewmatrix : torch.Tensor
|
168 |
-
projmatrix : torch.Tensor
|
169 |
-
sh_degree : int
|
170 |
-
campos : torch.Tensor
|
171 |
-
prefiltered : bool
|
172 |
-
debug : bool
|
173 |
-
|
174 |
-
class GaussianRasterizer(nn.Module):
|
175 |
-
def __init__(self, raster_settings):
|
176 |
-
super().__init__()
|
177 |
-
self.raster_settings = raster_settings
|
178 |
-
|
179 |
-
def markVisible(self, positions):
|
180 |
-
# Mark visible points (based on frustum culling for camera) with a boolean
|
181 |
-
with torch.no_grad():
|
182 |
-
raster_settings = self.raster_settings
|
183 |
-
visible = _C.mark_visible(
|
184 |
-
positions,
|
185 |
-
raster_settings.viewmatrix,
|
186 |
-
raster_settings.projmatrix)
|
187 |
-
|
188 |
-
return visible
|
189 |
-
|
190 |
-
def forward(self, means3D, means2D, opacities, shs = None, colors_precomp = None, scales = None, rotations = None, cov3D_precomp = None):
|
191 |
-
|
192 |
-
raster_settings = self.raster_settings
|
193 |
-
|
194 |
-
if (shs is None and colors_precomp is None) or (shs is not None and colors_precomp is not None):
|
195 |
-
raise Exception('Please provide excatly one of either SHs or precomputed colors!')
|
196 |
-
|
197 |
-
if ((scales is None or rotations is None) and cov3D_precomp is None) or ((scales is not None or rotations is not None) and cov3D_precomp is not None):
|
198 |
-
raise Exception('Please provide exactly one of either scale/rotation pair or precomputed 3D covariance!')
|
199 |
-
|
200 |
-
if shs is None:
|
201 |
-
shs = torch.Tensor([])
|
202 |
-
if colors_precomp is None:
|
203 |
-
colors_precomp = torch.Tensor([])
|
204 |
-
|
205 |
-
if scales is None:
|
206 |
-
scales = torch.Tensor([])
|
207 |
-
if rotations is None:
|
208 |
-
rotations = torch.Tensor([])
|
209 |
-
if cov3D_precomp is None:
|
210 |
-
cov3D_precomp = torch.Tensor([])
|
211 |
-
|
212 |
-
# Invoke C++/CUDA rasterization routine
|
213 |
-
return rasterize_gaussians(
|
214 |
-
means3D,
|
215 |
-
means2D,
|
216 |
-
shs,
|
217 |
-
colors_precomp,
|
218 |
-
opacities,
|
219 |
-
scales,
|
220 |
-
rotations,
|
221 |
-
cov3D_precomp,
|
222 |
-
raster_settings,
|
223 |
-
)
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/ext.cpp
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#include <torch/extension.h>
|
13 |
-
#include "rasterize_points.h"
|
14 |
-
|
15 |
-
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
|
16 |
-
m.def("rasterize_gaussians", &RasterizeGaussiansCUDA);
|
17 |
-
m.def("rasterize_gaussians_backward", &RasterizeGaussiansBackwardCUDA);
|
18 |
-
m.def("mark_visible", &markVisible);
|
19 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/rasterize_points.cu
DELETED
@@ -1,229 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#include <math.h>
|
13 |
-
#include <torch/extension.h>
|
14 |
-
#include <cstdio>
|
15 |
-
#include <sstream>
|
16 |
-
#include <iostream>
|
17 |
-
#include <tuple>
|
18 |
-
#include <stdio.h>
|
19 |
-
#include <cuda_runtime_api.h>
|
20 |
-
#include <memory>
|
21 |
-
#include "cuda_rasterizer/config.h"
|
22 |
-
#include "cuda_rasterizer/rasterizer.h"
|
23 |
-
#include <fstream>
|
24 |
-
#include <string>
|
25 |
-
#include <functional>
|
26 |
-
|
27 |
-
std::function<char*(size_t N)> resizeFunctional(torch::Tensor& t) {
|
28 |
-
auto lambda = [&t](size_t N) {
|
29 |
-
t.resize_({(long long)N});
|
30 |
-
return reinterpret_cast<char*>(t.contiguous().data_ptr());
|
31 |
-
};
|
32 |
-
return lambda;
|
33 |
-
}
|
34 |
-
|
35 |
-
std::tuple<int, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor>
|
36 |
-
RasterizeGaussiansCUDA(
|
37 |
-
const torch::Tensor& background,
|
38 |
-
const torch::Tensor& means3D,
|
39 |
-
const torch::Tensor& colors,
|
40 |
-
const torch::Tensor& opacity,
|
41 |
-
const torch::Tensor& scales,
|
42 |
-
const torch::Tensor& rotations,
|
43 |
-
const float scale_modifier,
|
44 |
-
const torch::Tensor& cov3D_precomp,
|
45 |
-
const torch::Tensor& viewmatrix,
|
46 |
-
const torch::Tensor& projmatrix,
|
47 |
-
const float tan_fovx,
|
48 |
-
const float tan_fovy,
|
49 |
-
const int image_height,
|
50 |
-
const int image_width,
|
51 |
-
const torch::Tensor& sh,
|
52 |
-
const int degree,
|
53 |
-
const torch::Tensor& campos,
|
54 |
-
const bool prefiltered,
|
55 |
-
const bool debug)
|
56 |
-
{
|
57 |
-
if (means3D.ndimension() != 2 || means3D.size(1) != 3) {
|
58 |
-
AT_ERROR("means3D must have dimensions (num_points, 3)");
|
59 |
-
}
|
60 |
-
|
61 |
-
const int P = means3D.size(0);
|
62 |
-
const int H = image_height;
|
63 |
-
const int W = image_width;
|
64 |
-
|
65 |
-
auto int_opts = means3D.options().dtype(torch::kInt32);
|
66 |
-
auto float_opts = means3D.options().dtype(torch::kFloat32);
|
67 |
-
|
68 |
-
torch::Tensor out_color = torch::full({NUM_CHANNELS, H, W}, 0.0, float_opts);
|
69 |
-
torch::Tensor out_depth = torch::full({1, H, W}, 0.0, float_opts);
|
70 |
-
torch::Tensor out_alpha = torch::full({1, H, W}, 0.0, float_opts);
|
71 |
-
torch::Tensor radii = torch::full({P}, 0, means3D.options().dtype(torch::kInt32));
|
72 |
-
|
73 |
-
torch::Device device(torch::kCUDA);
|
74 |
-
torch::TensorOptions options(torch::kByte);
|
75 |
-
torch::Tensor geomBuffer = torch::empty({0}, options.device(device));
|
76 |
-
torch::Tensor binningBuffer = torch::empty({0}, options.device(device));
|
77 |
-
torch::Tensor imgBuffer = torch::empty({0}, options.device(device));
|
78 |
-
std::function<char*(size_t)> geomFunc = resizeFunctional(geomBuffer);
|
79 |
-
std::function<char*(size_t)> binningFunc = resizeFunctional(binningBuffer);
|
80 |
-
std::function<char*(size_t)> imgFunc = resizeFunctional(imgBuffer);
|
81 |
-
|
82 |
-
int rendered = 0;
|
83 |
-
if(P != 0)
|
84 |
-
{
|
85 |
-
int M = 0;
|
86 |
-
if(sh.size(0) != 0)
|
87 |
-
{
|
88 |
-
M = sh.size(1);
|
89 |
-
}
|
90 |
-
|
91 |
-
rendered = CudaRasterizer::Rasterizer::forward(
|
92 |
-
geomFunc,
|
93 |
-
binningFunc,
|
94 |
-
imgFunc,
|
95 |
-
P, degree, M,
|
96 |
-
background.contiguous().data<float>(),
|
97 |
-
W, H,
|
98 |
-
means3D.contiguous().data<float>(),
|
99 |
-
sh.contiguous().data_ptr<float>(),
|
100 |
-
colors.contiguous().data<float>(),
|
101 |
-
opacity.contiguous().data<float>(),
|
102 |
-
scales.contiguous().data_ptr<float>(),
|
103 |
-
scale_modifier,
|
104 |
-
rotations.contiguous().data_ptr<float>(),
|
105 |
-
cov3D_precomp.contiguous().data<float>(),
|
106 |
-
viewmatrix.contiguous().data<float>(),
|
107 |
-
projmatrix.contiguous().data<float>(),
|
108 |
-
campos.contiguous().data<float>(),
|
109 |
-
tan_fovx,
|
110 |
-
tan_fovy,
|
111 |
-
prefiltered,
|
112 |
-
out_color.contiguous().data<float>(),
|
113 |
-
out_depth.contiguous().data<float>(),
|
114 |
-
out_alpha.contiguous().data<float>(),
|
115 |
-
radii.contiguous().data<int>(),
|
116 |
-
debug);
|
117 |
-
}
|
118 |
-
return std::make_tuple(rendered, out_color, out_depth, out_alpha, radii, geomBuffer, binningBuffer, imgBuffer);
|
119 |
-
}
|
120 |
-
|
121 |
-
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor>
|
122 |
-
RasterizeGaussiansBackwardCUDA(
|
123 |
-
const torch::Tensor& background,
|
124 |
-
const torch::Tensor& means3D,
|
125 |
-
const torch::Tensor& radii,
|
126 |
-
const torch::Tensor& colors,
|
127 |
-
const torch::Tensor& scales,
|
128 |
-
const torch::Tensor& rotations,
|
129 |
-
const float scale_modifier,
|
130 |
-
const torch::Tensor& cov3D_precomp,
|
131 |
-
const torch::Tensor& viewmatrix,
|
132 |
-
const torch::Tensor& projmatrix,
|
133 |
-
const float tan_fovx,
|
134 |
-
const float tan_fovy,
|
135 |
-
const torch::Tensor& dL_dout_color,
|
136 |
-
const torch::Tensor& dL_dout_depth,
|
137 |
-
const torch::Tensor& dL_dout_alpha,
|
138 |
-
const torch::Tensor& sh,
|
139 |
-
const int degree,
|
140 |
-
const torch::Tensor& campos,
|
141 |
-
const torch::Tensor& geomBuffer,
|
142 |
-
const int R,
|
143 |
-
const torch::Tensor& binningBuffer,
|
144 |
-
const torch::Tensor& imageBuffer,
|
145 |
-
const torch::Tensor& alphas,
|
146 |
-
const bool debug)
|
147 |
-
{
|
148 |
-
const int P = means3D.size(0);
|
149 |
-
const int H = dL_dout_color.size(1);
|
150 |
-
const int W = dL_dout_color.size(2);
|
151 |
-
|
152 |
-
int M = 0;
|
153 |
-
if(sh.size(0) != 0)
|
154 |
-
{
|
155 |
-
M = sh.size(1);
|
156 |
-
}
|
157 |
-
|
158 |
-
torch::Tensor dL_dmeans3D = torch::zeros({P, 3}, means3D.options());
|
159 |
-
torch::Tensor dL_dmeans2D = torch::zeros({P, 3}, means3D.options());
|
160 |
-
torch::Tensor dL_dcolors = torch::zeros({P, NUM_CHANNELS}, means3D.options());
|
161 |
-
torch::Tensor dL_ddepths = torch::zeros({P, 1}, means3D.options());
|
162 |
-
torch::Tensor dL_dconic = torch::zeros({P, 2, 2}, means3D.options());
|
163 |
-
torch::Tensor dL_dopacity = torch::zeros({P, 1}, means3D.options());
|
164 |
-
torch::Tensor dL_dcov3D = torch::zeros({P, 6}, means3D.options());
|
165 |
-
torch::Tensor dL_dsh = torch::zeros({P, M, 3}, means3D.options());
|
166 |
-
torch::Tensor dL_dscales = torch::zeros({P, 3}, means3D.options());
|
167 |
-
torch::Tensor dL_drotations = torch::zeros({P, 4}, means3D.options());
|
168 |
-
|
169 |
-
if(P != 0)
|
170 |
-
{
|
171 |
-
CudaRasterizer::Rasterizer::backward(P, degree, M, R,
|
172 |
-
background.contiguous().data<float>(),
|
173 |
-
W, H,
|
174 |
-
means3D.contiguous().data<float>(),
|
175 |
-
sh.contiguous().data<float>(),
|
176 |
-
colors.contiguous().data<float>(),
|
177 |
-
alphas.contiguous().data<float>(),
|
178 |
-
scales.data_ptr<float>(),
|
179 |
-
scale_modifier,
|
180 |
-
rotations.data_ptr<float>(),
|
181 |
-
cov3D_precomp.contiguous().data<float>(),
|
182 |
-
viewmatrix.contiguous().data<float>(),
|
183 |
-
projmatrix.contiguous().data<float>(),
|
184 |
-
campos.contiguous().data<float>(),
|
185 |
-
tan_fovx,
|
186 |
-
tan_fovy,
|
187 |
-
radii.contiguous().data<int>(),
|
188 |
-
reinterpret_cast<char*>(geomBuffer.contiguous().data_ptr()),
|
189 |
-
reinterpret_cast<char*>(binningBuffer.contiguous().data_ptr()),
|
190 |
-
reinterpret_cast<char*>(imageBuffer.contiguous().data_ptr()),
|
191 |
-
dL_dout_color.contiguous().data<float>(),
|
192 |
-
dL_dout_depth.contiguous().data<float>(),
|
193 |
-
dL_dout_alpha.contiguous().data<float>(),
|
194 |
-
dL_dmeans2D.contiguous().data<float>(),
|
195 |
-
dL_dconic.contiguous().data<float>(),
|
196 |
-
dL_dopacity.contiguous().data<float>(),
|
197 |
-
dL_dcolors.contiguous().data<float>(),
|
198 |
-
dL_ddepths.contiguous().data<float>(),
|
199 |
-
dL_dmeans3D.contiguous().data<float>(),
|
200 |
-
dL_dcov3D.contiguous().data<float>(),
|
201 |
-
dL_dsh.contiguous().data<float>(),
|
202 |
-
dL_dscales.contiguous().data<float>(),
|
203 |
-
dL_drotations.contiguous().data<float>(),
|
204 |
-
debug);
|
205 |
-
}
|
206 |
-
|
207 |
-
return std::make_tuple(dL_dmeans2D, dL_dcolors, dL_dopacity, dL_dmeans3D, dL_dcov3D, dL_dsh, dL_dscales, dL_drotations);
|
208 |
-
}
|
209 |
-
|
210 |
-
torch::Tensor markVisible(
|
211 |
-
torch::Tensor& means3D,
|
212 |
-
torch::Tensor& viewmatrix,
|
213 |
-
torch::Tensor& projmatrix)
|
214 |
-
{
|
215 |
-
const int P = means3D.size(0);
|
216 |
-
|
217 |
-
torch::Tensor present = torch::full({P}, false, means3D.options().dtype(at::kBool));
|
218 |
-
|
219 |
-
if(P != 0)
|
220 |
-
{
|
221 |
-
CudaRasterizer::Rasterizer::markVisible(P,
|
222 |
-
means3D.contiguous().data<float>(),
|
223 |
-
viewmatrix.contiguous().data<float>(),
|
224 |
-
projmatrix.contiguous().data<float>(),
|
225 |
-
present.contiguous().data<bool>());
|
226 |
-
}
|
227 |
-
|
228 |
-
return present;
|
229 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/rasterize_points.h
DELETED
@@ -1,70 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* Copyright (C) 2023, Inria
|
3 |
-
* GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
* All rights reserved.
|
5 |
-
*
|
6 |
-
* This software is free for non-commercial, research and evaluation use
|
7 |
-
* under the terms of the LICENSE.md file.
|
8 |
-
*
|
9 |
-
* For inquiries contact george.drettakis@inria.fr
|
10 |
-
*/
|
11 |
-
|
12 |
-
#pragma once
|
13 |
-
#include <torch/extension.h>
|
14 |
-
#include <cstdio>
|
15 |
-
#include <tuple>
|
16 |
-
#include <string>
|
17 |
-
|
18 |
-
std::tuple<int, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor>
|
19 |
-
RasterizeGaussiansCUDA(
|
20 |
-
const torch::Tensor& background,
|
21 |
-
const torch::Tensor& means3D,
|
22 |
-
const torch::Tensor& colors,
|
23 |
-
const torch::Tensor& opacity,
|
24 |
-
const torch::Tensor& scales,
|
25 |
-
const torch::Tensor& rotations,
|
26 |
-
const float scale_modifier,
|
27 |
-
const torch::Tensor& cov3D_precomp,
|
28 |
-
const torch::Tensor& viewmatrix,
|
29 |
-
const torch::Tensor& projmatrix,
|
30 |
-
const float tan_fovx,
|
31 |
-
const float tan_fovy,
|
32 |
-
const int image_height,
|
33 |
-
const int image_width,
|
34 |
-
const torch::Tensor& sh,
|
35 |
-
const int degree,
|
36 |
-
const torch::Tensor& campos,
|
37 |
-
const bool prefiltered,
|
38 |
-
const bool debug);
|
39 |
-
|
40 |
-
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor>
|
41 |
-
RasterizeGaussiansBackwardCUDA(
|
42 |
-
const torch::Tensor& background,
|
43 |
-
const torch::Tensor& means3D,
|
44 |
-
const torch::Tensor& radii,
|
45 |
-
const torch::Tensor& colors,
|
46 |
-
const torch::Tensor& scales,
|
47 |
-
const torch::Tensor& rotations,
|
48 |
-
const float scale_modifier,
|
49 |
-
const torch::Tensor& cov3D_precomp,
|
50 |
-
const torch::Tensor& viewmatrix,
|
51 |
-
const torch::Tensor& projmatrix,
|
52 |
-
const float tan_fovx,
|
53 |
-
const float tan_fovy,
|
54 |
-
const torch::Tensor& dL_dout_color,
|
55 |
-
const torch::Tensor& dL_dout_depth,
|
56 |
-
const torch::Tensor& dL_dout_alpha,
|
57 |
-
const torch::Tensor& sh,
|
58 |
-
const int degree,
|
59 |
-
const torch::Tensor& campos,
|
60 |
-
const torch::Tensor& geomBuffer,
|
61 |
-
const int R,
|
62 |
-
const torch::Tensor& binningBuffer,
|
63 |
-
const torch::Tensor& imageBuffer,
|
64 |
-
const torch::Tensor& alpha,
|
65 |
-
const bool debug);
|
66 |
-
|
67 |
-
torch::Tensor markVisible(
|
68 |
-
torch::Tensor& means3D,
|
69 |
-
torch::Tensor& viewmatrix,
|
70 |
-
torch::Tensor& projmatrix);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/setup.py
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
#
|
2 |
-
# Copyright (C) 2023, Inria
|
3 |
-
# GRAPHDECO research group, https://team.inria.fr/graphdeco
|
4 |
-
# All rights reserved.
|
5 |
-
#
|
6 |
-
# This software is free for non-commercial, research and evaluation use
|
7 |
-
# under the terms of the LICENSE.md file.
|
8 |
-
#
|
9 |
-
# For inquiries contact george.drettakis@inria.fr
|
10 |
-
#
|
11 |
-
|
12 |
-
from setuptools import setup
|
13 |
-
from torch.utils.cpp_extension import CUDAExtension, BuildExtension
|
14 |
-
import os
|
15 |
-
os.path.dirname(os.path.abspath(__file__))
|
16 |
-
|
17 |
-
setup(
|
18 |
-
name="diff_gaussian_rasterization",
|
19 |
-
packages=['diff_gaussian_rasterization'],
|
20 |
-
ext_modules=[
|
21 |
-
CUDAExtension(
|
22 |
-
name="diff_gaussian_rasterization._C",
|
23 |
-
sources=[
|
24 |
-
"cuda_rasterizer/rasterizer_impl.cu",
|
25 |
-
"cuda_rasterizer/forward.cu",
|
26 |
-
"cuda_rasterizer/backward.cu",
|
27 |
-
"rasterize_points.cu",
|
28 |
-
"ext.cpp"],
|
29 |
-
extra_compile_args={"nvcc": ["-I" + os.path.join(os.path.dirname(os.path.abspath(__file__)), "third_party/glm/")]})
|
30 |
-
],
|
31 |
-
cmdclass={
|
32 |
-
'build_ext': BuildExtension
|
33 |
-
}
|
34 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/.appveyor.yml
DELETED
@@ -1,92 +0,0 @@
|
|
1 |
-
shallow_clone: true
|
2 |
-
|
3 |
-
platform:
|
4 |
-
- x86
|
5 |
-
- x64
|
6 |
-
|
7 |
-
configuration:
|
8 |
-
- Debug
|
9 |
-
- Release
|
10 |
-
|
11 |
-
image:
|
12 |
-
- Visual Studio 2013
|
13 |
-
- Visual Studio 2015
|
14 |
-
- Visual Studio 2017
|
15 |
-
- Visual Studio 2019
|
16 |
-
|
17 |
-
environment:
|
18 |
-
matrix:
|
19 |
-
- GLM_ARGUMENTS: -DGLM_TEST_FORCE_PURE=ON
|
20 |
-
- GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
|
21 |
-
- GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
|
22 |
-
- GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
|
23 |
-
- GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
|
24 |
-
|
25 |
-
matrix:
|
26 |
-
exclude:
|
27 |
-
- image: Visual Studio 2013
|
28 |
-
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
|
29 |
-
- image: Visual Studio 2013
|
30 |
-
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
|
31 |
-
- image: Visual Studio 2013
|
32 |
-
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
|
33 |
-
- image: Visual Studio 2013
|
34 |
-
configuration: Debug
|
35 |
-
- image: Visual Studio 2015
|
36 |
-
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
|
37 |
-
- image: Visual Studio 2015
|
38 |
-
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
|
39 |
-
- image: Visual Studio 2015
|
40 |
-
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
|
41 |
-
- image: Visual Studio 2015
|
42 |
-
platform: x86
|
43 |
-
- image: Visual Studio 2015
|
44 |
-
configuration: Debug
|
45 |
-
- image: Visual Studio 2017
|
46 |
-
platform: x86
|
47 |
-
- image: Visual Studio 2017
|
48 |
-
configuration: Debug
|
49 |
-
- image: Visual Studio 2019
|
50 |
-
platform: x64
|
51 |
-
|
52 |
-
branches:
|
53 |
-
only:
|
54 |
-
- master
|
55 |
-
|
56 |
-
before_build:
|
57 |
-
- ps: |
|
58 |
-
mkdir build
|
59 |
-
cd build
|
60 |
-
|
61 |
-
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2013") {
|
62 |
-
$env:generator="Visual Studio 12 2013"
|
63 |
-
}
|
64 |
-
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") {
|
65 |
-
$env:generator="Visual Studio 14 2015"
|
66 |
-
}
|
67 |
-
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2017") {
|
68 |
-
$env:generator="Visual Studio 15 2017"
|
69 |
-
}
|
70 |
-
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2019") {
|
71 |
-
$env:generator="Visual Studio 16 2019"
|
72 |
-
}
|
73 |
-
if ($env:PLATFORM -eq "x64") {
|
74 |
-
$env:generator="$env:generator Win64"
|
75 |
-
}
|
76 |
-
echo generator="$env:generator"
|
77 |
-
cmake .. -G "$env:generator" -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/install" -DGLM_QUIET=ON -DGLM_TEST_ENABLE=ON "$env:GLM_ARGUMENTS"
|
78 |
-
|
79 |
-
build_script:
|
80 |
-
- cmake --build . --parallel --config %CONFIGURATION% -- /m /v:minimal
|
81 |
-
- cmake --build . --target install --parallel --config %CONFIGURATION% -- /m /v:minimal
|
82 |
-
|
83 |
-
test_script:
|
84 |
-
- ctest --parallel 4 --verbose -C %CONFIGURATION%
|
85 |
-
- cd ..
|
86 |
-
- ps: |
|
87 |
-
mkdir build_test_cmake
|
88 |
-
cd build_test_cmake
|
89 |
-
cmake ..\test\cmake\ -G "$env:generator" -DCMAKE_PREFIX_PATH="$env:APPVEYOR_BUILD_FOLDER/install"
|
90 |
-
- cmake --build . --parallel --config %CONFIGURATION% -- /m /v:minimal
|
91 |
-
|
92 |
-
deploy: off
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/.gitignore
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
# Compiled Object files
|
2 |
-
*.slo
|
3 |
-
*.lo
|
4 |
-
*.o
|
5 |
-
*.obj
|
6 |
-
|
7 |
-
# Precompiled Headers
|
8 |
-
*.gch
|
9 |
-
*.pch
|
10 |
-
|
11 |
-
# Compiled Dynamic libraries
|
12 |
-
*.so
|
13 |
-
*.dylib
|
14 |
-
*.dll
|
15 |
-
|
16 |
-
# Fortran module files
|
17 |
-
*.mod
|
18 |
-
|
19 |
-
# Compiled Static libraries
|
20 |
-
*.lai
|
21 |
-
*.la
|
22 |
-
*.a
|
23 |
-
*.lib
|
24 |
-
|
25 |
-
# Executables
|
26 |
-
*.exe
|
27 |
-
*.out
|
28 |
-
*.app
|
29 |
-
|
30 |
-
# CMake
|
31 |
-
CMakeCache.txt
|
32 |
-
CMakeFiles
|
33 |
-
cmake_install.cmake
|
34 |
-
install_manifest.txt
|
35 |
-
*.cmake
|
36 |
-
!glmConfig.cmake
|
37 |
-
!glmConfig-version.cmake
|
38 |
-
# ^ May need to add future .cmake files as exceptions
|
39 |
-
|
40 |
-
# Test logs
|
41 |
-
Testing/*
|
42 |
-
|
43 |
-
# Test input
|
44 |
-
test/gtc/*.dds
|
45 |
-
|
46 |
-
# Project Files
|
47 |
-
Makefile
|
48 |
-
*.cbp
|
49 |
-
*.user
|
50 |
-
|
51 |
-
# Misc.
|
52 |
-
*.log
|
53 |
-
|
54 |
-
# local build(s)
|
55 |
-
build*
|
56 |
-
|
57 |
-
/.vs
|
58 |
-
/.vscode
|
59 |
-
/CMakeSettings.json
|
60 |
-
.DS_Store
|
61 |
-
*.swp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/.travis.yml
DELETED
@@ -1,388 +0,0 @@
|
|
1 |
-
language: cpp
|
2 |
-
|
3 |
-
branches:
|
4 |
-
only:
|
5 |
-
- master
|
6 |
-
- stable
|
7 |
-
|
8 |
-
jobs:
|
9 |
-
include:
|
10 |
-
- name: "Xcode 7.3 C++98 pure release"
|
11 |
-
os: osx
|
12 |
-
osx_image: xcode7.3
|
13 |
-
env:
|
14 |
-
- MATRIX_EVAL=""
|
15 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON"
|
16 |
-
|
17 |
-
- name: "Xcode 7.3 C++98 sse2 release"
|
18 |
-
os: osx
|
19 |
-
osx_image: xcode7.3
|
20 |
-
env:
|
21 |
-
- MATRIX_EVAL=""
|
22 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
|
23 |
-
|
24 |
-
- name: "Xcode 7.3 C++98 ms release"
|
25 |
-
os: osx
|
26 |
-
osx_image: xcode7.3
|
27 |
-
env:
|
28 |
-
- MATRIX_EVAL=""
|
29 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
|
30 |
-
|
31 |
-
- name: "XCode 7.3 C++11 pure release"
|
32 |
-
os: osx
|
33 |
-
osx_image: xcode7.3
|
34 |
-
env:
|
35 |
-
- MATRIX_EVAL=""
|
36 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON"
|
37 |
-
|
38 |
-
- name: "XCode 7.3 C++11 sse2 release"
|
39 |
-
os: osx
|
40 |
-
osx_image: xcode7.3
|
41 |
-
env:
|
42 |
-
- MATRIX_EVAL=""
|
43 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
|
44 |
-
|
45 |
-
- name: "XCode 10.3 C++11 sse2 release"
|
46 |
-
os: osx
|
47 |
-
osx_image: xcode10.3
|
48 |
-
env:
|
49 |
-
- MATRIX_EVAL=""
|
50 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
|
51 |
-
|
52 |
-
- name: "XCode 12.2 C++11 sse2 release"
|
53 |
-
os: osx
|
54 |
-
osx_image: xcode12.2
|
55 |
-
env:
|
56 |
-
- MATRIX_EVAL=""
|
57 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
|
58 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
59 |
-
- CMAKE_ENV="--parallel"
|
60 |
-
|
61 |
-
- name: "XCode 12.2 C++11 sse2 debug"
|
62 |
-
os: osx
|
63 |
-
osx_image: xcode12.2
|
64 |
-
env:
|
65 |
-
- MATRIX_EVAL=""
|
66 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON"
|
67 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
68 |
-
- CMAKE_ENV="--parallel"
|
69 |
-
|
70 |
-
- name: "XCode 12.2 C++11 avx debug"
|
71 |
-
os: osx
|
72 |
-
osx_image: xcode12.2
|
73 |
-
env:
|
74 |
-
- MATRIX_EVAL=""
|
75 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON"
|
76 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
77 |
-
- CMAKE_ENV="--parallel"
|
78 |
-
|
79 |
-
- name: "XCode 12.2 C++14 avx debug"
|
80 |
-
os: osx
|
81 |
-
osx_image: xcode12.2
|
82 |
-
env:
|
83 |
-
- MATRIX_EVAL=""
|
84 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON"
|
85 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
86 |
-
- CMAKE_ENV="--parallel"
|
87 |
-
|
88 |
-
- name: "XCode 12.2 C++14 pure debug"
|
89 |
-
os: osx
|
90 |
-
osx_image: xcode12.2
|
91 |
-
env:
|
92 |
-
- MATRIX_EVAL=""
|
93 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON"
|
94 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
95 |
-
- CMAKE_ENV="--parallel"
|
96 |
-
|
97 |
-
- name: "XCode 12.2 C++17 pure debug"
|
98 |
-
os: osx
|
99 |
-
osx_image: xcode12.2
|
100 |
-
env:
|
101 |
-
- MATRIX_EVAL=""
|
102 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON"
|
103 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
104 |
-
- CMAKE_ENV="--parallel"
|
105 |
-
|
106 |
-
- name: "XCode 12.2 C++17 sse2 debug"
|
107 |
-
os: osx
|
108 |
-
osx_image: xcode12.2
|
109 |
-
env:
|
110 |
-
- MATRIX_EVAL=""
|
111 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
|
112 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
113 |
-
- CMAKE_ENV="--parallel"
|
114 |
-
|
115 |
-
- name: "XCode 12.2 C++17 sse2 release"
|
116 |
-
os: osx
|
117 |
-
osx_image: xcode12.2
|
118 |
-
env:
|
119 |
-
- MATRIX_EVAL=""
|
120 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
|
121 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
122 |
-
- CMAKE_ENV="--parallel"
|
123 |
-
|
124 |
-
- name: "XCode 12.2 C++17 avx release"
|
125 |
-
os: osx
|
126 |
-
osx_image: xcode12.2
|
127 |
-
env:
|
128 |
-
- MATRIX_EVAL=""
|
129 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON"
|
130 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
131 |
-
- CMAKE_ENV="--parallel"
|
132 |
-
|
133 |
-
- name: "GCC 4.9 C++98 pure release"
|
134 |
-
os: linux
|
135 |
-
dist: Xenial
|
136 |
-
addons:
|
137 |
-
apt:
|
138 |
-
sources:
|
139 |
-
- ubuntu-toolchain-r-test
|
140 |
-
packages:
|
141 |
-
- g++-4.9
|
142 |
-
env:
|
143 |
-
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
|
144 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON"
|
145 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
146 |
-
- CMAKE_ENV="--parallel"
|
147 |
-
|
148 |
-
- name: "GCC 4.9 C++98 pure debug"
|
149 |
-
os: linux
|
150 |
-
dist: Xenial
|
151 |
-
addons:
|
152 |
-
apt:
|
153 |
-
sources:
|
154 |
-
- ubuntu-toolchain-r-test
|
155 |
-
packages:
|
156 |
-
- g++-4.9
|
157 |
-
env:
|
158 |
-
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
|
159 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON"
|
160 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
161 |
-
- CMAKE_ENV="--parallel"
|
162 |
-
|
163 |
-
- name: "GCC 4.9 C++98 ms debug"
|
164 |
-
os: linux
|
165 |
-
dist: Xenial
|
166 |
-
addons:
|
167 |
-
apt:
|
168 |
-
sources:
|
169 |
-
- ubuntu-toolchain-r-test
|
170 |
-
packages:
|
171 |
-
- g++-4.9
|
172 |
-
env:
|
173 |
-
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
|
174 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
|
175 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
176 |
-
- CMAKE_ENV="--parallel"
|
177 |
-
|
178 |
-
- name: "GCC 4.9 C++11 ms debug"
|
179 |
-
os: linux
|
180 |
-
dist: Xenial
|
181 |
-
addons:
|
182 |
-
apt:
|
183 |
-
sources:
|
184 |
-
- ubuntu-toolchain-r-test
|
185 |
-
packages:
|
186 |
-
- g++-4.9
|
187 |
-
env:
|
188 |
-
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
|
189 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
|
190 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
191 |
-
- CMAKE_ENV="--parallel"
|
192 |
-
|
193 |
-
- name: "GCC 4.9 C++11 pure debug"
|
194 |
-
os: linux
|
195 |
-
dist: Xenial
|
196 |
-
addons:
|
197 |
-
apt:
|
198 |
-
sources:
|
199 |
-
- ubuntu-toolchain-r-test
|
200 |
-
packages:
|
201 |
-
- g++-4.9
|
202 |
-
env:
|
203 |
-
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
|
204 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON"
|
205 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
206 |
-
- CMAKE_ENV="--parallel"
|
207 |
-
|
208 |
-
- name: "GCC 6 C++14 pure debug"
|
209 |
-
os: linux
|
210 |
-
dist: bionic
|
211 |
-
addons:
|
212 |
-
apt:
|
213 |
-
sources:
|
214 |
-
- ubuntu-toolchain-r-test
|
215 |
-
packages:
|
216 |
-
- g++-6
|
217 |
-
env:
|
218 |
-
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
|
219 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON"
|
220 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
221 |
-
- CMAKE_ENV="--parallel"
|
222 |
-
|
223 |
-
- name: "GCC 6 C++14 ms debug"
|
224 |
-
os: linux
|
225 |
-
dist: bionic
|
226 |
-
addons:
|
227 |
-
apt:
|
228 |
-
sources:
|
229 |
-
- ubuntu-toolchain-r-test
|
230 |
-
packages:
|
231 |
-
- g++-6
|
232 |
-
env:
|
233 |
-
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
|
234 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
|
235 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
236 |
-
- CMAKE_ENV="--parallel"
|
237 |
-
|
238 |
-
- name: "GCC 7 C++17 ms debug"
|
239 |
-
os: linux
|
240 |
-
dist: bionic
|
241 |
-
addons:
|
242 |
-
apt:
|
243 |
-
sources:
|
244 |
-
- ubuntu-toolchain-r-test
|
245 |
-
packages:
|
246 |
-
- g++-7
|
247 |
-
env:
|
248 |
-
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
|
249 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON"
|
250 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
251 |
-
- CMAKE_ENV="--parallel"
|
252 |
-
|
253 |
-
- name: "GCC 7 C++17 pure debug"
|
254 |
-
os: linux
|
255 |
-
dist: bionic
|
256 |
-
addons:
|
257 |
-
apt:
|
258 |
-
sources:
|
259 |
-
- ubuntu-toolchain-r-test
|
260 |
-
packages:
|
261 |
-
- g++-7
|
262 |
-
env:
|
263 |
-
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
|
264 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
|
265 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
266 |
-
- CMAKE_ENV="--parallel"
|
267 |
-
|
268 |
-
- name: "GCC 10 C++17 pure debug"
|
269 |
-
os: linux
|
270 |
-
dist: bionic
|
271 |
-
addons:
|
272 |
-
apt:
|
273 |
-
sources:
|
274 |
-
- ubuntu-toolchain-r-test
|
275 |
-
packages:
|
276 |
-
- g++-10
|
277 |
-
env:
|
278 |
-
- MATRIX_EVAL="CC=gcc-10 && CXX=g++-10"
|
279 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
|
280 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
281 |
-
- CMAKE_ENV="--parallel"
|
282 |
-
|
283 |
-
- name: "GCC 10 C++17 pure release"
|
284 |
-
os: linux
|
285 |
-
dist: bionic
|
286 |
-
addons:
|
287 |
-
apt:
|
288 |
-
sources:
|
289 |
-
- ubuntu-toolchain-r-test
|
290 |
-
packages:
|
291 |
-
- g++-10
|
292 |
-
env:
|
293 |
-
- MATRIX_EVAL="CC=gcc-10 && CXX=g++-10"
|
294 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
|
295 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
296 |
-
- CMAKE_ENV="--parallel"
|
297 |
-
|
298 |
-
- name: "Clang C++14 pure release"
|
299 |
-
os: linux
|
300 |
-
dist: Xenial
|
301 |
-
env:
|
302 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
303 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON"
|
304 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
305 |
-
- CMAKE_ENV="--parallel"
|
306 |
-
|
307 |
-
- name: "Clang C++14 pure debug"
|
308 |
-
os: linux
|
309 |
-
dist: Xenial
|
310 |
-
env:
|
311 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
312 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON"
|
313 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
314 |
-
- CMAKE_ENV="--parallel"
|
315 |
-
|
316 |
-
- name: "Clang C++14 sse2 debug"
|
317 |
-
os: linux
|
318 |
-
dist: Xenial
|
319 |
-
env:
|
320 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
321 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
|
322 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
323 |
-
- CMAKE_ENV="--parallel"
|
324 |
-
|
325 |
-
- name: "Clang C++14 sse2 debug"
|
326 |
-
os: linux
|
327 |
-
dist: focal
|
328 |
-
env:
|
329 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
330 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
|
331 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
332 |
-
- CMAKE_ENV="--parallel"
|
333 |
-
|
334 |
-
- name: "Clang C++17 sse2 debug"
|
335 |
-
os: linux
|
336 |
-
dist: focal
|
337 |
-
env:
|
338 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
339 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON"
|
340 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
341 |
-
- CMAKE_ENV="--parallel"
|
342 |
-
|
343 |
-
- name: "Clang C++17 avx2 debug"
|
344 |
-
os: linux
|
345 |
-
dist: focal
|
346 |
-
env:
|
347 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
348 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX2=ON"
|
349 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
350 |
-
- CMAKE_ENV="--parallel"
|
351 |
-
|
352 |
-
- name: "Clang C++17 pure debug"
|
353 |
-
os: linux
|
354 |
-
dist: focal
|
355 |
-
env:
|
356 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
357 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
|
358 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
359 |
-
- CMAKE_ENV="--parallel"
|
360 |
-
|
361 |
-
- name: "Clang C++17 pure release"
|
362 |
-
os: linux
|
363 |
-
dist: focal
|
364 |
-
env:
|
365 |
-
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
366 |
-
- CMAKE_BUILD_ENV="-DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON"
|
367 |
-
- CTEST_ENV="--parallel 4 --output-on-failure"
|
368 |
-
- CMAKE_ENV="--parallel"
|
369 |
-
|
370 |
-
before_script:
|
371 |
-
- cmake --version
|
372 |
-
- eval "${MATRIX_EVAL}"
|
373 |
-
|
374 |
-
script:
|
375 |
-
- ${CC} --version
|
376 |
-
- mkdir ./build
|
377 |
-
- cd ./build
|
378 |
-
- cmake -DCMAKE_INSTALL_PREFIX=$TRAVIS_BUILD_DIR/install -DCMAKE_CXX_COMPILER=$COMPILER ${CMAKE_BUILD_ENV} ..
|
379 |
-
- cmake --build . ${CMAKE_ENV}
|
380 |
-
- ctest ${CTEST_ENV}
|
381 |
-
- cmake --build . --target install ${CMAKE_ENV}
|
382 |
-
- cd $TRAVIS_BUILD_DIR
|
383 |
-
- mkdir ./build_test_cmake
|
384 |
-
- cd ./build_test_cmake
|
385 |
-
- cmake -DCMAKE_CXX_COMPILER=$COMPILER $TRAVIS_BUILD_DIR/test/cmake/ -DCMAKE_PREFIX_PATH=$TRAVIS_BUILD_DIR/install
|
386 |
-
- cmake --build .
|
387 |
-
|
388 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/CMakeLists.txt
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
|
2 |
-
cmake_policy(VERSION 3.2)
|
3 |
-
|
4 |
-
|
5 |
-
file(READ "glm/detail/setup.hpp" GLM_SETUP_FILE)
|
6 |
-
string(REGEX MATCH "#define[ ]+GLM_VERSION_MAJOR[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
|
7 |
-
set(GLM_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
8 |
-
string(REGEX MATCH "#define[ ]+GLM_VERSION_MINOR[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
|
9 |
-
set(GLM_VERSION_MINOR "${CMAKE_MATCH_1}")
|
10 |
-
string(REGEX MATCH "#define[ ]+GLM_VERSION_PATCH[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
|
11 |
-
set(GLM_VERSION_PATCH "${CMAKE_MATCH_1}")
|
12 |
-
string(REGEX MATCH "#define[ ]+GLM_VERSION_REVISION[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
|
13 |
-
set(GLM_VERSION_REVISION "${CMAKE_MATCH_1}")
|
14 |
-
|
15 |
-
set(GLM_VERSION ${GLM_VERSION_MAJOR}.${GLM_VERSION_MINOR}.${GLM_VERSION_PATCH}.${GLM_VERSION_REVISION})
|
16 |
-
project(glm VERSION ${GLM_VERSION} LANGUAGES CXX)
|
17 |
-
message(STATUS "GLM: Version " ${GLM_VERSION})
|
18 |
-
|
19 |
-
add_subdirectory(glm)
|
20 |
-
add_library(glm::glm ALIAS glm)
|
21 |
-
|
22 |
-
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
23 |
-
|
24 |
-
include(CPack)
|
25 |
-
install(DIRECTORY glm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PATTERN "CMakeLists.txt" EXCLUDE)
|
26 |
-
install(EXPORT glm FILE glmConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/glm NAMESPACE glm::)
|
27 |
-
include(CMakePackageConfigHelpers)
|
28 |
-
write_basic_package_version_file("glmConfigVersion.cmake" COMPATIBILITY AnyNewerVersion)
|
29 |
-
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/glmConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/glm)
|
30 |
-
|
31 |
-
include(CTest)
|
32 |
-
if(BUILD_TESTING)
|
33 |
-
add_subdirectory(test)
|
34 |
-
endif()
|
35 |
-
|
36 |
-
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
37 |
-
|
38 |
-
if (NOT TARGET uninstall)
|
39 |
-
configure_file(cmake/cmake_uninstall.cmake.in
|
40 |
-
cmake_uninstall.cmake IMMEDIATE @ONLY)
|
41 |
-
|
42 |
-
add_custom_target(uninstall
|
43 |
-
"${CMAKE_COMMAND}" -P
|
44 |
-
"${CMAKE_BINARY_DIR}/cmake_uninstall.cmake")
|
45 |
-
endif()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/cmake/cmake_uninstall.cmake.in
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
2 |
-
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
3 |
-
endif()
|
4 |
-
|
5 |
-
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
6 |
-
string(REGEX REPLACE "\n" ";" files "${files}")
|
7 |
-
foreach(file ${files})
|
8 |
-
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
9 |
-
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
10 |
-
exec_program(
|
11 |
-
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
12 |
-
OUTPUT_VARIABLE rm_out
|
13 |
-
RETURN_VALUE rm_retval
|
14 |
-
)
|
15 |
-
if(NOT "${rm_retval}" STREQUAL 0)
|
16 |
-
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
17 |
-
endif()
|
18 |
-
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
19 |
-
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
20 |
-
endif()
|
21 |
-
endforeach()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/copying.txt
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
================================================================================
|
2 |
-
OpenGL Mathematics (GLM)
|
3 |
-
--------------------------------------------------------------------------------
|
4 |
-
GLM is licensed under The Happy Bunny License or MIT License
|
5 |
-
|
6 |
-
================================================================================
|
7 |
-
The Happy Bunny License (Modified MIT License)
|
8 |
-
--------------------------------------------------------------------------------
|
9 |
-
Copyright (c) 2005 - G-Truc Creation
|
10 |
-
|
11 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
12 |
-
of this software and associated documentation files (the "Software"), to deal
|
13 |
-
in the Software without restriction, including without limitation the rights
|
14 |
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
15 |
-
copies of the Software, and to permit persons to whom the Software is
|
16 |
-
furnished to do so, subject to the following conditions:
|
17 |
-
|
18 |
-
The above copyright notice and this permission notice shall be included in
|
19 |
-
all copies or substantial portions of the Software.
|
20 |
-
|
21 |
-
Restrictions:
|
22 |
-
By making use of the Software for military purposes, you choose to make a
|
23 |
-
Bunny unhappy.
|
24 |
-
|
25 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
26 |
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
27 |
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
28 |
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
29 |
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
30 |
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
31 |
-
THE SOFTWARE.
|
32 |
-
|
33 |
-
================================================================================
|
34 |
-
The MIT License
|
35 |
-
--------------------------------------------------------------------------------
|
36 |
-
Copyright (c) 2005 - G-Truc Creation
|
37 |
-
|
38 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
39 |
-
of this software and associated documentation files (the "Software"), to deal
|
40 |
-
in the Software without restriction, including without limitation the rights
|
41 |
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
42 |
-
copies of the Software, and to permit persons to whom the Software is
|
43 |
-
furnished to do so, subject to the following conditions:
|
44 |
-
|
45 |
-
The above copyright notice and this permission notice shall be included in
|
46 |
-
all copies or substantial portions of the Software.
|
47 |
-
|
48 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
49 |
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
50 |
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
51 |
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
52 |
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
53 |
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
54 |
-
THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/doc/api/a00001_source.html
DELETED
@@ -1,493 +0,0 @@
|
|
1 |
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2 |
-
<html xmlns="http://www.w3.org/1999/xhtml">
|
3 |
-
<head>
|
4 |
-
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
5 |
-
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
6 |
-
<meta name="generator" content="Doxygen 1.8.10"/>
|
7 |
-
<title>0.9.9 API documentation: _features.hpp Source File</title>
|
8 |
-
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
9 |
-
<script type="text/javascript" src="jquery.js"></script>
|
10 |
-
<script type="text/javascript" src="dynsections.js"></script>
|
11 |
-
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
12 |
-
<script type="text/javascript" src="search/searchdata.js"></script>
|
13 |
-
<script type="text/javascript" src="search/search.js"></script>
|
14 |
-
<script type="text/javascript">
|
15 |
-
$(document).ready(function() { init_search(); });
|
16 |
-
</script>
|
17 |
-
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
18 |
-
</head>
|
19 |
-
<body>
|
20 |
-
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
21 |
-
<div id="titlearea">
|
22 |
-
<table cellspacing="0" cellpadding="0">
|
23 |
-
<tbody>
|
24 |
-
<tr style="height: 56px;">
|
25 |
-
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
|
26 |
-
<td id="projectalign" style="padding-left: 0.5em;">
|
27 |
-
<div id="projectname">0.9.9 API documentation
|
28 |
-
</div>
|
29 |
-
</td>
|
30 |
-
</tr>
|
31 |
-
</tbody>
|
32 |
-
</table>
|
33 |
-
</div>
|
34 |
-
<!-- end header part -->
|
35 |
-
<!-- Generated by Doxygen 1.8.10 -->
|
36 |
-
<script type="text/javascript">
|
37 |
-
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
38 |
-
</script>
|
39 |
-
<div id="navrow1" class="tabs">
|
40 |
-
<ul class="tablist">
|
41 |
-
<li><a href="index.html"><span>Main Page</span></a></li>
|
42 |
-
<li><a href="modules.html"><span>Modules</span></a></li>
|
43 |
-
<li class="current"><a href="files.html"><span>Files</span></a></li>
|
44 |
-
<li>
|
45 |
-
<div id="MSearchBox" class="MSearchBoxInactive">
|
46 |
-
<span class="left">
|
47 |
-
<img id="MSearchSelect" src="search/mag_sel.png"
|
48 |
-
onmouseover="return searchBox.OnSearchSelectShow()"
|
49 |
-
onmouseout="return searchBox.OnSearchSelectHide()"
|
50 |
-
alt=""/>
|
51 |
-
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
52 |
-
onfocus="searchBox.OnSearchFieldFocus(true)"
|
53 |
-
onblur="searchBox.OnSearchFieldFocus(false)"
|
54 |
-
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
55 |
-
</span><span class="right">
|
56 |
-
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
57 |
-
</span>
|
58 |
-
</div>
|
59 |
-
</li>
|
60 |
-
</ul>
|
61 |
-
</div>
|
62 |
-
<div id="navrow2" class="tabs2">
|
63 |
-
<ul class="tablist">
|
64 |
-
<li><a href="files.html"><span>File List</span></a></li>
|
65 |
-
</ul>
|
66 |
-
</div>
|
67 |
-
<!-- window showing the filter options -->
|
68 |
-
<div id="MSearchSelectWindow"
|
69 |
-
onmouseover="return searchBox.OnSearchSelectShow()"
|
70 |
-
onmouseout="return searchBox.OnSearchSelectHide()"
|
71 |
-
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
72 |
-
</div>
|
73 |
-
|
74 |
-
<!-- iframe showing the search results (closed by default) -->
|
75 |
-
<div id="MSearchResultsWindow">
|
76 |
-
<iframe src="javascript:void(0)" frameborder="0"
|
77 |
-
name="MSearchResults" id="MSearchResults">
|
78 |
-
</iframe>
|
79 |
-
</div>
|
80 |
-
|
81 |
-
<div id="nav-path" class="navpath">
|
82 |
-
<ul>
|
83 |
-
<li class="navelem"><a class="el" href="dir_3a581ba30d25676e4b797b1f96d53b45.html">F:</a></li><li class="navelem"><a class="el" href="dir_9e5fe034a00e89334fd5186c3e7db156.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_d9496f0844b48bc7e53b5af8c99b9ab2.html">Source</a></li><li class="navelem"><a class="el" href="dir_a8bee7be44182a33f3820393ae0b105d.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_44e5e654415abd9ca6fdeaddaff8565e.html">glm</a></li><li class="navelem"><a class="el" href="dir_cef2d71d502cb69a9252bca2297d9549.html">glm</a></li><li class="navelem"><a class="el" href="dir_033f5edb0915b828d2c46ed4804e5503.html">detail</a></li> </ul>
|
84 |
-
</div>
|
85 |
-
</div><!-- top -->
|
86 |
-
<div class="header">
|
87 |
-
<div class="headertitle">
|
88 |
-
<div class="title">_features.hpp</div> </div>
|
89 |
-
</div><!--header-->
|
90 |
-
<div class="contents">
|
91 |
-
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> <span class="preprocessor">#pragma once</span></div>
|
92 |
-
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
|
93 |
-
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="comment">// #define GLM_CXX98_EXCEPTIONS</span></div>
|
94 |
-
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="comment">// #define GLM_CXX98_RTTI</span></div>
|
95 |
-
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
|
96 |
-
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="comment">// #define GLM_CXX11_RVALUE_REFERENCES</span></div>
|
97 |
-
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="comment">// Rvalue references - GCC 4.3</span></div>
|
98 |
-
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html</span></div>
|
99 |
-
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> </div>
|
100 |
-
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> <span class="comment">// GLM_CXX11_TRAILING_RETURN</span></div>
|
101 |
-
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> <span class="comment">// Rvalue references for *this - GCC not supported</span></div>
|
102 |
-
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm</span></div>
|
103 |
-
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> </div>
|
104 |
-
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="comment">// GLM_CXX11_NONSTATIC_MEMBER_INIT</span></div>
|
105 |
-
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="comment">// Initialization of class objects by rvalues - GCC any</span></div>
|
106 |
-
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html</span></div>
|
107 |
-
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> </div>
|
108 |
-
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="comment">// GLM_CXX11_NONSTATIC_MEMBER_INIT</span></div>
|
109 |
-
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> <span class="comment">// Non-static data member initializers - GCC 4.7</span></div>
|
110 |
-
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm</span></div>
|
111 |
-
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> </div>
|
112 |
-
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> <span class="comment">// #define GLM_CXX11_VARIADIC_TEMPLATE</span></div>
|
113 |
-
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> <span class="comment">// Variadic templates - GCC 4.3</span></div>
|
114 |
-
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf</span></div>
|
115 |
-
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div>
|
116 |
-
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> <span class="comment">//</span></div>
|
117 |
-
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> <span class="comment">// Extending variadic template template parameters - GCC 4.4</span></div>
|
118 |
-
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf</span></div>
|
119 |
-
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> </div>
|
120 |
-
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> <span class="comment">// #define GLM_CXX11_GENERALIZED_INITIALIZERS</span></div>
|
121 |
-
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span> <span class="comment">// Initializer lists - GCC 4.4</span></div>
|
122 |
-
<div class="line"><a name="l00032"></a><span class="lineno"> 32</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm</span></div>
|
123 |
-
<div class="line"><a name="l00033"></a><span class="lineno"> 33</span> </div>
|
124 |
-
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span> <span class="comment">// #define GLM_CXX11_STATIC_ASSERT</span></div>
|
125 |
-
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span> <span class="comment">// Static assertions - GCC 4.3</span></div>
|
126 |
-
<div class="line"><a name="l00036"></a><span class="lineno"> 36</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html</span></div>
|
127 |
-
<div class="line"><a name="l00037"></a><span class="lineno"> 37</span> </div>
|
128 |
-
<div class="line"><a name="l00038"></a><span class="lineno"> 38</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
|
129 |
-
<div class="line"><a name="l00039"></a><span class="lineno"> 39</span> <span class="comment">// auto-typed variables - GCC 4.4</span></div>
|
130 |
-
<div class="line"><a name="l00040"></a><span class="lineno"> 40</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf</span></div>
|
131 |
-
<div class="line"><a name="l00041"></a><span class="lineno"> 41</span> </div>
|
132 |
-
<div class="line"><a name="l00042"></a><span class="lineno"> 42</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
|
133 |
-
<div class="line"><a name="l00043"></a><span class="lineno"> 43</span> <span class="comment">// Multi-declarator auto - GCC 4.4</span></div>
|
134 |
-
<div class="line"><a name="l00044"></a><span class="lineno"> 44</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf</span></div>
|
135 |
-
<div class="line"><a name="l00045"></a><span class="lineno"> 45</span> </div>
|
136 |
-
<div class="line"><a name="l00046"></a><span class="lineno"> 46</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
|
137 |
-
<div class="line"><a name="l00047"></a><span class="lineno"> 47</span> <span class="comment">// Removal of auto as a storage-class specifier - GCC 4.4</span></div>
|
138 |
-
<div class="line"><a name="l00048"></a><span class="lineno"> 48</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm</span></div>
|
139 |
-
<div class="line"><a name="l00049"></a><span class="lineno"> 49</span> </div>
|
140 |
-
<div class="line"><a name="l00050"></a><span class="lineno"> 50</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
|
141 |
-
<div class="line"><a name="l00051"></a><span class="lineno"> 51</span> <span class="comment">// New function declarator syntax - GCC 4.4</span></div>
|
142 |
-
<div class="line"><a name="l00052"></a><span class="lineno"> 52</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm</span></div>
|
143 |
-
<div class="line"><a name="l00053"></a><span class="lineno"> 53</span> </div>
|
144 |
-
<div class="line"><a name="l00054"></a><span class="lineno"> 54</span> <span class="comment">// #define GLM_CXX11_LAMBDAS</span></div>
|
145 |
-
<div class="line"><a name="l00055"></a><span class="lineno"> 55</span> <span class="comment">// New wording for C++0x lambdas - GCC 4.5</span></div>
|
146 |
-
<div class="line"><a name="l00056"></a><span class="lineno"> 56</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf</span></div>
|
147 |
-
<div class="line"><a name="l00057"></a><span class="lineno"> 57</span> </div>
|
148 |
-
<div class="line"><a name="l00058"></a><span class="lineno"> 58</span> <span class="comment">// #define GLM_CXX11_DECLTYPE</span></div>
|
149 |
-
<div class="line"><a name="l00059"></a><span class="lineno"> 59</span> <span class="comment">// Declared type of an expression - GCC 4.3</span></div>
|
150 |
-
<div class="line"><a name="l00060"></a><span class="lineno"> 60</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf</span></div>
|
151 |
-
<div class="line"><a name="l00061"></a><span class="lineno"> 61</span> </div>
|
152 |
-
<div class="line"><a name="l00062"></a><span class="lineno"> 62</span> <span class="comment">//</span></div>
|
153 |
-
<div class="line"><a name="l00063"></a><span class="lineno"> 63</span> <span class="comment">// Right angle brackets - GCC 4.3</span></div>
|
154 |
-
<div class="line"><a name="l00064"></a><span class="lineno"> 64</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html</span></div>
|
155 |
-
<div class="line"><a name="l00065"></a><span class="lineno"> 65</span> </div>
|
156 |
-
<div class="line"><a name="l00066"></a><span class="lineno"> 66</span> <span class="comment">//</span></div>
|
157 |
-
<div class="line"><a name="l00067"></a><span class="lineno"> 67</span> <span class="comment">// Default template arguments for function templates DR226 GCC 4.3</span></div>
|
158 |
-
<div class="line"><a name="l00068"></a><span class="lineno"> 68</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226</span></div>
|
159 |
-
<div class="line"><a name="l00069"></a><span class="lineno"> 69</span> </div>
|
160 |
-
<div class="line"><a name="l00070"></a><span class="lineno"> 70</span> <span class="comment">//</span></div>
|
161 |
-
<div class="line"><a name="l00071"></a><span class="lineno"> 71</span> <span class="comment">// Solving the SFINAE problem for expressions DR339 GCC 4.4</span></div>
|
162 |
-
<div class="line"><a name="l00072"></a><span class="lineno"> 72</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html</span></div>
|
163 |
-
<div class="line"><a name="l00073"></a><span class="lineno"> 73</span> </div>
|
164 |
-
<div class="line"><a name="l00074"></a><span class="lineno"> 74</span> <span class="comment">// #define GLM_CXX11_ALIAS_TEMPLATE</span></div>
|
165 |
-
<div class="line"><a name="l00075"></a><span class="lineno"> 75</span> <span class="comment">// Template aliases N2258 GCC 4.7</span></div>
|
166 |
-
<div class="line"><a name="l00076"></a><span class="lineno"> 76</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf</span></div>
|
167 |
-
<div class="line"><a name="l00077"></a><span class="lineno"> 77</span> </div>
|
168 |
-
<div class="line"><a name="l00078"></a><span class="lineno"> 78</span> <span class="comment">//</span></div>
|
169 |
-
<div class="line"><a name="l00079"></a><span class="lineno"> 79</span> <span class="comment">// Extern templates N1987 Yes</span></div>
|
170 |
-
<div class="line"><a name="l00080"></a><span class="lineno"> 80</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm</span></div>
|
171 |
-
<div class="line"><a name="l00081"></a><span class="lineno"> 81</span> </div>
|
172 |
-
<div class="line"><a name="l00082"></a><span class="lineno"> 82</span> <span class="comment">// #define GLM_CXX11_NULLPTR</span></div>
|
173 |
-
<div class="line"><a name="l00083"></a><span class="lineno"> 83</span> <span class="comment">// Null pointer constant N2431 GCC 4.6</span></div>
|
174 |
-
<div class="line"><a name="l00084"></a><span class="lineno"> 84</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf</span></div>
|
175 |
-
<div class="line"><a name="l00085"></a><span class="lineno"> 85</span> </div>
|
176 |
-
<div class="line"><a name="l00086"></a><span class="lineno"> 86</span> <span class="comment">// #define GLM_CXX11_STRONG_ENUMS</span></div>
|
177 |
-
<div class="line"><a name="l00087"></a><span class="lineno"> 87</span> <span class="comment">// Strongly-typed enums N2347 GCC 4.4</span></div>
|
178 |
-
<div class="line"><a name="l00088"></a><span class="lineno"> 88</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf</span></div>
|
179 |
-
<div class="line"><a name="l00089"></a><span class="lineno"> 89</span> </div>
|
180 |
-
<div class="line"><a name="l00090"></a><span class="lineno"> 90</span> <span class="comment">//</span></div>
|
181 |
-
<div class="line"><a name="l00091"></a><span class="lineno"> 91</span> <span class="comment">// Forward declarations for enums N2764 GCC 4.6</span></div>
|
182 |
-
<div class="line"><a name="l00092"></a><span class="lineno"> 92</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf</span></div>
|
183 |
-
<div class="line"><a name="l00093"></a><span class="lineno"> 93</span> </div>
|
184 |
-
<div class="line"><a name="l00094"></a><span class="lineno"> 94</span> <span class="comment">//</span></div>
|
185 |
-
<div class="line"><a name="l00095"></a><span class="lineno"> 95</span> <span class="comment">// Generalized attributes N2761 GCC 4.8</span></div>
|
186 |
-
<div class="line"><a name="l00096"></a><span class="lineno"> 96</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf</span></div>
|
187 |
-
<div class="line"><a name="l00097"></a><span class="lineno"> 97</span> </div>
|
188 |
-
<div class="line"><a name="l00098"></a><span class="lineno"> 98</span> <span class="comment">//</span></div>
|
189 |
-
<div class="line"><a name="l00099"></a><span class="lineno"> 99</span> <span class="comment">// Generalized constant expressions N2235 GCC 4.6</span></div>
|
190 |
-
<div class="line"><a name="l00100"></a><span class="lineno"> 100</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf</span></div>
|
191 |
-
<div class="line"><a name="l00101"></a><span class="lineno"> 101</span> </div>
|
192 |
-
<div class="line"><a name="l00102"></a><span class="lineno"> 102</span> <span class="comment">//</span></div>
|
193 |
-
<div class="line"><a name="l00103"></a><span class="lineno"> 103</span> <span class="comment">// Alignment support N2341 GCC 4.8</span></div>
|
194 |
-
<div class="line"><a name="l00104"></a><span class="lineno"> 104</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf</span></div>
|
195 |
-
<div class="line"><a name="l00105"></a><span class="lineno"> 105</span> </div>
|
196 |
-
<div class="line"><a name="l00106"></a><span class="lineno"> 106</span> <span class="comment">// #define GLM_CXX11_DELEGATING_CONSTRUCTORS</span></div>
|
197 |
-
<div class="line"><a name="l00107"></a><span class="lineno"> 107</span> <span class="comment">// Delegating constructors N1986 GCC 4.7</span></div>
|
198 |
-
<div class="line"><a name="l00108"></a><span class="lineno"> 108</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf</span></div>
|
199 |
-
<div class="line"><a name="l00109"></a><span class="lineno"> 109</span> </div>
|
200 |
-
<div class="line"><a name="l00110"></a><span class="lineno"> 110</span> <span class="comment">//</span></div>
|
201 |
-
<div class="line"><a name="l00111"></a><span class="lineno"> 111</span> <span class="comment">// Inheriting constructors N2540 GCC 4.8</span></div>
|
202 |
-
<div class="line"><a name="l00112"></a><span class="lineno"> 112</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm</span></div>
|
203 |
-
<div class="line"><a name="l00113"></a><span class="lineno"> 113</span> </div>
|
204 |
-
<div class="line"><a name="l00114"></a><span class="lineno"> 114</span> <span class="comment">// #define GLM_CXX11_EXPLICIT_CONVERSIONS</span></div>
|
205 |
-
<div class="line"><a name="l00115"></a><span class="lineno"> 115</span> <span class="comment">// Explicit conversion operators N2437 GCC 4.5</span></div>
|
206 |
-
<div class="line"><a name="l00116"></a><span class="lineno"> 116</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf</span></div>
|
207 |
-
<div class="line"><a name="l00117"></a><span class="lineno"> 117</span> </div>
|
208 |
-
<div class="line"><a name="l00118"></a><span class="lineno"> 118</span> <span class="comment">//</span></div>
|
209 |
-
<div class="line"><a name="l00119"></a><span class="lineno"> 119</span> <span class="comment">// New character types N2249 GCC 4.4</span></div>
|
210 |
-
<div class="line"><a name="l00120"></a><span class="lineno"> 120</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html</span></div>
|
211 |
-
<div class="line"><a name="l00121"></a><span class="lineno"> 121</span> </div>
|
212 |
-
<div class="line"><a name="l00122"></a><span class="lineno"> 122</span> <span class="comment">//</span></div>
|
213 |
-
<div class="line"><a name="l00123"></a><span class="lineno"> 123</span> <span class="comment">// Unicode string literals N2442 GCC 4.5</span></div>
|
214 |
-
<div class="line"><a name="l00124"></a><span class="lineno"> 124</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm</span></div>
|
215 |
-
<div class="line"><a name="l00125"></a><span class="lineno"> 125</span> </div>
|
216 |
-
<div class="line"><a name="l00126"></a><span class="lineno"> 126</span> <span class="comment">//</span></div>
|
217 |
-
<div class="line"><a name="l00127"></a><span class="lineno"> 127</span> <span class="comment">// Raw string literals N2442 GCC 4.5</span></div>
|
218 |
-
<div class="line"><a name="l00128"></a><span class="lineno"> 128</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm</span></div>
|
219 |
-
<div class="line"><a name="l00129"></a><span class="lineno"> 129</span> </div>
|
220 |
-
<div class="line"><a name="l00130"></a><span class="lineno"> 130</span> <span class="comment">//</span></div>
|
221 |
-
<div class="line"><a name="l00131"></a><span class="lineno"> 131</span> <span class="comment">// Universal character name literals N2170 GCC 4.5</span></div>
|
222 |
-
<div class="line"><a name="l00132"></a><span class="lineno"> 132</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html</span></div>
|
223 |
-
<div class="line"><a name="l00133"></a><span class="lineno"> 133</span> </div>
|
224 |
-
<div class="line"><a name="l00134"></a><span class="lineno"> 134</span> <span class="comment">// #define GLM_CXX11_USER_LITERALS</span></div>
|
225 |
-
<div class="line"><a name="l00135"></a><span class="lineno"> 135</span> <span class="comment">// User-defined literals N2765 GCC 4.7</span></div>
|
226 |
-
<div class="line"><a name="l00136"></a><span class="lineno"> 136</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf</span></div>
|
227 |
-
<div class="line"><a name="l00137"></a><span class="lineno"> 137</span> </div>
|
228 |
-
<div class="line"><a name="l00138"></a><span class="lineno"> 138</span> <span class="comment">//</span></div>
|
229 |
-
<div class="line"><a name="l00139"></a><span class="lineno"> 139</span> <span class="comment">// Standard Layout Types N2342 GCC 4.5</span></div>
|
230 |
-
<div class="line"><a name="l00140"></a><span class="lineno"> 140</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm</span></div>
|
231 |
-
<div class="line"><a name="l00141"></a><span class="lineno"> 141</span> </div>
|
232 |
-
<div class="line"><a name="l00142"></a><span class="lineno"> 142</span> <span class="comment">// #define GLM_CXX11_DEFAULTED_FUNCTIONS</span></div>
|
233 |
-
<div class="line"><a name="l00143"></a><span class="lineno"> 143</span> <span class="comment">// #define GLM_CXX11_DELETED_FUNCTIONS</span></div>
|
234 |
-
<div class="line"><a name="l00144"></a><span class="lineno"> 144</span> <span class="comment">// Defaulted and deleted functions N2346 GCC 4.4</span></div>
|
235 |
-
<div class="line"><a name="l00145"></a><span class="lineno"> 145</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm</span></div>
|
236 |
-
<div class="line"><a name="l00146"></a><span class="lineno"> 146</span> </div>
|
237 |
-
<div class="line"><a name="l00147"></a><span class="lineno"> 147</span> <span class="comment">//</span></div>
|
238 |
-
<div class="line"><a name="l00148"></a><span class="lineno"> 148</span> <span class="comment">// Extended friend declarations N1791 GCC 4.7</span></div>
|
239 |
-
<div class="line"><a name="l00149"></a><span class="lineno"> 149</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf</span></div>
|
240 |
-
<div class="line"><a name="l00150"></a><span class="lineno"> 150</span> </div>
|
241 |
-
<div class="line"><a name="l00151"></a><span class="lineno"> 151</span> <span class="comment">//</span></div>
|
242 |
-
<div class="line"><a name="l00152"></a><span class="lineno"> 152</span> <span class="comment">// Extending sizeof N2253 GCC 4.4</span></div>
|
243 |
-
<div class="line"><a name="l00153"></a><span class="lineno"> 153</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html</span></div>
|
244 |
-
<div class="line"><a name="l00154"></a><span class="lineno"> 154</span> </div>
|
245 |
-
<div class="line"><a name="l00155"></a><span class="lineno"> 155</span> <span class="comment">// #define GLM_CXX11_INLINE_NAMESPACES</span></div>
|
246 |
-
<div class="line"><a name="l00156"></a><span class="lineno"> 156</span> <span class="comment">// Inline namespaces N2535 GCC 4.4</span></div>
|
247 |
-
<div class="line"><a name="l00157"></a><span class="lineno"> 157</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm</span></div>
|
248 |
-
<div class="line"><a name="l00158"></a><span class="lineno"> 158</span> </div>
|
249 |
-
<div class="line"><a name="l00159"></a><span class="lineno"> 159</span> <span class="comment">// #define GLM_CXX11_UNRESTRICTED_UNIONS</span></div>
|
250 |
-
<div class="line"><a name="l00160"></a><span class="lineno"> 160</span> <span class="comment">// Unrestricted unions N2544 GCC 4.6</span></div>
|
251 |
-
<div class="line"><a name="l00161"></a><span class="lineno"> 161</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf</span></div>
|
252 |
-
<div class="line"><a name="l00162"></a><span class="lineno"> 162</span> </div>
|
253 |
-
<div class="line"><a name="l00163"></a><span class="lineno"> 163</span> <span class="comment">// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS</span></div>
|
254 |
-
<div class="line"><a name="l00164"></a><span class="lineno"> 164</span> <span class="comment">// Local and unnamed types as template arguments N2657 GCC 4.5</span></div>
|
255 |
-
<div class="line"><a name="l00165"></a><span class="lineno"> 165</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm</span></div>
|
256 |
-
<div class="line"><a name="l00166"></a><span class="lineno"> 166</span> </div>
|
257 |
-
<div class="line"><a name="l00167"></a><span class="lineno"> 167</span> <span class="comment">// #define GLM_CXX11_RANGE_FOR</span></div>
|
258 |
-
<div class="line"><a name="l00168"></a><span class="lineno"> 168</span> <span class="comment">// Range-based for N2930 GCC 4.6</span></div>
|
259 |
-
<div class="line"><a name="l00169"></a><span class="lineno"> 169</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html</span></div>
|
260 |
-
<div class="line"><a name="l00170"></a><span class="lineno"> 170</span> </div>
|
261 |
-
<div class="line"><a name="l00171"></a><span class="lineno"> 171</span> <span class="comment">// #define GLM_CXX11_OVERRIDE_CONTROL</span></div>
|
262 |
-
<div class="line"><a name="l00172"></a><span class="lineno"> 172</span> <span class="comment">// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7</span></div>
|
263 |
-
<div class="line"><a name="l00173"></a><span class="lineno"> 173</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm</span></div>
|
264 |
-
<div class="line"><a name="l00174"></a><span class="lineno"> 174</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm</span></div>
|
265 |
-
<div class="line"><a name="l00175"></a><span class="lineno"> 175</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm</span></div>
|
266 |
-
<div class="line"><a name="l00176"></a><span class="lineno"> 176</span> </div>
|
267 |
-
<div class="line"><a name="l00177"></a><span class="lineno"> 177</span> <span class="comment">//</span></div>
|
268 |
-
<div class="line"><a name="l00178"></a><span class="lineno"> 178</span> <span class="comment">// Minimal support for garbage collection and reachability-based leak detection N2670 No</span></div>
|
269 |
-
<div class="line"><a name="l00179"></a><span class="lineno"> 179</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm</span></div>
|
270 |
-
<div class="line"><a name="l00180"></a><span class="lineno"> 180</span> </div>
|
271 |
-
<div class="line"><a name="l00181"></a><span class="lineno"> 181</span> <span class="comment">// #define GLM_CXX11_NOEXCEPT</span></div>
|
272 |
-
<div class="line"><a name="l00182"></a><span class="lineno"> 182</span> <span class="comment">// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only)</span></div>
|
273 |
-
<div class="line"><a name="l00183"></a><span class="lineno"> 183</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html</span></div>
|
274 |
-
<div class="line"><a name="l00184"></a><span class="lineno"> 184</span> </div>
|
275 |
-
<div class="line"><a name="l00185"></a><span class="lineno"> 185</span> <span class="comment">//</span></div>
|
276 |
-
<div class="line"><a name="l00186"></a><span class="lineno"> 186</span> <span class="comment">// Defining move special member functions N3053 GCC 4.6</span></div>
|
277 |
-
<div class="line"><a name="l00187"></a><span class="lineno"> 187</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html</span></div>
|
278 |
-
<div class="line"><a name="l00188"></a><span class="lineno"> 188</span> </div>
|
279 |
-
<div class="line"><a name="l00189"></a><span class="lineno"> 189</span> <span class="comment">//</span></div>
|
280 |
-
<div class="line"><a name="l00190"></a><span class="lineno"> 190</span> <span class="comment">// Sequence points N2239 Yes</span></div>
|
281 |
-
<div class="line"><a name="l00191"></a><span class="lineno"> 191</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html</span></div>
|
282 |
-
<div class="line"><a name="l00192"></a><span class="lineno"> 192</span> </div>
|
283 |
-
<div class="line"><a name="l00193"></a><span class="lineno"> 193</span> <span class="comment">//</span></div>
|
284 |
-
<div class="line"><a name="l00194"></a><span class="lineno"> 194</span> <span class="comment">// Atomic operations N2427 GCC 4.4</span></div>
|
285 |
-
<div class="line"><a name="l00195"></a><span class="lineno"> 195</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html</span></div>
|
286 |
-
<div class="line"><a name="l00196"></a><span class="lineno"> 196</span> </div>
|
287 |
-
<div class="line"><a name="l00197"></a><span class="lineno"> 197</span> <span class="comment">//</span></div>
|
288 |
-
<div class="line"><a name="l00198"></a><span class="lineno"> 198</span> <span class="comment">// Strong Compare and Exchange N2748 GCC 4.5</span></div>
|
289 |
-
<div class="line"><a name="l00199"></a><span class="lineno"> 199</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html</span></div>
|
290 |
-
<div class="line"><a name="l00200"></a><span class="lineno"> 200</span> </div>
|
291 |
-
<div class="line"><a name="l00201"></a><span class="lineno"> 201</span> <span class="comment">//</span></div>
|
292 |
-
<div class="line"><a name="l00202"></a><span class="lineno"> 202</span> <span class="comment">// Bidirectional Fences N2752 GCC 4.8</span></div>
|
293 |
-
<div class="line"><a name="l00203"></a><span class="lineno"> 203</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm</span></div>
|
294 |
-
<div class="line"><a name="l00204"></a><span class="lineno"> 204</span> </div>
|
295 |
-
<div class="line"><a name="l00205"></a><span class="lineno"> 205</span> <span class="comment">//</span></div>
|
296 |
-
<div class="line"><a name="l00206"></a><span class="lineno"> 206</span> <span class="comment">// Memory model N2429 GCC 4.8</span></div>
|
297 |
-
<div class="line"><a name="l00207"></a><span class="lineno"> 207</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm</span></div>
|
298 |
-
<div class="line"><a name="l00208"></a><span class="lineno"> 208</span> </div>
|
299 |
-
<div class="line"><a name="l00209"></a><span class="lineno"> 209</span> <span class="comment">//</span></div>
|
300 |
-
<div class="line"><a name="l00210"></a><span class="lineno"> 210</span> <span class="comment">// Data-dependency ordering: atomics and memory model N2664 GCC 4.4</span></div>
|
301 |
-
<div class="line"><a name="l00211"></a><span class="lineno"> 211</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm</span></div>
|
302 |
-
<div class="line"><a name="l00212"></a><span class="lineno"> 212</span> </div>
|
303 |
-
<div class="line"><a name="l00213"></a><span class="lineno"> 213</span> <span class="comment">//</span></div>
|
304 |
-
<div class="line"><a name="l00214"></a><span class="lineno"> 214</span> <span class="comment">// Propagating exceptions N2179 GCC 4.4</span></div>
|
305 |
-
<div class="line"><a name="l00215"></a><span class="lineno"> 215</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html</span></div>
|
306 |
-
<div class="line"><a name="l00216"></a><span class="lineno"> 216</span> </div>
|
307 |
-
<div class="line"><a name="l00217"></a><span class="lineno"> 217</span> <span class="comment">//</span></div>
|
308 |
-
<div class="line"><a name="l00218"></a><span class="lineno"> 218</span> <span class="comment">// Abandoning a process and at_quick_exit N2440 GCC 4.8</span></div>
|
309 |
-
<div class="line"><a name="l00219"></a><span class="lineno"> 219</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm</span></div>
|
310 |
-
<div class="line"><a name="l00220"></a><span class="lineno"> 220</span> </div>
|
311 |
-
<div class="line"><a name="l00221"></a><span class="lineno"> 221</span> <span class="comment">//</span></div>
|
312 |
-
<div class="line"><a name="l00222"></a><span class="lineno"> 222</span> <span class="comment">// Allow atomics use in signal handlers N2547 Yes</span></div>
|
313 |
-
<div class="line"><a name="l00223"></a><span class="lineno"> 223</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm</span></div>
|
314 |
-
<div class="line"><a name="l00224"></a><span class="lineno"> 224</span> </div>
|
315 |
-
<div class="line"><a name="l00225"></a><span class="lineno"> 225</span> <span class="comment">//</span></div>
|
316 |
-
<div class="line"><a name="l00226"></a><span class="lineno"> 226</span> <span class="comment">// Thread-local storage N2659 GCC 4.8</span></div>
|
317 |
-
<div class="line"><a name="l00227"></a><span class="lineno"> 227</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm</span></div>
|
318 |
-
<div class="line"><a name="l00228"></a><span class="lineno"> 228</span> </div>
|
319 |
-
<div class="line"><a name="l00229"></a><span class="lineno"> 229</span> <span class="comment">//</span></div>
|
320 |
-
<div class="line"><a name="l00230"></a><span class="lineno"> 230</span> <span class="comment">// Dynamic initialization and destruction with concurrency N2660 GCC 4.3</span></div>
|
321 |
-
<div class="line"><a name="l00231"></a><span class="lineno"> 231</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm</span></div>
|
322 |
-
<div class="line"><a name="l00232"></a><span class="lineno"> 232</span> </div>
|
323 |
-
<div class="line"><a name="l00233"></a><span class="lineno"> 233</span> <span class="comment">//</span></div>
|
324 |
-
<div class="line"><a name="l00234"></a><span class="lineno"> 234</span> <span class="comment">// __func__ predefined identifier N2340 GCC 4.3</span></div>
|
325 |
-
<div class="line"><a name="l00235"></a><span class="lineno"> 235</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm</span></div>
|
326 |
-
<div class="line"><a name="l00236"></a><span class="lineno"> 236</span> </div>
|
327 |
-
<div class="line"><a name="l00237"></a><span class="lineno"> 237</span> <span class="comment">//</span></div>
|
328 |
-
<div class="line"><a name="l00238"></a><span class="lineno"> 238</span> <span class="comment">// C99 preprocessor N1653 GCC 4.3</span></div>
|
329 |
-
<div class="line"><a name="l00239"></a><span class="lineno"> 239</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm</span></div>
|
330 |
-
<div class="line"><a name="l00240"></a><span class="lineno"> 240</span> </div>
|
331 |
-
<div class="line"><a name="l00241"></a><span class="lineno"> 241</span> <span class="comment">//</span></div>
|
332 |
-
<div class="line"><a name="l00242"></a><span class="lineno"> 242</span> <span class="comment">// long long N1811 GCC 4.3</span></div>
|
333 |
-
<div class="line"><a name="l00243"></a><span class="lineno"> 243</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf</span></div>
|
334 |
-
<div class="line"><a name="l00244"></a><span class="lineno"> 244</span> </div>
|
335 |
-
<div class="line"><a name="l00245"></a><span class="lineno"> 245</span> <span class="comment">//</span></div>
|
336 |
-
<div class="line"><a name="l00246"></a><span class="lineno"> 246</span> <span class="comment">// Extended integral types N1988 Yes</span></div>
|
337 |
-
<div class="line"><a name="l00247"></a><span class="lineno"> 247</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf</span></div>
|
338 |
-
<div class="line"><a name="l00248"></a><span class="lineno"> 248</span> </div>
|
339 |
-
<div class="line"><a name="l00249"></a><span class="lineno"> 249</span> <span class="preprocessor">#if(GLM_COMPILER & GLM_COMPILER_GCC)</span></div>
|
340 |
-
<div class="line"><a name="l00250"></a><span class="lineno"> 250</span> </div>
|
341 |
-
<div class="line"><a name="l00251"></a><span class="lineno"> 251</span> <span class="preprocessor"># define GLM_CXX11_STATIC_ASSERT</span></div>
|
342 |
-
<div class="line"><a name="l00252"></a><span class="lineno"> 252</span> </div>
|
343 |
-
<div class="line"><a name="l00253"></a><span class="lineno"> 253</span> <span class="preprocessor">#elif(GLM_COMPILER & GLM_COMPILER_CLANG)</span></div>
|
344 |
-
<div class="line"><a name="l00254"></a><span class="lineno"> 254</span> <span class="preprocessor"># if(__has_feature(cxx_exceptions))</span></div>
|
345 |
-
<div class="line"><a name="l00255"></a><span class="lineno"> 255</span> <span class="preprocessor"># define GLM_CXX98_EXCEPTIONS</span></div>
|
346 |
-
<div class="line"><a name="l00256"></a><span class="lineno"> 256</span> <span class="preprocessor"># endif</span></div>
|
347 |
-
<div class="line"><a name="l00257"></a><span class="lineno"> 257</span> </div>
|
348 |
-
<div class="line"><a name="l00258"></a><span class="lineno"> 258</span> <span class="preprocessor"># if(__has_feature(cxx_rtti))</span></div>
|
349 |
-
<div class="line"><a name="l00259"></a><span class="lineno"> 259</span> <span class="preprocessor"># define GLM_CXX98_RTTI</span></div>
|
350 |
-
<div class="line"><a name="l00260"></a><span class="lineno"> 260</span> <span class="preprocessor"># endif</span></div>
|
351 |
-
<div class="line"><a name="l00261"></a><span class="lineno"> 261</span> </div>
|
352 |
-
<div class="line"><a name="l00262"></a><span class="lineno"> 262</span> <span class="preprocessor"># if(__has_feature(cxx_access_control_sfinae))</span></div>
|
353 |
-
<div class="line"><a name="l00263"></a><span class="lineno"> 263</span> <span class="preprocessor"># define GLM_CXX11_ACCESS_CONTROL_SFINAE</span></div>
|
354 |
-
<div class="line"><a name="l00264"></a><span class="lineno"> 264</span> <span class="preprocessor"># endif</span></div>
|
355 |
-
<div class="line"><a name="l00265"></a><span class="lineno"> 265</span> </div>
|
356 |
-
<div class="line"><a name="l00266"></a><span class="lineno"> 266</span> <span class="preprocessor"># if(__has_feature(cxx_alias_templates))</span></div>
|
357 |
-
<div class="line"><a name="l00267"></a><span class="lineno"> 267</span> <span class="preprocessor"># define GLM_CXX11_ALIAS_TEMPLATE</span></div>
|
358 |
-
<div class="line"><a name="l00268"></a><span class="lineno"> 268</span> <span class="preprocessor"># endif</span></div>
|
359 |
-
<div class="line"><a name="l00269"></a><span class="lineno"> 269</span> </div>
|
360 |
-
<div class="line"><a name="l00270"></a><span class="lineno"> 270</span> <span class="preprocessor"># if(__has_feature(cxx_alignas))</span></div>
|
361 |
-
<div class="line"><a name="l00271"></a><span class="lineno"> 271</span> <span class="preprocessor"># define GLM_CXX11_ALIGNAS</span></div>
|
362 |
-
<div class="line"><a name="l00272"></a><span class="lineno"> 272</span> <span class="preprocessor"># endif</span></div>
|
363 |
-
<div class="line"><a name="l00273"></a><span class="lineno"> 273</span> </div>
|
364 |
-
<div class="line"><a name="l00274"></a><span class="lineno"> 274</span> <span class="preprocessor"># if(__has_feature(cxx_attributes))</span></div>
|
365 |
-
<div class="line"><a name="l00275"></a><span class="lineno"> 275</span> <span class="preprocessor"># define GLM_CXX11_ATTRIBUTES</span></div>
|
366 |
-
<div class="line"><a name="l00276"></a><span class="lineno"> 276</span> <span class="preprocessor"># endif</span></div>
|
367 |
-
<div class="line"><a name="l00277"></a><span class="lineno"> 277</span> </div>
|
368 |
-
<div class="line"><a name="l00278"></a><span class="lineno"> 278</span> <span class="preprocessor"># if(__has_feature(cxx_constexpr))</span></div>
|
369 |
-
<div class="line"><a name="l00279"></a><span class="lineno"> 279</span> <span class="preprocessor"># define GLM_CXX11_CONSTEXPR</span></div>
|
370 |
-
<div class="line"><a name="l00280"></a><span class="lineno"> 280</span> <span class="preprocessor"># endif</span></div>
|
371 |
-
<div class="line"><a name="l00281"></a><span class="lineno"> 281</span> </div>
|
372 |
-
<div class="line"><a name="l00282"></a><span class="lineno"> 282</span> <span class="preprocessor"># if(__has_feature(cxx_decltype))</span></div>
|
373 |
-
<div class="line"><a name="l00283"></a><span class="lineno"> 283</span> <span class="preprocessor"># define GLM_CXX11_DECLTYPE</span></div>
|
374 |
-
<div class="line"><a name="l00284"></a><span class="lineno"> 284</span> <span class="preprocessor"># endif</span></div>
|
375 |
-
<div class="line"><a name="l00285"></a><span class="lineno"> 285</span> </div>
|
376 |
-
<div class="line"><a name="l00286"></a><span class="lineno"> 286</span> <span class="preprocessor"># if(__has_feature(cxx_default_function_template_args))</span></div>
|
377 |
-
<div class="line"><a name="l00287"></a><span class="lineno"> 287</span> <span class="preprocessor"># define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS</span></div>
|
378 |
-
<div class="line"><a name="l00288"></a><span class="lineno"> 288</span> <span class="preprocessor"># endif</span></div>
|
379 |
-
<div class="line"><a name="l00289"></a><span class="lineno"> 289</span> </div>
|
380 |
-
<div class="line"><a name="l00290"></a><span class="lineno"> 290</span> <span class="preprocessor"># if(__has_feature(cxx_defaulted_functions))</span></div>
|
381 |
-
<div class="line"><a name="l00291"></a><span class="lineno"> 291</span> <span class="preprocessor"># define GLM_CXX11_DEFAULTED_FUNCTIONS</span></div>
|
382 |
-
<div class="line"><a name="l00292"></a><span class="lineno"> 292</span> <span class="preprocessor"># endif</span></div>
|
383 |
-
<div class="line"><a name="l00293"></a><span class="lineno"> 293</span> </div>
|
384 |
-
<div class="line"><a name="l00294"></a><span class="lineno"> 294</span> <span class="preprocessor"># if(__has_feature(cxx_delegating_constructors))</span></div>
|
385 |
-
<div class="line"><a name="l00295"></a><span class="lineno"> 295</span> <span class="preprocessor"># define GLM_CXX11_DELEGATING_CONSTRUCTORS</span></div>
|
386 |
-
<div class="line"><a name="l00296"></a><span class="lineno"> 296</span> <span class="preprocessor"># endif</span></div>
|
387 |
-
<div class="line"><a name="l00297"></a><span class="lineno"> 297</span> </div>
|
388 |
-
<div class="line"><a name="l00298"></a><span class="lineno"> 298</span> <span class="preprocessor"># if(__has_feature(cxx_deleted_functions))</span></div>
|
389 |
-
<div class="line"><a name="l00299"></a><span class="lineno"> 299</span> <span class="preprocessor"># define GLM_CXX11_DELETED_FUNCTIONS</span></div>
|
390 |
-
<div class="line"><a name="l00300"></a><span class="lineno"> 300</span> <span class="preprocessor"># endif</span></div>
|
391 |
-
<div class="line"><a name="l00301"></a><span class="lineno"> 301</span> </div>
|
392 |
-
<div class="line"><a name="l00302"></a><span class="lineno"> 302</span> <span class="preprocessor"># if(__has_feature(cxx_explicit_conversions))</span></div>
|
393 |
-
<div class="line"><a name="l00303"></a><span class="lineno"> 303</span> <span class="preprocessor"># define GLM_CXX11_EXPLICIT_CONVERSIONS</span></div>
|
394 |
-
<div class="line"><a name="l00304"></a><span class="lineno"> 304</span> <span class="preprocessor"># endif</span></div>
|
395 |
-
<div class="line"><a name="l00305"></a><span class="lineno"> 305</span> </div>
|
396 |
-
<div class="line"><a name="l00306"></a><span class="lineno"> 306</span> <span class="preprocessor"># if(__has_feature(cxx_generalized_initializers))</span></div>
|
397 |
-
<div class="line"><a name="l00307"></a><span class="lineno"> 307</span> <span class="preprocessor"># define GLM_CXX11_GENERALIZED_INITIALIZERS</span></div>
|
398 |
-
<div class="line"><a name="l00308"></a><span class="lineno"> 308</span> <span class="preprocessor"># endif</span></div>
|
399 |
-
<div class="line"><a name="l00309"></a><span class="lineno"> 309</span> </div>
|
400 |
-
<div class="line"><a name="l00310"></a><span class="lineno"> 310</span> <span class="preprocessor"># if(__has_feature(cxx_implicit_moves))</span></div>
|
401 |
-
<div class="line"><a name="l00311"></a><span class="lineno"> 311</span> <span class="preprocessor"># define GLM_CXX11_IMPLICIT_MOVES</span></div>
|
402 |
-
<div class="line"><a name="l00312"></a><span class="lineno"> 312</span> <span class="preprocessor"># endif</span></div>
|
403 |
-
<div class="line"><a name="l00313"></a><span class="lineno"> 313</span> </div>
|
404 |
-
<div class="line"><a name="l00314"></a><span class="lineno"> 314</span> <span class="preprocessor"># if(__has_feature(cxx_inheriting_constructors))</span></div>
|
405 |
-
<div class="line"><a name="l00315"></a><span class="lineno"> 315</span> <span class="preprocessor"># define GLM_CXX11_INHERITING_CONSTRUCTORS</span></div>
|
406 |
-
<div class="line"><a name="l00316"></a><span class="lineno"> 316</span> <span class="preprocessor"># endif</span></div>
|
407 |
-
<div class="line"><a name="l00317"></a><span class="lineno"> 317</span> </div>
|
408 |
-
<div class="line"><a name="l00318"></a><span class="lineno"> 318</span> <span class="preprocessor"># if(__has_feature(cxx_inline_namespaces))</span></div>
|
409 |
-
<div class="line"><a name="l00319"></a><span class="lineno"> 319</span> <span class="preprocessor"># define GLM_CXX11_INLINE_NAMESPACES</span></div>
|
410 |
-
<div class="line"><a name="l00320"></a><span class="lineno"> 320</span> <span class="preprocessor"># endif</span></div>
|
411 |
-
<div class="line"><a name="l00321"></a><span class="lineno"> 321</span> </div>
|
412 |
-
<div class="line"><a name="l00322"></a><span class="lineno"> 322</span> <span class="preprocessor"># if(__has_feature(cxx_lambdas))</span></div>
|
413 |
-
<div class="line"><a name="l00323"></a><span class="lineno"> 323</span> <span class="preprocessor"># define GLM_CXX11_LAMBDAS</span></div>
|
414 |
-
<div class="line"><a name="l00324"></a><span class="lineno"> 324</span> <span class="preprocessor"># endif</span></div>
|
415 |
-
<div class="line"><a name="l00325"></a><span class="lineno"> 325</span> </div>
|
416 |
-
<div class="line"><a name="l00326"></a><span class="lineno"> 326</span> <span class="preprocessor"># if(__has_feature(cxx_local_type_template_args))</span></div>
|
417 |
-
<div class="line"><a name="l00327"></a><span class="lineno"> 327</span> <span class="preprocessor"># define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS</span></div>
|
418 |
-
<div class="line"><a name="l00328"></a><span class="lineno"> 328</span> <span class="preprocessor"># endif</span></div>
|
419 |
-
<div class="line"><a name="l00329"></a><span class="lineno"> 329</span> </div>
|
420 |
-
<div class="line"><a name="l00330"></a><span class="lineno"> 330</span> <span class="preprocessor"># if(__has_feature(cxx_noexcept))</span></div>
|
421 |
-
<div class="line"><a name="l00331"></a><span class="lineno"> 331</span> <span class="preprocessor"># define GLM_CXX11_NOEXCEPT</span></div>
|
422 |
-
<div class="line"><a name="l00332"></a><span class="lineno"> 332</span> <span class="preprocessor"># endif</span></div>
|
423 |
-
<div class="line"><a name="l00333"></a><span class="lineno"> 333</span> </div>
|
424 |
-
<div class="line"><a name="l00334"></a><span class="lineno"> 334</span> <span class="preprocessor"># if(__has_feature(cxx_nonstatic_member_init))</span></div>
|
425 |
-
<div class="line"><a name="l00335"></a><span class="lineno"> 335</span> <span class="preprocessor"># define GLM_CXX11_NONSTATIC_MEMBER_INIT</span></div>
|
426 |
-
<div class="line"><a name="l00336"></a><span class="lineno"> 336</span> <span class="preprocessor"># endif</span></div>
|
427 |
-
<div class="line"><a name="l00337"></a><span class="lineno"> 337</span> </div>
|
428 |
-
<div class="line"><a name="l00338"></a><span class="lineno"> 338</span> <span class="preprocessor"># if(__has_feature(cxx_nullptr))</span></div>
|
429 |
-
<div class="line"><a name="l00339"></a><span class="lineno"> 339</span> <span class="preprocessor"># define GLM_CXX11_NULLPTR</span></div>
|
430 |
-
<div class="line"><a name="l00340"></a><span class="lineno"> 340</span> <span class="preprocessor"># endif</span></div>
|
431 |
-
<div class="line"><a name="l00341"></a><span class="lineno"> 341</span> </div>
|
432 |
-
<div class="line"><a name="l00342"></a><span class="lineno"> 342</span> <span class="preprocessor"># if(__has_feature(cxx_override_control))</span></div>
|
433 |
-
<div class="line"><a name="l00343"></a><span class="lineno"> 343</span> <span class="preprocessor"># define GLM_CXX11_OVERRIDE_CONTROL</span></div>
|
434 |
-
<div class="line"><a name="l00344"></a><span class="lineno"> 344</span> <span class="preprocessor"># endif</span></div>
|
435 |
-
<div class="line"><a name="l00345"></a><span class="lineno"> 345</span> </div>
|
436 |
-
<div class="line"><a name="l00346"></a><span class="lineno"> 346</span> <span class="preprocessor"># if(__has_feature(cxx_reference_qualified_functions))</span></div>
|
437 |
-
<div class="line"><a name="l00347"></a><span class="lineno"> 347</span> <span class="preprocessor"># define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS</span></div>
|
438 |
-
<div class="line"><a name="l00348"></a><span class="lineno"> 348</span> <span class="preprocessor"># endif</span></div>
|
439 |
-
<div class="line"><a name="l00349"></a><span class="lineno"> 349</span> </div>
|
440 |
-
<div class="line"><a name="l00350"></a><span class="lineno"> 350</span> <span class="preprocessor"># if(__has_feature(cxx_range_for))</span></div>
|
441 |
-
<div class="line"><a name="l00351"></a><span class="lineno"> 351</span> <span class="preprocessor"># define GLM_CXX11_RANGE_FOR</span></div>
|
442 |
-
<div class="line"><a name="l00352"></a><span class="lineno"> 352</span> <span class="preprocessor"># endif</span></div>
|
443 |
-
<div class="line"><a name="l00353"></a><span class="lineno"> 353</span> </div>
|
444 |
-
<div class="line"><a name="l00354"></a><span class="lineno"> 354</span> <span class="preprocessor"># if(__has_feature(cxx_raw_string_literals))</span></div>
|
445 |
-
<div class="line"><a name="l00355"></a><span class="lineno"> 355</span> <span class="preprocessor"># define GLM_CXX11_RAW_STRING_LITERALS</span></div>
|
446 |
-
<div class="line"><a name="l00356"></a><span class="lineno"> 356</span> <span class="preprocessor"># endif</span></div>
|
447 |
-
<div class="line"><a name="l00357"></a><span class="lineno"> 357</span> </div>
|
448 |
-
<div class="line"><a name="l00358"></a><span class="lineno"> 358</span> <span class="preprocessor"># if(__has_feature(cxx_rvalue_references))</span></div>
|
449 |
-
<div class="line"><a name="l00359"></a><span class="lineno"> 359</span> <span class="preprocessor"># define GLM_CXX11_RVALUE_REFERENCES</span></div>
|
450 |
-
<div class="line"><a name="l00360"></a><span class="lineno"> 360</span> <span class="preprocessor"># endif</span></div>
|
451 |
-
<div class="line"><a name="l00361"></a><span class="lineno"> 361</span> </div>
|
452 |
-
<div class="line"><a name="l00362"></a><span class="lineno"> 362</span> <span class="preprocessor"># if(__has_feature(cxx_static_assert))</span></div>
|
453 |
-
<div class="line"><a name="l00363"></a><span class="lineno"> 363</span> <span class="preprocessor"># define GLM_CXX11_STATIC_ASSERT</span></div>
|
454 |
-
<div class="line"><a name="l00364"></a><span class="lineno"> 364</span> <span class="preprocessor"># endif</span></div>
|
455 |
-
<div class="line"><a name="l00365"></a><span class="lineno"> 365</span> </div>
|
456 |
-
<div class="line"><a name="l00366"></a><span class="lineno"> 366</span> <span class="preprocessor"># if(__has_feature(cxx_auto_type))</span></div>
|
457 |
-
<div class="line"><a name="l00367"></a><span class="lineno"> 367</span> <span class="preprocessor"># define GLM_CXX11_AUTO_TYPE</span></div>
|
458 |
-
<div class="line"><a name="l00368"></a><span class="lineno"> 368</span> <span class="preprocessor"># endif</span></div>
|
459 |
-
<div class="line"><a name="l00369"></a><span class="lineno"> 369</span> </div>
|
460 |
-
<div class="line"><a name="l00370"></a><span class="lineno"> 370</span> <span class="preprocessor"># if(__has_feature(cxx_strong_enums))</span></div>
|
461 |
-
<div class="line"><a name="l00371"></a><span class="lineno"> 371</span> <span class="preprocessor"># define GLM_CXX11_STRONG_ENUMS</span></div>
|
462 |
-
<div class="line"><a name="l00372"></a><span class="lineno"> 372</span> <span class="preprocessor"># endif</span></div>
|
463 |
-
<div class="line"><a name="l00373"></a><span class="lineno"> 373</span> </div>
|
464 |
-
<div class="line"><a name="l00374"></a><span class="lineno"> 374</span> <span class="preprocessor"># if(__has_feature(cxx_trailing_return))</span></div>
|
465 |
-
<div class="line"><a name="l00375"></a><span class="lineno"> 375</span> <span class="preprocessor"># define GLM_CXX11_TRAILING_RETURN</span></div>
|
466 |
-
<div class="line"><a name="l00376"></a><span class="lineno"> 376</span> <span class="preprocessor"># endif</span></div>
|
467 |
-
<div class="line"><a name="l00377"></a><span class="lineno"> 377</span> </div>
|
468 |
-
<div class="line"><a name="l00378"></a><span class="lineno"> 378</span> <span class="preprocessor"># if(__has_feature(cxx_unicode_literals))</span></div>
|
469 |
-
<div class="line"><a name="l00379"></a><span class="lineno"> 379</span> <span class="preprocessor"># define GLM_CXX11_UNICODE_LITERALS</span></div>
|
470 |
-
<div class="line"><a name="l00380"></a><span class="lineno"> 380</span> <span class="preprocessor"># endif</span></div>
|
471 |
-
<div class="line"><a name="l00381"></a><span class="lineno"> 381</span> </div>
|
472 |
-
<div class="line"><a name="l00382"></a><span class="lineno"> 382</span> <span class="preprocessor"># if(__has_feature(cxx_unrestricted_unions))</span></div>
|
473 |
-
<div class="line"><a name="l00383"></a><span class="lineno"> 383</span> <span class="preprocessor"># define GLM_CXX11_UNRESTRICTED_UNIONS</span></div>
|
474 |
-
<div class="line"><a name="l00384"></a><span class="lineno"> 384</span> <span class="preprocessor"># endif</span></div>
|
475 |
-
<div class="line"><a name="l00385"></a><span class="lineno"> 385</span> </div>
|
476 |
-
<div class="line"><a name="l00386"></a><span class="lineno"> 386</span> <span class="preprocessor"># if(__has_feature(cxx_user_literals))</span></div>
|
477 |
-
<div class="line"><a name="l00387"></a><span class="lineno"> 387</span> <span class="preprocessor"># define GLM_CXX11_USER_LITERALS</span></div>
|
478 |
-
<div class="line"><a name="l00388"></a><span class="lineno"> 388</span> <span class="preprocessor"># endif</span></div>
|
479 |
-
<div class="line"><a name="l00389"></a><span class="lineno"> 389</span> </div>
|
480 |
-
<div class="line"><a name="l00390"></a><span class="lineno"> 390</span> <span class="preprocessor"># if(__has_feature(cxx_variadic_templates))</span></div>
|
481 |
-
<div class="line"><a name="l00391"></a><span class="lineno"> 391</span> <span class="preprocessor"># define GLM_CXX11_VARIADIC_TEMPLATES</span></div>
|
482 |
-
<div class="line"><a name="l00392"></a><span class="lineno"> 392</span> <span class="preprocessor"># endif</span></div>
|
483 |
-
<div class="line"><a name="l00393"></a><span class="lineno"> 393</span> </div>
|
484 |
-
<div class="line"><a name="l00394"></a><span class="lineno"> 394</span> <span class="preprocessor">#endif//(GLM_COMPILER & GLM_COMPILER_CLANG)</span></div>
|
485 |
-
</div><!-- fragment --></div><!-- contents -->
|
486 |
-
<!-- start footer part -->
|
487 |
-
<hr class="footer"/><address class="footer"><small>
|
488 |
-
Generated by  <a href="http://www.doxygen.org/index.html">
|
489 |
-
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
490 |
-
</a> 1.8.10
|
491 |
-
</small></address>
|
492 |
-
</body>
|
493 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/doc/api/a00002_source.html
DELETED
@@ -1,121 +0,0 @@
|
|
1 |
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2 |
-
<html xmlns="http://www.w3.org/1999/xhtml">
|
3 |
-
<head>
|
4 |
-
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
5 |
-
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
6 |
-
<meta name="generator" content="Doxygen 1.8.10"/>
|
7 |
-
<title>0.9.9 API documentation: _fixes.hpp Source File</title>
|
8 |
-
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
9 |
-
<script type="text/javascript" src="jquery.js"></script>
|
10 |
-
<script type="text/javascript" src="dynsections.js"></script>
|
11 |
-
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
12 |
-
<script type="text/javascript" src="search/searchdata.js"></script>
|
13 |
-
<script type="text/javascript" src="search/search.js"></script>
|
14 |
-
<script type="text/javascript">
|
15 |
-
$(document).ready(function() { init_search(); });
|
16 |
-
</script>
|
17 |
-
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
18 |
-
</head>
|
19 |
-
<body>
|
20 |
-
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
21 |
-
<div id="titlearea">
|
22 |
-
<table cellspacing="0" cellpadding="0">
|
23 |
-
<tbody>
|
24 |
-
<tr style="height: 56px;">
|
25 |
-
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
|
26 |
-
<td id="projectalign" style="padding-left: 0.5em;">
|
27 |
-
<div id="projectname">0.9.9 API documentation
|
28 |
-
</div>
|
29 |
-
</td>
|
30 |
-
</tr>
|
31 |
-
</tbody>
|
32 |
-
</table>
|
33 |
-
</div>
|
34 |
-
<!-- end header part -->
|
35 |
-
<!-- Generated by Doxygen 1.8.10 -->
|
36 |
-
<script type="text/javascript">
|
37 |
-
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
38 |
-
</script>
|
39 |
-
<div id="navrow1" class="tabs">
|
40 |
-
<ul class="tablist">
|
41 |
-
<li><a href="index.html"><span>Main Page</span></a></li>
|
42 |
-
<li><a href="modules.html"><span>Modules</span></a></li>
|
43 |
-
<li class="current"><a href="files.html"><span>Files</span></a></li>
|
44 |
-
<li>
|
45 |
-
<div id="MSearchBox" class="MSearchBoxInactive">
|
46 |
-
<span class="left">
|
47 |
-
<img id="MSearchSelect" src="search/mag_sel.png"
|
48 |
-
onmouseover="return searchBox.OnSearchSelectShow()"
|
49 |
-
onmouseout="return searchBox.OnSearchSelectHide()"
|
50 |
-
alt=""/>
|
51 |
-
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
52 |
-
onfocus="searchBox.OnSearchFieldFocus(true)"
|
53 |
-
onblur="searchBox.OnSearchFieldFocus(false)"
|
54 |
-
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
55 |
-
</span><span class="right">
|
56 |
-
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
57 |
-
</span>
|
58 |
-
</div>
|
59 |
-
</li>
|
60 |
-
</ul>
|
61 |
-
</div>
|
62 |
-
<div id="navrow2" class="tabs2">
|
63 |
-
<ul class="tablist">
|
64 |
-
<li><a href="files.html"><span>File List</span></a></li>
|
65 |
-
</ul>
|
66 |
-
</div>
|
67 |
-
<!-- window showing the filter options -->
|
68 |
-
<div id="MSearchSelectWindow"
|
69 |
-
onmouseover="return searchBox.OnSearchSelectShow()"
|
70 |
-
onmouseout="return searchBox.OnSearchSelectHide()"
|
71 |
-
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
72 |
-
</div>
|
73 |
-
|
74 |
-
<!-- iframe showing the search results (closed by default) -->
|
75 |
-
<div id="MSearchResultsWindow">
|
76 |
-
<iframe src="javascript:void(0)" frameborder="0"
|
77 |
-
name="MSearchResults" id="MSearchResults">
|
78 |
-
</iframe>
|
79 |
-
</div>
|
80 |
-
|
81 |
-
<div id="nav-path" class="navpath">
|
82 |
-
<ul>
|
83 |
-
<li class="navelem"><a class="el" href="dir_3a581ba30d25676e4b797b1f96d53b45.html">F:</a></li><li class="navelem"><a class="el" href="dir_9e5fe034a00e89334fd5186c3e7db156.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_d9496f0844b48bc7e53b5af8c99b9ab2.html">Source</a></li><li class="navelem"><a class="el" href="dir_a8bee7be44182a33f3820393ae0b105d.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_44e5e654415abd9ca6fdeaddaff8565e.html">glm</a></li><li class="navelem"><a class="el" href="dir_cef2d71d502cb69a9252bca2297d9549.html">glm</a></li><li class="navelem"><a class="el" href="dir_033f5edb0915b828d2c46ed4804e5503.html">detail</a></li> </ul>
|
84 |
-
</div>
|
85 |
-
</div><!-- top -->
|
86 |
-
<div class="header">
|
87 |
-
<div class="headertitle">
|
88 |
-
<div class="title">_fixes.hpp</div> </div>
|
89 |
-
</div><!--header-->
|
90 |
-
<div class="contents">
|
91 |
-
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> <span class="preprocessor">#include <cmath></span></div>
|
92 |
-
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
|
93 |
-
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="preprocessor">#ifdef max</span></div>
|
94 |
-
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="preprocessor">#undef max</span></div>
|
95 |
-
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="preprocessor">#endif</span></div>
|
96 |
-
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> </div>
|
97 |
-
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="preprocessor">#ifdef min</span></div>
|
98 |
-
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> <span class="preprocessor">#undef min</span></div>
|
99 |
-
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> <span class="preprocessor">#endif</span></div>
|
100 |
-
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> </div>
|
101 |
-
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="preprocessor">#ifdef isnan</span></div>
|
102 |
-
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="preprocessor">#undef isnan</span></div>
|
103 |
-
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> <span class="preprocessor">#endif</span></div>
|
104 |
-
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> </div>
|
105 |
-
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> <span class="preprocessor">#ifdef isinf</span></div>
|
106 |
-
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> <span class="preprocessor">#undef isinf</span></div>
|
107 |
-
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> <span class="preprocessor">#endif</span></div>
|
108 |
-
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> </div>
|
109 |
-
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="preprocessor">#ifdef log2</span></div>
|
110 |
-
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> <span class="preprocessor">#undef log2</span></div>
|
111 |
-
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> <span class="preprocessor">#endif</span></div>
|
112 |
-
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> </div>
|
113 |
-
</div><!-- fragment --></div><!-- contents -->
|
114 |
-
<!-- start footer part -->
|
115 |
-
<hr class="footer"/><address class="footer"><small>
|
116 |
-
Generated by  <a href="http://www.doxygen.org/index.html">
|
117 |
-
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
118 |
-
</a> 1.8.10
|
119 |
-
</small></address>
|
120 |
-
</body>
|
121 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/doc/api/a00003_source.html
DELETED
@@ -1,182 +0,0 @@
|
|
1 |
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2 |
-
<html xmlns="http://www.w3.org/1999/xhtml">
|
3 |
-
<head>
|
4 |
-
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
5 |
-
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
6 |
-
<meta name="generator" content="Doxygen 1.8.10"/>
|
7 |
-
<title>0.9.9 API documentation: _noise.hpp Source File</title>
|
8 |
-
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
9 |
-
<script type="text/javascript" src="jquery.js"></script>
|
10 |
-
<script type="text/javascript" src="dynsections.js"></script>
|
11 |
-
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
12 |
-
<script type="text/javascript" src="search/searchdata.js"></script>
|
13 |
-
<script type="text/javascript" src="search/search.js"></script>
|
14 |
-
<script type="text/javascript">
|
15 |
-
$(document).ready(function() { init_search(); });
|
16 |
-
</script>
|
17 |
-
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
18 |
-
</head>
|
19 |
-
<body>
|
20 |
-
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
21 |
-
<div id="titlearea">
|
22 |
-
<table cellspacing="0" cellpadding="0">
|
23 |
-
<tbody>
|
24 |
-
<tr style="height: 56px;">
|
25 |
-
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
|
26 |
-
<td id="projectalign" style="padding-left: 0.5em;">
|
27 |
-
<div id="projectname">0.9.9 API documentation
|
28 |
-
</div>
|
29 |
-
</td>
|
30 |
-
</tr>
|
31 |
-
</tbody>
|
32 |
-
</table>
|
33 |
-
</div>
|
34 |
-
<!-- end header part -->
|
35 |
-
<!-- Generated by Doxygen 1.8.10 -->
|
36 |
-
<script type="text/javascript">
|
37 |
-
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
38 |
-
</script>
|
39 |
-
<div id="navrow1" class="tabs">
|
40 |
-
<ul class="tablist">
|
41 |
-
<li><a href="index.html"><span>Main Page</span></a></li>
|
42 |
-
<li><a href="modules.html"><span>Modules</span></a></li>
|
43 |
-
<li class="current"><a href="files.html"><span>Files</span></a></li>
|
44 |
-
<li>
|
45 |
-
<div id="MSearchBox" class="MSearchBoxInactive">
|
46 |
-
<span class="left">
|
47 |
-
<img id="MSearchSelect" src="search/mag_sel.png"
|
48 |
-
onmouseover="return searchBox.OnSearchSelectShow()"
|
49 |
-
onmouseout="return searchBox.OnSearchSelectHide()"
|
50 |
-
alt=""/>
|
51 |
-
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
52 |
-
onfocus="searchBox.OnSearchFieldFocus(true)"
|
53 |
-
onblur="searchBox.OnSearchFieldFocus(false)"
|
54 |
-
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
55 |
-
</span><span class="right">
|
56 |
-
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
57 |
-
</span>
|
58 |
-
</div>
|
59 |
-
</li>
|
60 |
-
</ul>
|
61 |
-
</div>
|
62 |
-
<div id="navrow2" class="tabs2">
|
63 |
-
<ul class="tablist">
|
64 |
-
<li><a href="files.html"><span>File List</span></a></li>
|
65 |
-
</ul>
|
66 |
-
</div>
|
67 |
-
<!-- window showing the filter options -->
|
68 |
-
<div id="MSearchSelectWindow"
|
69 |
-
onmouseover="return searchBox.OnSearchSelectShow()"
|
70 |
-
onmouseout="return searchBox.OnSearchSelectHide()"
|
71 |
-
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
72 |
-
</div>
|
73 |
-
|
74 |
-
<!-- iframe showing the search results (closed by default) -->
|
75 |
-
<div id="MSearchResultsWindow">
|
76 |
-
<iframe src="javascript:void(0)" frameborder="0"
|
77 |
-
name="MSearchResults" id="MSearchResults">
|
78 |
-
</iframe>
|
79 |
-
</div>
|
80 |
-
|
81 |
-
<div id="nav-path" class="navpath">
|
82 |
-
<ul>
|
83 |
-
<li class="navelem"><a class="el" href="dir_3a581ba30d25676e4b797b1f96d53b45.html">F:</a></li><li class="navelem"><a class="el" href="dir_9e5fe034a00e89334fd5186c3e7db156.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_d9496f0844b48bc7e53b5af8c99b9ab2.html">Source</a></li><li class="navelem"><a class="el" href="dir_a8bee7be44182a33f3820393ae0b105d.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_44e5e654415abd9ca6fdeaddaff8565e.html">glm</a></li><li class="navelem"><a class="el" href="dir_cef2d71d502cb69a9252bca2297d9549.html">glm</a></li><li class="navelem"><a class="el" href="dir_033f5edb0915b828d2c46ed4804e5503.html">detail</a></li> </ul>
|
84 |
-
</div>
|
85 |
-
</div><!-- top -->
|
86 |
-
<div class="header">
|
87 |
-
<div class="headertitle">
|
88 |
-
<div class="title">_noise.hpp</div> </div>
|
89 |
-
</div><!--header-->
|
90 |
-
<div class="contents">
|
91 |
-
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> <span class="preprocessor">#pragma once</span></div>
|
92 |
-
<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> </div>
|
93 |
-
<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="preprocessor">#include "../common.hpp"</span></div>
|
94 |
-
<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> </div>
|
95 |
-
<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="keyword">namespace </span><a class="code" href="a00236.html">glm</a>{</div>
|
96 |
-
<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="keyword">namespace </span>detail</div>
|
97 |
-
<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> {</div>
|
98 |
-
<div class="line"><a name="l00008"></a><span class="lineno"> 8</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T></div>
|
99 |
-
<div class="line"><a name="l00009"></a><span class="lineno"> 9</span>  GLM_FUNC_QUALIFIER T mod289(T <span class="keyword">const</span>& x)</div>
|
100 |
-
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span>  {</div>
|
101 |
-
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span>  <span class="keywordflow">return</span> x - <a class="code" href="a00241.html#gaa9d0742639e85b29c7c5de11cfd6840d">floor</a>(x * (static_cast<T>(1.0) / static_cast<T>(289.0))) * <span class="keyword">static_cast<</span>T<span class="keyword">></span>(289.0);</div>
|
102 |
-
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span>  }</div>
|
103 |
-
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> </div>
|
104 |
-
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T></div>
|
105 |
-
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span>  GLM_FUNC_QUALIFIER T permute(T <span class="keyword">const</span>& x)</div>
|
106 |
-
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span>  {</div>
|
107 |
-
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
|
108 |
-
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span>  }</div>
|
109 |
-
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> </div>
|
110 |
-
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
111 |
-
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span>  GLM_FUNC_QUALIFIER vec<2, T, Q> permute(vec<2, T, Q> <span class="keyword">const</span>& x)</div>
|
112 |
-
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span>  {</div>
|
113 |
-
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
|
114 |
-
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span>  }</div>
|
115 |
-
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div>
|
116 |
-
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
117 |
-
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span>  GLM_FUNC_QUALIFIER vec<3, T, Q> permute(vec<3, T, Q> <span class="keyword">const</span>& x)</div>
|
118 |
-
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>  {</div>
|
119 |
-
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
|
120 |
-
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span>  }</div>
|
121 |
-
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span> </div>
|
122 |
-
<div class="line"><a name="l00032"></a><span class="lineno"> 32</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
123 |
-
<div class="line"><a name="l00033"></a><span class="lineno"> 33</span>  GLM_FUNC_QUALIFIER vec<4, T, Q> permute(vec<4, T, Q> <span class="keyword">const</span>& x)</div>
|
124 |
-
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span>  {</div>
|
125 |
-
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
|
126 |
-
<div class="line"><a name="l00036"></a><span class="lineno"> 36</span>  }</div>
|
127 |
-
<div class="line"><a name="l00037"></a><span class="lineno"> 37</span> </div>
|
128 |
-
<div class="line"><a name="l00038"></a><span class="lineno"> 38</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T></div>
|
129 |
-
<div class="line"><a name="l00039"></a><span class="lineno"> 39</span>  GLM_FUNC_QUALIFIER T taylorInvSqrt(T <span class="keyword">const</span>& r)</div>
|
130 |
-
<div class="line"><a name="l00040"></a><span class="lineno"> 40</span>  {</div>
|
131 |
-
<div class="line"><a name="l00041"></a><span class="lineno"> 41</span>  <span class="keywordflow">return</span> <span class="keyword">static_cast<</span>T<span class="keyword">></span>(1.79284291400159) - <span class="keyword">static_cast<</span>T<span class="keyword">></span>(0.85373472095314) * r;</div>
|
132 |
-
<div class="line"><a name="l00042"></a><span class="lineno"> 42</span>  }</div>
|
133 |
-
<div class="line"><a name="l00043"></a><span class="lineno"> 43</span> </div>
|
134 |
-
<div class="line"><a name="l00044"></a><span class="lineno"> 44</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
135 |
-
<div class="line"><a name="l00045"></a><span class="lineno"> 45</span>  GLM_FUNC_QUALIFIER vec<2, T, Q> taylorInvSqrt(vec<2, T, Q> <span class="keyword">const</span>& r)</div>
|
136 |
-
<div class="line"><a name="l00046"></a><span class="lineno"> 46</span>  {</div>
|
137 |
-
<div class="line"><a name="l00047"></a><span class="lineno"> 47</span>  <span class="keywordflow">return</span> <span class="keyword">static_cast<</span>T<span class="keyword">></span>(1.79284291400159) - <span class="keyword">static_cast<</span>T<span class="keyword">></span>(0.85373472095314) * r;</div>
|
138 |
-
<div class="line"><a name="l00048"></a><span class="lineno"> 48</span>  }</div>
|
139 |
-
<div class="line"><a name="l00049"></a><span class="lineno"> 49</span> </div>
|
140 |
-
<div class="line"><a name="l00050"></a><span class="lineno"> 50</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
141 |
-
<div class="line"><a name="l00051"></a><span class="lineno"> 51</span>  GLM_FUNC_QUALIFIER vec<3, T, Q> taylorInvSqrt(vec<3, T, Q> <span class="keyword">const</span>& r)</div>
|
142 |
-
<div class="line"><a name="l00052"></a><span class="lineno"> 52</span>  {</div>
|
143 |
-
<div class="line"><a name="l00053"></a><span class="lineno"> 53</span>  <span class="keywordflow">return</span> <span class="keyword">static_cast<</span>T<span class="keyword">></span>(1.79284291400159) - <span class="keyword">static_cast<</span>T<span class="keyword">></span>(0.85373472095314) * r;</div>
|
144 |
-
<div class="line"><a name="l00054"></a><span class="lineno"> 54</span>  }</div>
|
145 |
-
<div class="line"><a name="l00055"></a><span class="lineno"> 55</span> </div>
|
146 |
-
<div class="line"><a name="l00056"></a><span class="lineno"> 56</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
147 |
-
<div class="line"><a name="l00057"></a><span class="lineno"> 57</span>  GLM_FUNC_QUALIFIER vec<4, T, Q> taylorInvSqrt(vec<4, T, Q> <span class="keyword">const</span>& r)</div>
|
148 |
-
<div class="line"><a name="l00058"></a><span class="lineno"> 58</span>  {</div>
|
149 |
-
<div class="line"><a name="l00059"></a><span class="lineno"> 59</span>  <span class="keywordflow">return</span> <span class="keyword">static_cast<</span>T<span class="keyword">></span>(1.79284291400159) - <span class="keyword">static_cast<</span>T<span class="keyword">></span>(0.85373472095314) * r;</div>
|
150 |
-
<div class="line"><a name="l00060"></a><span class="lineno"> 60</span>  }</div>
|
151 |
-
<div class="line"><a name="l00061"></a><span class="lineno"> 61</span> </div>
|
152 |
-
<div class="line"><a name="l00062"></a><span class="lineno"> 62</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
153 |
-
<div class="line"><a name="l00063"></a><span class="lineno"> 63</span>  GLM_FUNC_QUALIFIER vec<2, T, Q> fade(vec<2, T, Q> <span class="keyword">const</span>& t)</div>
|
154 |
-
<div class="line"><a name="l00064"></a><span class="lineno"> 64</span>  {</div>
|
155 |
-
<div class="line"><a name="l00065"></a><span class="lineno"> 65</span>  <span class="keywordflow">return</span> (t * t * t) * (t * (t * <span class="keyword">static_cast<</span>T<span class="keyword">></span>(6) - static_cast<T>(15)) + static_cast<T>(10));</div>
|
156 |
-
<div class="line"><a name="l00066"></a><span class="lineno"> 66</span>  }</div>
|
157 |
-
<div class="line"><a name="l00067"></a><span class="lineno"> 67</span> </div>
|
158 |
-
<div class="line"><a name="l00068"></a><span class="lineno"> 68</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
159 |
-
<div class="line"><a name="l00069"></a><span class="lineno"> 69</span>  GLM_FUNC_QUALIFIER vec<3, T, Q> fade(vec<3, T, Q> <span class="keyword">const</span>& t)</div>
|
160 |
-
<div class="line"><a name="l00070"></a><span class="lineno"> 70</span>  {</div>
|
161 |
-
<div class="line"><a name="l00071"></a><span class="lineno"> 71</span>  <span class="keywordflow">return</span> (t * t * t) * (t * (t * <span class="keyword">static_cast<</span>T<span class="keyword">></span>(6) - static_cast<T>(15)) + static_cast<T>(10));</div>
|
162 |
-
<div class="line"><a name="l00072"></a><span class="lineno"> 72</span>  }</div>
|
163 |
-
<div class="line"><a name="l00073"></a><span class="lineno"> 73</span> </div>
|
164 |
-
<div class="line"><a name="l00074"></a><span class="lineno"> 74</span>  <span class="keyword">template</span><<span class="keyword">typename</span> T, qualifier Q></div>
|
165 |
-
<div class="line"><a name="l00075"></a><span class="lineno"> 75</span>  GLM_FUNC_QUALIFIER vec<4, T, Q> fade(vec<4, T, Q> <span class="keyword">const</span>& t)</div>
|
166 |
-
<div class="line"><a name="l00076"></a><span class="lineno"> 76</span>  {</div>
|
167 |
-
<div class="line"><a name="l00077"></a><span class="lineno"> 77</span>  <span class="keywordflow">return</span> (t * t * t) * (t * (t * <span class="keyword">static_cast<</span>T<span class="keyword">></span>(6) - static_cast<T>(15)) + static_cast<T>(10));</div>
|
168 |
-
<div class="line"><a name="l00078"></a><span class="lineno"> 78</span>  }</div>
|
169 |
-
<div class="line"><a name="l00079"></a><span class="lineno"> 79</span> }<span class="comment">//namespace detail</span></div>
|
170 |
-
<div class="line"><a name="l00080"></a><span class="lineno"> 80</span> }<span class="comment">//namespace glm</span></div>
|
171 |
-
<div class="line"><a name="l00081"></a><span class="lineno"> 81</span> </div>
|
172 |
-
<div class="ttc" id="a00241_html_gaa9d0742639e85b29c7c5de11cfd6840d"><div class="ttname"><a href="a00241.html#gaa9d0742639e85b29c7c5de11cfd6840d">glm::floor</a></div><div class="ttdeci">GLM_FUNC_DECL vec< L, T, Q > floor(vec< L, T, Q > const &x)</div><div class="ttdoc">Returns a value equal to the nearest integer that is less then or equal to x. </div></div>
|
173 |
-
<div class="ttc" id="a00236_html"><div class="ttname"><a href="a00236.html">glm</a></div><div class="ttdef"><b>Definition:</b> <a href="a00015_source.html#l00020">common.hpp:20</a></div></div>
|
174 |
-
</div><!-- fragment --></div><!-- contents -->
|
175 |
-
<!-- start footer part -->
|
176 |
-
<hr class="footer"/><address class="footer"><small>
|
177 |
-
Generated by  <a href="http://www.doxygen.org/index.html">
|
178 |
-
<img class="footer" src="doxygen.png" alt="doxygen"/>
|
179 |
-
</a> 1.8.10
|
180 |
-
</small></address>
|
181 |
-
</body>
|
182 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff-gaussian-rasterization/third_party/glm/doc/api/a00004_source.html
DELETED
The diff for this file is too large to render.
See raw diff
|
|