venite's picture
initial
f670afc
# Copyright (C) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# This work is made available under the Nvidia Source Code License-NC.
# To view a copy of this license, check out LICENSE.md
import numpy as np
import torch
class EvalCameraController:
def __init__(self, voxel, maxstep=128, pattern=0, cam_ang=73, smooth_decay_multiplier=1.0):
self.voxel = voxel
self.maxstep = maxstep
self.camera_poses = [] # ori, dir, up, f
circle = torch.linspace(0, 2*np.pi, steps=maxstep)
size = min(voxel.voxel_t.size(1), voxel.voxel_t.size(2)) / 2
# Shrink the circle a bit.
shift = size * 0.2
size = size * 0.8
if pattern == 0:
height_history = []
# Calculate smooth height.
for i in range(maxstep):
farpoint = torch.tensor([
70,
torch.sin(circle[i])*size + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size + voxel.voxel_t.size(2)/2 + shift])
height_history.append(self._get_height(farpoint[1], farpoint[2], farpoint[0]))
# Filtfilt
height_history = self.filtfilt(height_history, decay=0.2*smooth_decay_multiplier)
for i in range(maxstep):
farpoint = torch.tensor([
70,
torch.sin(circle[i])*size + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = height_history[i]
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.5 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.5 + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(cam_ang/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
elif pattern == 1:
zoom = torch.linspace(1.0, 0.25, steps=maxstep)
height_history = []
for i in range(maxstep):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size + voxel.voxel_t.size(2)/2 + shift])
height_history.append(self._get_height(farpoint[1], farpoint[2], farpoint[0]))
height_history = self.filtfilt(height_history, decay=0.2*smooth_decay_multiplier)
for i in range(maxstep):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = height_history[i]
nearpoint = torch.tensor([
60,
torch.sin(circle[i]-0.3*np.pi)*size*0.3 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]-0.3*np.pi)*size*0.3 + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(cam_ang/2)*zoom[i]) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
elif pattern == 2:
move = torch.linspace(1.0, 0.2, steps=maxstep)
height_history = []
for i in range(maxstep):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
height_history.append(self._get_height(farpoint[1], farpoint[2], farpoint[0]))
height_history = self.filtfilt(height_history, decay=0.2*smooth_decay_multiplier)
for i in range(maxstep):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = height_history[i]
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(cam_ang/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
elif pattern == 3:
move = torch.linspace(0.75, 0.2, steps=maxstep)
height_history = []
for i in range(maxstep):
farpoint = torch.tensor([
70,
torch.sin(-circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(-circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
height_history.append(self._get_height(farpoint[1], farpoint[2], farpoint[0]))
height_history = self.filtfilt(height_history, decay=0.2*smooth_decay_multiplier)
for i in range(maxstep):
farpoint = torch.tensor([
70,
torch.sin(-circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(-circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = height_history[i]
nearpoint = torch.tensor([
60,
torch.sin(-circle[i]-0.4*np.pi)*size*0.9*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(-circle[i]-0.4*np.pi)*size*0.9*move[i] + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(cam_ang/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
elif pattern == 4:
move = torch.linspace(1.0, 0.5, steps=maxstep)
height_history = []
for i in range(maxstep):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
height_history.append(self._get_height(farpoint[1], farpoint[2], farpoint[0]))
height_history = self.filtfilt(height_history, decay=0.2*smooth_decay_multiplier)
for i in range(maxstep):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = height_history[i]
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(cam_ang/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
# look outward
elif pattern == 5:
move = torch.linspace(1.0, 0.5, steps=maxstep)
height_history = []
for i in range(maxstep):
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(2)/2 + shift])
height_history.append(self._get_height(nearpoint[1], nearpoint[2], nearpoint[0]))
height_history = self.filtfilt(height_history, decay=0.2*smooth_decay_multiplier)
for i in range(maxstep):
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(2)/2 + shift])
nearpoint[0] = height_history[i]
farpoint = torch.tensor([
60,
torch.sin(circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(nearpoint)
cam_dir = self.voxel.world2local(farpoint - nearpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(cam_ang/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
# Rise
elif pattern == 6:
shift = 0
lift = torch.linspace(0.0, 200.0, steps=maxstep)
zoom = torch.linspace(0.8, 1.6, steps=maxstep)
for i in range(maxstep):
farpoint = torch.tensor([
80+lift[i],
torch.sin(circle[i]/4)*size*0.2 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]/4)*size*0.2 + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = self._get_height(farpoint[1], farpoint[2], farpoint[0])
nearpoint = torch.tensor([
65,
torch.sin(circle[i]/4+0.5*np.pi)*size*0.1 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]/4+0.5*np.pi)*size*0.1 + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)*zoom[i]) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
# 45deg
elif pattern == 7:
rad = torch.tensor([np.deg2rad(45).astype(np.float32)])
size = 1536
for i in range(maxstep):
farpoint = torch.tensor([
61+size,
torch.sin(rad)*size + voxel.voxel_t.size(1)/2,
torch.cos(rad)*size + voxel.voxel_t.size(2)/2])
nearpoint = torch.tensor([
61,
voxel.voxel_t.size(1)/2,
voxel.voxel_t.size(2)/2])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(19.5/2)) # about 50mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
def _get_height(self, loc0, loc1, minheight):
loc0 = int(loc0)
loc1 = int(loc1)
height = minheight
for dx in range(-3, 4):
for dy in range(-3, 4):
if (loc0+dx) < 0 or (loc0+dx) >= self.voxel.heightmap.shape[0] or (loc1+dy) < 0 or \
(loc1+dy) >= self.voxel.heightmap.shape[1]:
height = max(height, minheight)
else:
height = max(height, self.voxel.heightmap[loc0+dx, loc1+dy] + 2)
return height
def filtfilt(self, height_history, decay=0.2):
# Filtfilt
height_history2 = []
maxstep = len(height_history)
prev_height = height_history[0]
for i in range(maxstep):
prev_height = prev_height - decay
if prev_height < height_history[i]:
prev_height = height_history[i]
height_history2.append(prev_height)
prev_height = height_history[-1]
for i in range(maxstep-1, -1, -1):
prev_height = prev_height - decay
if prev_height < height_history[i]:
prev_height = height_history[i]
height_history2[i] = max(prev_height, height_history2[i])
return height_history2
def __len__(self):
return len(self.camera_poses)
def __getitem__(self, idx):
return self.camera_poses[idx]
class TourCameraController:
def __init__(self, voxel, maxstep=128):
self.voxel = voxel
self.maxstep = maxstep
self.camera_poses = [] # ori, dir, up, f
circle = torch.linspace(0, 2*np.pi, steps=maxstep//4)
size = min(voxel.voxel_t.size(1), voxel.voxel_t.size(2)) / 2
# Shrink the circle a bit
shift = size * 0.2
size = size * 0.8
for i in range(maxstep//4):
farpoint = torch.tensor([
70,
torch.sin(circle[i])*size + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = self._get_height(farpoint[1], farpoint[2], farpoint[0])
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.5 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.5 + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
zoom = torch.linspace(1.0, 0.25, steps=maxstep//4)
for i in range(maxstep//4):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = self._get_height(farpoint[1], farpoint[2], farpoint[0])
nearpoint = torch.tensor([
60,
torch.sin(circle[i]-0.3*np.pi)*size*0.3 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]-0.3*np.pi)*size*0.3 + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)*zoom[i]) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
move = torch.linspace(1.0, 0.2, steps=maxstep//4)
for i in range(maxstep//4):
farpoint = torch.tensor([
90,
torch.sin(circle[i])*size*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*move[i] + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = self._get_height(farpoint[1], farpoint[2], farpoint[0])
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.3*move[i] + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
lift = torch.linspace(0.0, 200.0, steps=maxstep//4)
zoom = torch.linspace(0.6, 1.2, steps=maxstep//4)
for i in range(maxstep//4):
farpoint = torch.tensor([
80+lift[i],
torch.sin(circle[i])*size*0.2 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i])*size*0.2 + voxel.voxel_t.size(2)/2 + shift])
farpoint[0] = self._get_height(farpoint[1], farpoint[2], farpoint[0])
nearpoint = torch.tensor([
60,
torch.sin(circle[i]+0.5*np.pi)*size*0.1 + voxel.voxel_t.size(1)/2 + shift,
torch.cos(circle[i]+0.5*np.pi)*size*0.1 + voxel.voxel_t.size(2)/2 + shift])
cam_ori = self.voxel.world2local(farpoint)
cam_dir = self.voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = self.voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)*zoom[i]) # about 24mm fov
self.camera_poses.append((cam_ori, cam_dir, cam_up, cam_f))
def _get_height(self, loc0, loc1, minheight):
loc0 = int(loc0)
loc1 = int(loc1)
height = minheight
for dx in range(-3, 4):
for dy in range(-3, 4):
if (loc0+dx) < 0 or (loc0+dx) >= self.voxel.heightmap.shape[0] or (loc1+dy) < 0 or \
(loc1+dy) >= self.voxel.heightmap.shape[1]:
height = max(height, minheight)
else:
height = max(height, self.voxel.heightmap[loc0+dx, loc1+dy] + 2)
return height
def __len__(self):
return len(self.camera_poses)
def __getitem__(self, idx):
return self.camera_poses[idx]
def rand_camera_pose_birdseye(voxel, border=128):
r"""Generating random camera pose in the upper hemisphere, in the format of origin-direction-up
Assuming [Y X Z] coordinate. Y is negative gravity direction.
The camera pose is converted into the voxel coordinate system so that it can be used directly for rendering
1. Uniformly sample a point on the upper hemisphere of a unit sphere, as cam_ori.
2. Set cam_dir to be from cam_ori to the origin
3. cam_up is always pointing towards sky
4. move cam_ori to random place according to voxel size
"""
cam_dir = torch.randn(3, dtype=torch.float32)
cam_dir = cam_dir / torch.sqrt(torch.sum(cam_dir*cam_dir))
cam_dir[0] = -torch.abs(cam_dir[0])
cam_up = torch.tensor([1, 0, 0], dtype=torch.float32)
# generate camera lookat target
r = np.random.rand(2)
r[0] *= voxel.voxel_t.size(1)-border-border
r[1] *= voxel.voxel_t.size(2)-border-border
r = r + border
y = voxel.heightmap[int(r[0]+0.5), int(r[1]+0.5)] + (np.random.rand(1)-0.5) * 5
cam_target = torch.tensor([y, r[0], r[1]], dtype=torch.float32)
cam_ori = cam_target - cam_dir * (np.random.rand(1).item() * 100)
cam_ori[0] = max(voxel.heightmap[int(cam_ori[1]+0.5), int(cam_ori[2]+0.5)]+2, cam_ori[0])
# Translate to voxel coordinate
cam_ori = voxel.world2local(cam_ori)
cam_dir = voxel.world2local(cam_dir, is_vec=True)
cam_up = voxel.world2local(cam_up, is_vec=True)
return cam_ori, cam_dir, cam_up
def get_neighbor_height(heightmap, loc0, loc1, minheight, neighbor_size=7):
loc0 = int(loc0)
loc1 = int(loc1)
height = 0
for dx in range(-neighbor_size//2, neighbor_size//2+1):
for dy in range(-neighbor_size//2, neighbor_size//2+1):
if (loc0+dx) < 0 or (loc0+dx) >= heightmap.shape[0] or (loc1+dy) < 0 or (loc1+dy) >= heightmap.shape[1]:
height = max(height, minheight)
else:
height = max(minheight, heightmap[loc0+dx, loc1+dy] + 2)
return height
def rand_camera_pose_firstperson(voxel, border=128):
r"""Generating random camera pose in the upper hemisphere, in the format of origin-direction-up
"""
r = np.random.rand(5)
r[0] *= voxel.voxel_t.size(1)-border-border
r[1] *= voxel.voxel_t.size(2)-border-border
r[0] = r[0] + border
r[1] = r[1] + border
y = get_neighbor_height(voxel.heightmap, r[0], r[1], 0) + np.random.rand(1) * 15
cam_ori = torch.tensor([y, r[0], r[1]], dtype=torch.float32)
rand_ang_h = r[2] * 2 * np.pi
cam_target = torch.tensor([0, cam_ori[1]+np.sin(rand_ang_h)*border*r[4], cam_ori[2] +
np.cos(rand_ang_h)*border*r[4]], dtype=torch.float32)
cam_target[0] = get_neighbor_height(voxel.heightmap, cam_target[1],
cam_target[2], 0, neighbor_size=1) - 2 + r[3] * 10
cam_dir = cam_target - cam_ori
cam_up = torch.tensor([1, 0, 0], dtype=torch.float32)
cam_ori = voxel.world2local(cam_ori)
cam_dir = voxel.world2local(cam_dir, is_vec=True)
cam_up = voxel.world2local(cam_up, is_vec=True)
return cam_ori, cam_dir, cam_up
def rand_camera_pose_thridperson(voxel, border=96):
r = torch.rand(2)
r[0] *= voxel.voxel_t.size(1)
r[1] *= voxel.voxel_t.size(2)
rand_height = 60 + torch.rand(1) * 40
rand_height = get_neighbor_height(voxel.heightmap, r[0], r[1], rand_height, neighbor_size=5)
farpoint = torch.tensor([rand_height, r[0], r[1]], dtype=torch.float32)
r = torch.rand(2)
r[0] *= voxel.voxel_t.size(1) - border - border
r[1] *= voxel.voxel_t.size(2) - border - border
r[0] = r[0] + border
r[1] = r[1] + border
rand_height = get_neighbor_height(voxel.heightmap, r[0], r[1], 65, neighbor_size=1) - 5
nearpoint = torch.tensor([rand_height, r[0], r[1]], dtype=torch.float32)
cam_ori = voxel.world2local(farpoint)
cam_dir = voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = voxel.world2local(torch.tensor([1, 0, 0], dtype=torch.float32), is_vec=True)
return cam_ori, cam_dir, cam_up
def rand_camera_pose_thridperson2(voxel, border=48):
r = torch.rand(2)
r[0] *= voxel.voxel_t.size(1) - border - border
r[1] *= voxel.voxel_t.size(2) - border - border
r[0] = r[0] + border
r[1] = r[1] + border
rand_height = 60 + torch.rand(1) * 40
rand_height = get_neighbor_height(voxel.heightmap, r[0], r[1], rand_height, neighbor_size=5)
farpoint = torch.tensor([rand_height, r[0], r[1]], dtype=torch.float32)
r = torch.rand(2)
r[0] *= voxel.voxel_t.size(1) - border - border
r[1] *= voxel.voxel_t.size(2) - border - border
r[0] = r[0] + border
r[1] = r[1] + border
rand_height = get_neighbor_height(voxel.heightmap, r[0], r[1], 65, neighbor_size=1) - 5
nearpoint = torch.tensor([rand_height, r[0], r[1]], dtype=torch.float32)
# Random Up vector (tilt a little bit)
# up = torch.randn(3) * 0.05 # cutoff +-0.1, Tan(10deg) = 0.176
up = torch.randn(3) * 0.02
up[0] = 1.0
up = up / up.norm(p=2)
cam_ori = voxel.world2local(farpoint)
cam_dir = voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = voxel.world2local(up, is_vec=True)
return cam_ori, cam_dir, cam_up
def rand_camera_pose_thridperson3(voxel, border=64):
r"""Attempting to solve the camera too close to wall problem and the lack of aerial poses."""
r = torch.rand(2)
r[0] *= voxel.voxel_t.size(1) - border - border
r[1] *= voxel.voxel_t.size(2) - border - border
r[0] = r[0] + border
r[1] = r[1] + border
rand_height = 60 + torch.rand(1) * 40
if torch.rand(1) > 0.8:
rand_height = 60 + torch.rand(1) * 60
rand_height = get_neighbor_height(voxel.heightmap, r[0], r[1], rand_height, neighbor_size=7)
farpoint = torch.tensor([rand_height, r[0], r[1]], dtype=torch.float32)
r = torch.rand(2)
r[0] *= voxel.voxel_t.size(1) - border - border
r[1] *= voxel.voxel_t.size(2) - border - border
r[0] = r[0] + border
r[1] = r[1] + border
rand_height = get_neighbor_height(voxel.heightmap, r[0], r[1], 65, neighbor_size=3) - 5
nearpoint = torch.tensor([rand_height, r[0], r[1]], dtype=torch.float32)
# Random Up vector (tilt a little bit)
# up = torch.randn(3) * 0.05 # cutoff +-0.1, Tan(10deg) = 0.176
up = torch.randn(3) * 0.02
up[0] = 1.0
up = up / up.norm(p=2)
# print(up)
cam_ori = voxel.world2local(farpoint)
cam_dir = voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = voxel.world2local(up, is_vec=True)
return cam_ori, cam_dir, cam_up
def rand_camera_pose_tour(voxel):
size = min(voxel.voxel_t.size(1), voxel.voxel_t.size(2)) / 2
center = [voxel.voxel_t.size(1)/2, voxel.voxel_t.size(2)/2]
rnd = torch.rand(8)
rnd_deg = torch.rand(1) * 2 * np.pi
far_radius = rnd[0]*0.8+0.2
far_height = rnd[1]*30 + 60
farpoint = torch.tensor([
far_height,
torch.sin(rnd_deg)*size*far_radius + center[0],
torch.cos(rnd_deg)*size*far_radius + center[1]])
farpoint[0] = get_neighbor_height(voxel.heightmap, farpoint[1], farpoint[2], farpoint[0], neighbor_size=7)
near_radius = far_radius * rnd[2]
near_shift_rad = np.pi*(rnd[3]-0.5)
near_height = 60 + rnd[4] * 10
nearpoint = torch.tensor([
near_height,
torch.sin(rnd_deg+near_shift_rad)*size*near_radius + center[0],
torch.cos(rnd_deg+near_shift_rad)*size*near_radius + center[1]])
# Random Up vector (tilt a little bit)
# up = torch.randn(3) * 0.05 # cutoff +-0.1, Tan(10deg) = 0.176
up = torch.randn(3) * 0.02
up[0] = 1.0
up = up / up.norm(p=2)
cam_ori = voxel.world2local(farpoint)
cam_dir = voxel.world2local(nearpoint - farpoint, is_vec=True)
cam_up = voxel.world2local(up, is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)*(rnd[5]*0.75+0.25)) # about 24mm fov
return cam_ori, cam_dir, cam_up, cam_f
# Look from center to outward
def rand_camera_pose_insideout(voxel):
size = min(voxel.voxel_t.size(1), voxel.voxel_t.size(2)) / 2
center = [voxel.voxel_t.size(1)/2, voxel.voxel_t.size(2)/2]
rnd = torch.rand(8)
rnd_deg = torch.rand(1) * 2 * np.pi
far_radius = rnd[0]*0.8+0.2
far_height = rnd[1]*10 + 60
farpoint = torch.tensor([
far_height,
torch.sin(rnd_deg)*size*far_radius + center[0],
torch.cos(rnd_deg)*size*far_radius + center[1]])
near_radius = far_radius * rnd[2]
near_shift_rad = np.pi*(rnd[3]-0.5)
near_height = 60 + rnd[4] * 30
nearpoint = torch.tensor([
near_height,
torch.sin(rnd_deg+near_shift_rad)*size*near_radius + center[0],
torch.cos(rnd_deg+near_shift_rad)*size*near_radius + center[1]])
nearpoint[0] = get_neighbor_height(voxel.heightmap, nearpoint[1], nearpoint[2], nearpoint[0], neighbor_size=7)
# Random Up vector (tilt a little bit)
# up = torch.randn(3) * 0.05 # cutoff +-0.1, Tan(10deg) = 0.176
up = torch.randn(3) * 0.02
up[0] = 1.0
up = up / up.norm(p=2)
cam_ori = voxel.world2local(nearpoint)
cam_dir = voxel.world2local(farpoint-nearpoint, is_vec=True)
cam_up = voxel.world2local(up, is_vec=True)
cam_f = 0.5/np.tan(np.deg2rad(73/2)*(rnd[5]*0.75+0.25)) # about 24mm fov
return cam_ori, cam_dir, cam_up, cam_f