mirror of
https://github.com/open-goal/jak-project
synced 2026-08-18 21:57:54 -04:00
first pass at cam cleanup
This commit is contained in:
@@ -737,6 +737,7 @@ void Env::rebuild_stack_slot_use_def_info() {
|
||||
|
||||
int next_var_id = 1;
|
||||
for (int offset : offsets) {
|
||||
const int first_var_id = next_var_id;
|
||||
std::vector<bool> reads_before_write(block_count, false);
|
||||
std::vector<bool> writes(block_count, false);
|
||||
|
||||
@@ -784,6 +785,7 @@ void Env::rebuild_stack_slot_use_def_info() {
|
||||
|
||||
std::vector<int> phi_var(block_count, -1);
|
||||
std::vector<std::vector<int>> phi_sources(block_count);
|
||||
std::vector<int> access_ops;
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
if (live_in.at(block_id)) {
|
||||
phi_var.at(block_id) = next_var_id++;
|
||||
@@ -801,6 +803,7 @@ void Env::rebuild_stack_slot_use_def_info() {
|
||||
}
|
||||
ASSERT(current_var != -1);
|
||||
m_stack_slot_var_by_op[op_id] = current_var;
|
||||
access_ops.push_back(op_id);
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), current_var)];
|
||||
info.uses.push_back({op_id, block_id, AccessMode::READ, false});
|
||||
info.ssa_vars.insert(current_var);
|
||||
@@ -810,6 +813,7 @@ void Env::rebuild_stack_slot_use_def_info() {
|
||||
}
|
||||
current_var = next_var_id++;
|
||||
m_stack_slot_var_by_op[op_id] = current_var;
|
||||
access_ops.push_back(op_id);
|
||||
auto& info = m_stack_slot_use_def_info[RegId(Register(Reg::GPR, Reg::SP), current_var)];
|
||||
info.defs.push_back({op_id, block_id, AccessMode::WRITE, false});
|
||||
info.ssa_vars.insert(current_var);
|
||||
@@ -839,6 +843,57 @@ void Env::rebuild_stack_slot_use_def_info() {
|
||||
info.uses.push_back({first_op, block_id, AccessMode::READ, false});
|
||||
}
|
||||
}
|
||||
|
||||
// Match register variable analysis by merging every live stack-slot phi with its incoming
|
||||
// definitions. Without this, a conditional store and the loads after its control-flow join
|
||||
// receive different program-variable IDs even though they are one mutable source variable.
|
||||
std::vector<int> parent(next_var_id - first_var_id);
|
||||
for (int i = 0; i < (int)parent.size(); i++) {
|
||||
parent.at(i) = first_var_id + i;
|
||||
}
|
||||
auto find_root = [&](int var) {
|
||||
int root = var;
|
||||
while (parent.at(root - first_var_id) != root) {
|
||||
root = parent.at(root - first_var_id);
|
||||
}
|
||||
while (parent.at(var - first_var_id) != var) {
|
||||
const int next = parent.at(var - first_var_id);
|
||||
parent.at(var - first_var_id) = root;
|
||||
var = next;
|
||||
}
|
||||
return root;
|
||||
};
|
||||
for (int block_id = 0; block_id < block_count; block_id++) {
|
||||
if (phi_var.at(block_id) == -1) {
|
||||
continue;
|
||||
}
|
||||
const int phi_root = find_root(phi_var.at(block_id));
|
||||
for (int src_var : phi_sources.at(block_id)) {
|
||||
parent.at(find_root(src_var) - first_var_id) = phi_root;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<int, UseDefInfo> merged_info;
|
||||
for (int var = first_var_id; var < next_var_id; var++) {
|
||||
const int root = find_root(var);
|
||||
auto& merged = merged_info[root];
|
||||
merged.ssa_vars.insert(var);
|
||||
|
||||
const RegId old_id(Register(Reg::GPR, Reg::SP), var);
|
||||
auto old = m_stack_slot_use_def_info.find(old_id);
|
||||
if (old != m_stack_slot_use_def_info.end()) {
|
||||
merged.defs.insert(merged.defs.end(), old->second.defs.begin(), old->second.defs.end());
|
||||
merged.uses.insert(merged.uses.end(), old->second.uses.begin(), old->second.uses.end());
|
||||
merged.ssa_vars.insert(old->second.ssa_vars.begin(), old->second.ssa_vars.end());
|
||||
m_stack_slot_use_def_info.erase(old);
|
||||
}
|
||||
}
|
||||
for (auto& [root, info] : merged_info) {
|
||||
m_stack_slot_use_def_info.emplace(RegId(Register(Reg::GPR, Reg::SP), root), std::move(info));
|
||||
}
|
||||
for (int op_id : access_ops) {
|
||||
m_stack_slot_var_by_op.at(op_id) = find_root(m_stack_slot_var_by_op.at(op_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,40 +185,6 @@ FormElement* rewrite_as_dotimes(LetElement* in, const Env& env, FormPool& pool)
|
||||
return rewrite_as_dotimes(entry.dest, loop, env, pool);
|
||||
}
|
||||
|
||||
bool program_var_is_confined_to(const Form* top_level_form,
|
||||
const RegId& var,
|
||||
FormElement* init,
|
||||
FormElement* loop,
|
||||
const Env& env) {
|
||||
RegAccessSet all_accesses;
|
||||
top_level_form->collect_vars(all_accesses, true);
|
||||
|
||||
RegAccessSet confined_accesses;
|
||||
init->collect_vars(confined_accesses, true);
|
||||
loop->collect_vars(confined_accesses, true);
|
||||
|
||||
for (const auto& access : all_accesses) {
|
||||
if (env.get_program_var_id(access) == var && !confined_accesses.count(access)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool program_var_shares_name(const Form* top_level_form,
|
||||
const RegId& var,
|
||||
const std::string& name,
|
||||
const Env& env) {
|
||||
RegAccessSet all_accesses;
|
||||
top_level_form->collect_vars(all_accesses, true);
|
||||
for (const auto& access : all_accesses) {
|
||||
if (env.get_program_var_id(access) != var && env.get_variable_name(access) == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<MatchResult, Form*, bool> rewrite_shelled_return_form(
|
||||
const Matcher& matcher,
|
||||
FormElement* in,
|
||||
@@ -4245,47 +4211,9 @@ LetStats insert_lets(const Function& func,
|
||||
// }
|
||||
LetStats stats;
|
||||
|
||||
// A deliberately reused display name can cause otherwise independent program variables to be
|
||||
// grouped together by let insertion. Recognize the unshelled expansion before inserting lets
|
||||
// when the counter's complete lifetime is confined to the adjacent set!/while pair. Doing this
|
||||
// here keeps a following co-named loop from being pulled into the first counter's let body, while
|
||||
// preserving the existing behavior for co-named variables in every other situation.
|
||||
top_level_form->apply_form([&](Form* f) {
|
||||
auto& elts = f->elts();
|
||||
for (size_t i = 0; i + 1 < elts.size();) {
|
||||
auto* init = dynamic_cast<SetVarElement*>(elts.at(i));
|
||||
if (!init || !register_can_hold_var(init->dst().reg()) ||
|
||||
init->info().is_eliminated_coloring_move || !is_constant_int(init->src(), 0)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto var = env.get_program_var_id(init->dst());
|
||||
const auto name = env.get_variable_name(init->dst());
|
||||
if (!program_var_shares_name(top_level_form, var, name, env) ||
|
||||
!program_var_is_confined_to(top_level_form, var, init, elts.at(i + 1), env)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* dotimes = rewrite_as_dotimes(init->dst(), elts.at(i + 1), env, pool);
|
||||
if (!dotimes) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
dotimes->parent_form = f;
|
||||
elts.at(i) = dotimes;
|
||||
elts.erase(elts.begin() + i + 1);
|
||||
env.set_defined_in_let(name);
|
||||
let_rewrite_stats.dotimes++;
|
||||
i++;
|
||||
}
|
||||
});
|
||||
|
||||
// Stored per variable.
|
||||
struct PerVarInfo {
|
||||
std::string unique_name; // displayed name used to join deliberately co-named SSA variables
|
||||
std::string display_name;
|
||||
RegisterAccess access;
|
||||
std::unordered_set<FormElement*> elts_using_var; // all FormElements using var
|
||||
Form* lca_form = nullptr; // the lowest common form that contains all the above elts
|
||||
@@ -4293,7 +4221,7 @@ LetStats insert_lets(const Function& func,
|
||||
int end_idx = -1; // in the above form, 1 + last FormElement using var's index
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, PerVarInfo> var_info;
|
||||
std::unordered_map<RegId, PerVarInfo, RegId::hash> var_info;
|
||||
|
||||
// Part 1, figure out which forms reference each var
|
||||
top_level_form->apply([&](FormElement* elt) {
|
||||
@@ -4318,10 +4246,10 @@ LetStats insert_lets(const Function& func,
|
||||
// and add it.
|
||||
for (auto& access : reg_accesses) {
|
||||
if (register_can_hold_var(access.reg())) {
|
||||
auto unique_name = env.get_variable_name(access);
|
||||
var_info[unique_name].elts_using_var.insert(elt);
|
||||
var_info[unique_name].unique_name = unique_name;
|
||||
var_info[unique_name].access = access;
|
||||
const auto var = env.get_program_var_id(access);
|
||||
var_info[var].elts_using_var.insert(elt);
|
||||
var_info[var].display_name = env.get_variable_name(access);
|
||||
var_info[var].access = access;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -4336,7 +4264,7 @@ LetStats insert_lets(const Function& func,
|
||||
lca = lca_form(lca, fe->parent_form, env);
|
||||
}
|
||||
ASSERT(lca);
|
||||
var_info[kv.first].lca_form = lca;
|
||||
kv.second.lca_form = lca;
|
||||
}
|
||||
|
||||
// Part 3, find the minimum range of FormElement's within the lca form that contain
|
||||
@@ -4353,7 +4281,7 @@ LetStats insert_lets(const Function& func,
|
||||
bool uses = false;
|
||||
for (auto& ra : ras) {
|
||||
if ((ra.reg().get_kind() == Reg::FPR || ra.reg().get_kind() == Reg::GPR) &&
|
||||
env.get_variable_name(ra) == kv.second.unique_name) {
|
||||
env.get_program_var_id(ra) == kv.first) {
|
||||
uses = true;
|
||||
}
|
||||
}
|
||||
@@ -4399,7 +4327,7 @@ LetStats insert_lets(const Function& func,
|
||||
auto first_form = info.lca_form->at(info.start_idx);
|
||||
auto first_form_as_set = dynamic_cast<SetVarElement*>(first_form);
|
||||
if (first_form_as_set && register_can_hold_var(first_form_as_set->dst().reg()) &&
|
||||
env.get_variable_name(first_form_as_set->dst()) == env.get_variable_name(info.access) &&
|
||||
env.get_program_var_id(first_form_as_set->dst()) == env.get_program_var_id(info.access) &&
|
||||
!first_form_as_set->info().is_eliminated_coloring_move) {
|
||||
bool allowed = true;
|
||||
|
||||
@@ -4422,12 +4350,12 @@ LetStats insert_lets(const Function& func,
|
||||
li.start_elt = info.start_idx;
|
||||
li.end_elt = info.end_idx;
|
||||
li.set_form = first_form_as_set;
|
||||
li.name = info.unique_name;
|
||||
li.name = info.display_name;
|
||||
possible_insertions[li.form].push_back(li);
|
||||
stats.vars_in_lets++;
|
||||
}
|
||||
} else {
|
||||
// lg::print("fail for {} : {}\n", info.var_name, first_form->to_string(env));
|
||||
// lg::print("fail for {} : {}\n", info.display_name, first_form->to_string(env));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
(require "engine/gfx/hw/display.gc")
|
||||
(require "engine/camera/camera.gc")
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
;; Blend the active camera slaves into the single transform used for rendering.
|
||||
;; The complexity here is around camera orientation. Orientations are interpolated
|
||||
@@ -25,10 +24,12 @@
|
||||
;; (copy-tracking (source camera-slave))
|
||||
;; Adopt source's tracking controls together with its current follow state and rotation,
|
||||
;; avoiding a discontinuity when an already tracking slave is handed to the combiner.
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(defstate cam-combiner-active (camera-combiner)
|
||||
:event
|
||||
(behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
||||
(local-vars (source-slave camera-slave))
|
||||
(case message
|
||||
(('point-of-interest)
|
||||
(cond
|
||||
@@ -36,7 +37,9 @@
|
||||
(set! (-> self tracking use-point-of-interest) #t)
|
||||
(set! (-> self tracking point-of-interest quad) (-> (the-as vector (-> block param 0)) quad))
|
||||
(set! (-> self tracking point-of-interest-blend target) 1.0))
|
||||
(else (set! (-> self tracking use-point-of-interest) #f) (set! (-> self tracking point-of-interest-blend target) 0.0))))
|
||||
(else
|
||||
(set! (-> self tracking use-point-of-interest) #f)
|
||||
(set! (-> self tracking point-of-interest-blend target) 0.0))))
|
||||
(('set-interpolation)
|
||||
(set! (-> self interp-val) 0.0)
|
||||
(set! (-> self interp-step) (/ 5.0 (the float (-> block param 0)))))
|
||||
@@ -48,7 +51,9 @@
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#f)))
|
||||
(('stop-tracking) (set! (-> self tracking-status) (cam-track-status use-slave-tracking)) 0)
|
||||
(('stop-tracking)
|
||||
(set! (-> self tracking-status) (cam-track-status use-slave-tracking))
|
||||
0)
|
||||
(('start-tracking)
|
||||
(cond
|
||||
((< argc 1)
|
||||
@@ -59,21 +64,21 @@
|
||||
(format 0 "ERROR <GMJ>: invalid type '~A' to *camera-combiner* start-tracking~%" (rtype-of (-> block param 0))))
|
||||
((= (-> self tracking-status) (cam-track-status use-slave-tracking))
|
||||
(set! (-> self tracking-status) (cam-track-status track-at-combiner))
|
||||
(set! source-slave (the-as camera-slave (-> block param 0)))
|
||||
(set! (-> self tracking-options) (the-as cam-slave-options-i (-> source-slave options)))
|
||||
(set! (-> self tracking no-follow) (-> source-slave tracking no-follow))
|
||||
(copy-cam-float-seeker (-> self tracking tilt-adjust) (-> source-slave tracking tilt-adjust))
|
||||
(copy-cam-float-seeker (-> self tracking underwater-blend) (-> source-slave tracking underwater-blend))
|
||||
(set! (-> self tracking use-point-of-interest) (-> source-slave tracking use-point-of-interest))
|
||||
(vector-copy! (-> self tracking point-of-interest) (-> source-slave tracking point-of-interest))
|
||||
(copy-cam-float-seeker (-> self tracking point-of-interest-blend) (-> source-slave tracking point-of-interest-blend))
|
||||
(let ((source-position (-> source-slave trans)))
|
||||
(cam-calc-follow! (-> self tracking) source-position #f)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
source-position
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#f)))))
|
||||
(let ((source-slave (the-as camera-slave (-> block param 0))))
|
||||
(set! (-> self tracking-options) (the-as cam-slave-options-i (-> source-slave options)))
|
||||
(set! (-> self tracking no-follow) (-> source-slave tracking no-follow))
|
||||
(copy-cam-float-seeker (-> self tracking tilt-adjust) (-> source-slave tracking tilt-adjust))
|
||||
(copy-cam-float-seeker (-> self tracking underwater-blend) (-> source-slave tracking underwater-blend))
|
||||
(set! (-> self tracking use-point-of-interest) (-> source-slave tracking use-point-of-interest))
|
||||
(vector-copy! (-> self tracking point-of-interest) (-> source-slave tracking point-of-interest))
|
||||
(copy-cam-float-seeker (-> self tracking point-of-interest-blend) (-> source-slave tracking point-of-interest-blend))
|
||||
(let ((source-position (-> source-slave trans)))
|
||||
(cam-calc-follow! (-> self tracking) source-position #f)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
source-position
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#f))))))
|
||||
(('copy-tracking)
|
||||
(cond
|
||||
((< argc 1)
|
||||
@@ -85,17 +90,17 @@
|
||||
((nonzero? (-> self tracking-status)) #f)
|
||||
(else
|
||||
(set! (-> self tracking-status) (cam-track-status track-at-combiner))
|
||||
(set! source-slave (the-as camera-slave (-> block param 0)))
|
||||
(set! (-> self tracking-options) (the-as cam-slave-options-i (-> source-slave options)))
|
||||
(set! (-> self tracking no-follow) (-> source-slave tracking no-follow))
|
||||
(copy-cam-float-seeker (-> self tracking tilt-adjust) (-> source-slave tracking tilt-adjust))
|
||||
(copy-cam-float-seeker (-> self tracking underwater-blend) (-> source-slave tracking underwater-blend))
|
||||
(vector-copy! (-> self tracking follow-off) (-> source-slave tracking follow-off))
|
||||
(vector-copy! (-> self tracking follow-pt) (-> source-slave tracking follow-pt))
|
||||
(matrix-copy! (-> self tracking inv-mat) (-> source-slave tracking inv-mat))
|
||||
(set! (-> self tracking use-point-of-interest) (-> source-slave tracking use-point-of-interest))
|
||||
(vector-copy! (-> self tracking point-of-interest) (-> source-slave tracking point-of-interest))
|
||||
(copy-cam-float-seeker (-> self tracking point-of-interest-blend) (-> source-slave tracking point-of-interest-blend)))))))
|
||||
(let ((source-slave (the-as camera-slave (-> block param 0))))
|
||||
(set! (-> self tracking-options) (the-as cam-slave-options-i (-> source-slave options)))
|
||||
(set! (-> self tracking no-follow) (-> source-slave tracking no-follow))
|
||||
(copy-cam-float-seeker (-> self tracking tilt-adjust) (-> source-slave tracking tilt-adjust))
|
||||
(copy-cam-float-seeker (-> self tracking underwater-blend) (-> source-slave tracking underwater-blend))
|
||||
(vector-copy! (-> self tracking follow-off) (-> source-slave tracking follow-off))
|
||||
(vector-copy! (-> self tracking follow-pt) (-> source-slave tracking follow-pt))
|
||||
(matrix-copy! (-> self tracking inv-mat) (-> source-slave tracking inv-mat))
|
||||
(set! (-> self tracking use-point-of-interest) (-> source-slave tracking use-point-of-interest))
|
||||
(vector-copy! (-> self tracking point-of-interest) (-> source-slave tracking point-of-interest))
|
||||
(copy-cam-float-seeker (-> self tracking point-of-interest-blend) (-> source-slave tracking point-of-interest-blend))))))))
|
||||
:code
|
||||
(behavior ()
|
||||
(local-vars (output-matrix matrix))
|
||||
@@ -119,176 +124,148 @@
|
||||
(previous-position (new-stack-vector0)))
|
||||
(vector-copy! previous-position (-> self trans))
|
||||
(if source-slave
|
||||
(set! output-matrix
|
||||
(cond
|
||||
(destination-slave
|
||||
;; Position and FOV can be interpolated directly. Rotation is blended as
|
||||
;; an axis-angle below so that the resulting camera basis stays orthonormal.
|
||||
(vector-lerp-clamp! (-> self trans) (-> source-slave 0 trans) (-> destination-slave 0 trans) blend)
|
||||
(set! (-> self fov) (lerp-clamp (-> source-slave 0 fov) (-> destination-slave 0 fov) blend))
|
||||
(set! (-> self dist-from-src) (vector-vector-distance (-> self trans) (-> source-slave 0 trans)))
|
||||
(set! (-> self dist-from-dest) (vector-vector-distance (-> self trans) (-> destination-slave 0 trans)))
|
||||
(set! output-matrix
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-combiner))
|
||||
(cam-calc-follow! (-> self tracking) (-> self trans) #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
(-> self trans)
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(matrix-copy! (-> self inv-camera-rot) (-> self tracking inv-mat)))
|
||||
(else
|
||||
(let ((source-tracker (-> source-slave 0 tracking))
|
||||
(source-position (-> source-slave 0 trans))
|
||||
(destination-tracker (-> destination-slave 0 tracking))
|
||||
(destination-position (-> destination-slave 0 trans)))
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-src))
|
||||
(cam-calc-follow! (-> self tracking) source-position #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
source-position
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(set! source-tracker (-> self tracking))
|
||||
(set! source-position (-> self trans)))
|
||||
((= (-> self tracking-status) (cam-track-status track-at-dst))
|
||||
(cam-calc-follow! (-> self tracking) destination-position #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
destination-position
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(set! destination-tracker (-> self tracking))
|
||||
(set! destination-position (-> self trans))))
|
||||
;; Corresponding rows of two rotation bases differ in directions
|
||||
;; perpendicular to their shared axis of rotation. Cross the two
|
||||
;; strongest row deltas, omitting the row which changed least, to
|
||||
;; recover a stable rotation axis.
|
||||
(let ((rotation-work (new 'stack-no-clear 'matrix)))
|
||||
(dotimes (i 3)
|
||||
(set! (-> rotation-work vector i quad) (the-as uint128 0)))
|
||||
0.0
|
||||
0.0
|
||||
0.0
|
||||
(let ((rotation-axis (new-stack-vector0)))
|
||||
(set! output-matrix
|
||||
(cond
|
||||
(destination-slave
|
||||
(vector-lerp-clamp! (-> self trans) (-> source-slave 0 trans) (-> destination-slave 0 trans) blend)
|
||||
(set! (-> self fov) (lerp-clamp (-> source-slave 0 fov) (-> destination-slave 0 fov) blend))
|
||||
(set! (-> self dist-from-src) (vector-vector-distance (-> self trans) (-> source-slave 0 trans)))
|
||||
(set! (-> self dist-from-dest) (vector-vector-distance (-> self trans) (-> destination-slave 0 trans)))
|
||||
(set! output-matrix
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-combiner))
|
||||
(cam-calc-follow! (-> self tracking) (-> self trans) #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
(-> self trans)
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(matrix-copy! (-> self inv-camera-rot) (-> self tracking inv-mat)))
|
||||
(else
|
||||
(let ((source-tracker (-> source-slave 0 tracking))
|
||||
(source-position (-> source-slave 0 trans))
|
||||
(destination-tracker (-> destination-slave 0 tracking))
|
||||
(destination-position (-> destination-slave 0 trans)))
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-src))
|
||||
(cam-calc-follow! (-> self tracking) source-position #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
source-position
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(set! source-tracker (-> self tracking))
|
||||
(set! source-position (-> self trans)))
|
||||
((= (-> self tracking-status) (cam-track-status track-at-dst))
|
||||
(cam-calc-follow! (-> self tracking) destination-position #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
destination-position
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(set! destination-tracker (-> self tracking))
|
||||
(set! destination-position (-> self trans))))
|
||||
(let ((rotation-work (new 'stack-no-clear 'matrix)))
|
||||
(dotimes (i 3)
|
||||
(set! (-> rotation-work vector i quad) (the-as uint128 0)))
|
||||
0.0
|
||||
(let ((rotation-matrix (new-stack-matrix0)))
|
||||
(vector-! (-> rotation-work vector 0)
|
||||
(the-as vector (-> source-tracker inv-mat))
|
||||
(the-as vector (-> destination-tracker inv-mat)))
|
||||
(vector-! (-> rotation-work vector 1) (-> source-tracker inv-mat vector 1) (-> destination-tracker inv-mat vector 1))
|
||||
(vector-! (-> rotation-work vector 2) (-> source-tracker inv-mat vector 2) (-> destination-tracker inv-mat vector 2))
|
||||
(let ((row-0-delta (vector-length (-> rotation-work vector 0)))
|
||||
(row-1-delta (vector-length (-> rotation-work vector 1)))
|
||||
(row-2-delta (vector-length (-> rotation-work vector 2))))
|
||||
(cond
|
||||
((and (< row-0-delta row-1-delta) (< row-0-delta row-2-delta))
|
||||
(vector-cross! rotation-axis (-> rotation-work vector 1) (-> rotation-work vector 2)))
|
||||
((and (< row-1-delta row-0-delta) (< row-1-delta row-2-delta))
|
||||
(vector-cross! rotation-axis (-> rotation-work vector 0) (-> rotation-work vector 2)))
|
||||
(else (vector-cross! rotation-axis (-> rotation-work vector 0) (-> rotation-work vector 1)))))
|
||||
(vector-normalize! rotation-axis 1.0)
|
||||
;; Choose the source basis row least parallel to the axis,
|
||||
;; then project that row and its destination counterpart into
|
||||
;; the plane normal to the axis. Their planar angle is the
|
||||
;; amount of rotation separating the two camera bases.
|
||||
(let ((row-0-axis-dot (fabs (vector-dot (the-as vector (-> source-tracker inv-mat)) rotation-axis)))
|
||||
(row-1-axis-dot (fabs (vector-dot (-> source-tracker inv-mat vector 1) rotation-axis)))
|
||||
(row-2-axis-dot (fabs (vector-dot (-> source-tracker inv-mat vector 2) rotation-axis))))
|
||||
(cond
|
||||
((and (< row-0-axis-dot row-1-axis-dot) (< row-0-axis-dot row-2-axis-dot))
|
||||
(vector-flatten! (-> rotation-work vector 0) (the-as vector (-> source-tracker inv-mat)) rotation-axis)
|
||||
(vector-flatten! (-> rotation-work vector 1) (the-as vector (-> destination-tracker inv-mat)) rotation-axis))
|
||||
((< row-1-axis-dot row-2-axis-dot)
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> source-tracker inv-mat vector 1) rotation-axis)
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> destination-tracker inv-mat vector 1) rotation-axis))
|
||||
(else
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> source-tracker inv-mat vector 2) rotation-axis)
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> destination-tracker inv-mat vector 2) rotation-axis))))
|
||||
(vector-normalize! (-> rotation-work vector 0) 1.0)
|
||||
(vector-normalize! (-> rotation-work vector 1) 1.0)
|
||||
(vector-cross! (-> rotation-work vector 2) (-> rotation-work vector 0) (-> rotation-work vector 1))
|
||||
;; Orient the otherwise sign-ambiguous axis to agree with the
|
||||
;; direction from the projected source row to destination row.
|
||||
(if (< (vector-dot (-> rotation-work vector 2) rotation-axis) 0.0) (vector-negate! rotation-axis rotation-axis))
|
||||
(let ((rotation-angle (acos (vector-dot (-> rotation-work vector 0) (-> rotation-work vector 1)))))
|
||||
(cond
|
||||
;; A newly activated slave starts a new arc decision, so
|
||||
;; discard both the one-shot marker and the previous flip.
|
||||
((logtest? (-> *camera* master-options) (cam-master-options set-combiner-axis))
|
||||
(logclear! (-> *camera* master-options) (cam-master-options set-combiner-axis flip-combiner))
|
||||
;; Compare the target and destination directions in the
|
||||
;; local horizontal plane. The final test has no body in
|
||||
;; this version and therefore has no observable effect.
|
||||
(when (and (< 8192.0 rotation-angle) (logtest? (-> *camera* master-options) (cam-master-options have-target)))
|
||||
(vector-! (-> rotation-work vector 0) (-> *camera* tpos-curr) source-position)
|
||||
(vector-! (-> rotation-work vector 1) destination-position source-position)
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> rotation-work vector 0) (-> *camera* local-down))
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> rotation-work vector 1) (-> *camera* local-down))
|
||||
(when (and (< 4096.0 (vector-normalize-ret-len! (-> rotation-work vector 0) 1.0))
|
||||
(< 4096.0 (vector-normalize-ret-len! (-> rotation-work vector 1) 1.0)))
|
||||
(vector-cross! (-> rotation-work vector 2) (-> rotation-work vector 1) (-> rotation-work vector 0))
|
||||
(when (< (vector-dot (-> rotation-work vector 2) rotation-axis) -0.01)))))
|
||||
;; For rotations over 90 degrees, keep the chosen axis
|
||||
;; continuous across frames by switching to the equivalent
|
||||
;; complementary axis-angle representation when necessary.
|
||||
((and (< 16384.0 rotation-angle) (< (vector-dot (-> self flip-control-axis) rotation-axis) 0.0))
|
||||
(logxor! (-> *camera* master-options) (cam-master-options flip-combiner))))
|
||||
(vector-copy! (-> self flip-control-axis) rotation-axis)
|
||||
(when (logtest? (-> *camera* master-options) (cam-master-options flip-combiner))
|
||||
(set! rotation-angle (- 65536.0 rotation-angle))
|
||||
(vector-negate! rotation-axis rotation-axis))
|
||||
;; Rotate backward from the destination basis by the portion
|
||||
;; still separating it from the source: the full angle at
|
||||
;; blend 0 and no correction at blend 1.
|
||||
(let ((remaining-angle (* rotation-angle (- 1.0 blend))))
|
||||
(matrix-axis-sin-cos! rotation-matrix rotation-axis (sin remaining-angle) (cos remaining-angle))))
|
||||
(matrix*! (-> self inv-camera-rot) (-> destination-tracker inv-mat) rotation-matrix)))))
|
||||
output-matrix)))
|
||||
;; Do not advance the blend while the outgoing slave is still reaching its
|
||||
;; authored exit point or while the game is paused.
|
||||
(cond
|
||||
((and (< 0.0 (-> *camera* outro-t-step)) (< (-> *camera* outro-t) (-> *camera* outro-exit-value))))
|
||||
((and (< (-> *camera* outro-t-step) 0.0) (< (-> *camera* outro-exit-value) (-> *camera* outro-t))))
|
||||
((paused?))
|
||||
(else (+! (-> self interp-val) (* (-> self interp-step) (-> *display* time-adjust-ratio)))))
|
||||
;; Once the blend reaches its destination, retire the outgoing slave and
|
||||
;; promote the destination into slot 0.
|
||||
(when (>= (-> self interp-val) 1.0)
|
||||
(deactivate (-> *camera* slave 0 0))
|
||||
(set! (-> *camera* slave 0) (-> *camera* slave 1))
|
||||
(set! (-> *camera* slave 1) (the-as (pointer camera-slave) #f))
|
||||
(+! (-> *camera* num-slaves) -1))
|
||||
output-matrix)
|
||||
(else
|
||||
(set! (-> self dist-from-src) 409600.0)
|
||||
(set! (-> self dist-from-dest) 0.0)
|
||||
(vector-copy! (-> self trans) (-> source-slave 0 trans))
|
||||
(set! (-> self fov) (-> source-slave 0 fov))
|
||||
;; Resolve the endpoint-only tracking modes after a transition has left just
|
||||
;; one slave: destination tracking becomes steady combiner tracking, while
|
||||
;; source tracking ends with the retired source.
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-dst))
|
||||
(set! (-> self tracking-status) (cam-track-status track-at-combiner)))
|
||||
((= (-> self tracking-status) (cam-track-status track-at-src))
|
||||
(set! (-> self tracking-status) (cam-track-status use-slave-tracking))
|
||||
0))
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-combiner))
|
||||
(cam-calc-follow! (-> self tracking) (-> self trans) #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
(-> self trans)
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(matrix-copy! (-> self inv-camera-rot) (-> self tracking inv-mat)))
|
||||
(else (matrix-copy! (-> self inv-camera-rot) (-> source-slave 0 tracking inv-mat))))))))
|
||||
0.0
|
||||
0.0
|
||||
(let ((rotation-axis (new-stack-vector0)))
|
||||
0.0
|
||||
(let ((rotation-matrix (new-stack-matrix0)))
|
||||
(vector-! (-> rotation-work vector 0) (-> source-tracker inv-mat vector 0) (-> destination-tracker inv-mat vector 0))
|
||||
(vector-! (-> rotation-work vector 1) (-> source-tracker inv-mat vector 1) (-> destination-tracker inv-mat vector 1))
|
||||
(vector-! (-> rotation-work vector 2) (-> source-tracker inv-mat vector 2) (-> destination-tracker inv-mat vector 2))
|
||||
(let ((row-0-delta (vector-length (-> rotation-work vector 0)))
|
||||
(row-1-delta (vector-length (-> rotation-work vector 1)))
|
||||
(row-2-delta (vector-length (-> rotation-work vector 2))))
|
||||
(cond
|
||||
((and (< row-0-delta row-1-delta) (< row-0-delta row-2-delta))
|
||||
(vector-cross! rotation-axis (-> rotation-work vector 1) (-> rotation-work vector 2)))
|
||||
((and (< row-1-delta row-0-delta) (< row-1-delta row-2-delta))
|
||||
(vector-cross! rotation-axis (-> rotation-work vector 0) (-> rotation-work vector 2)))
|
||||
(else
|
||||
(vector-cross! rotation-axis (-> rotation-work vector 0) (-> rotation-work vector 1)))))
|
||||
(vector-normalize! rotation-axis 1.0)
|
||||
(let ((row-0-axis-dot (fabs (vector-dot (-> source-tracker inv-mat vector 0) rotation-axis)))
|
||||
(row-1-axis-dot (fabs (vector-dot (-> source-tracker inv-mat vector 1) rotation-axis)))
|
||||
(row-2-axis-dot (fabs (vector-dot (-> source-tracker inv-mat vector 2) rotation-axis))))
|
||||
(cond
|
||||
((and (< row-0-axis-dot row-1-axis-dot) (< row-0-axis-dot row-2-axis-dot))
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> source-tracker inv-mat vector 0) rotation-axis)
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> destination-tracker inv-mat vector 0) rotation-axis))
|
||||
((< row-1-axis-dot row-2-axis-dot)
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> source-tracker inv-mat vector 1) rotation-axis)
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> destination-tracker inv-mat vector 1) rotation-axis))
|
||||
(else
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> source-tracker inv-mat vector 2) rotation-axis)
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> destination-tracker inv-mat vector 2) rotation-axis))))
|
||||
(vector-normalize! (-> rotation-work vector 0) 1.0)
|
||||
(vector-normalize! (-> rotation-work vector 1) 1.0)
|
||||
(vector-cross! (-> rotation-work vector 2) (-> rotation-work vector 0) (-> rotation-work vector 1))
|
||||
(if (< (vector-dot (-> rotation-work vector 2) rotation-axis) 0.0)
|
||||
(vector-negate! rotation-axis rotation-axis))
|
||||
(let ((rotation-angle (acos (vector-dot (-> rotation-work vector 0) (-> rotation-work vector 1)))))
|
||||
(cond
|
||||
((logtest? (-> *camera* master-options) (cam-master-options set-combiner-axis))
|
||||
(logclear! (-> *camera* master-options) (cam-master-options set-combiner-axis flip-combiner))
|
||||
(when (and (< 8192.0 rotation-angle) (logtest? (-> *camera* master-options) (cam-master-options have-target)))
|
||||
(vector-! (-> rotation-work vector 0) (-> *camera* tpos-curr) source-position)
|
||||
(vector-! (-> rotation-work vector 1) destination-position source-position)
|
||||
(vector-flatten! (-> rotation-work vector 0) (-> rotation-work vector 0) (-> *camera* local-down))
|
||||
(vector-flatten! (-> rotation-work vector 1) (-> rotation-work vector 1) (-> *camera* local-down))
|
||||
(when (and (< 4096.0 (vector-normalize-ret-len! (-> rotation-work vector 0) 1.0))
|
||||
(< 4096.0 (vector-normalize-ret-len! (-> rotation-work vector 1) 1.0)))
|
||||
(vector-cross! (-> rotation-work vector 2) (-> rotation-work vector 1) (-> rotation-work vector 0))
|
||||
(when (< (vector-dot (-> rotation-work vector 2) rotation-axis) -0.01)))))
|
||||
((and (< 16384.0 rotation-angle) (< (vector-dot (-> self flip-control-axis) rotation-axis) 0.0))
|
||||
(logxor! (-> *camera* master-options) (cam-master-options flip-combiner))))
|
||||
(vector-copy! (-> self flip-control-axis) rotation-axis)
|
||||
(when (logtest? (-> *camera* master-options) (cam-master-options flip-combiner))
|
||||
(set! rotation-angle (- 65536.0 rotation-angle))
|
||||
(vector-negate! rotation-axis rotation-axis))
|
||||
(let ((remaining-angle (* rotation-angle (- 1.0 blend))))
|
||||
(matrix-axis-sin-cos! rotation-matrix rotation-axis (sin remaining-angle) (cos remaining-angle))))
|
||||
(matrix*! (-> self inv-camera-rot) (-> destination-tracker inv-mat) rotation-matrix)))))
|
||||
output-matrix)))
|
||||
(cond
|
||||
((and (< 0.0 (-> *camera* outro-t-step)) (< (-> *camera* outro-t) (-> *camera* outro-exit-value))))
|
||||
((and (< (-> *camera* outro-t-step) 0.0) (< (-> *camera* outro-exit-value) (-> *camera* outro-t))))
|
||||
((paused?))
|
||||
(else
|
||||
(+! (-> self interp-val) (* (-> self interp-step) (-> *display* time-adjust-ratio)))))
|
||||
(when (>= (-> self interp-val) 1.0)
|
||||
(deactivate (-> *camera* slave 0 0))
|
||||
(set! (-> *camera* slave 0) (-> *camera* slave 1))
|
||||
(set! (-> *camera* slave 1) (the-as (pointer camera-slave) #f))
|
||||
(+! (-> *camera* num-slaves) -1))
|
||||
output-matrix)
|
||||
(else
|
||||
(set! (-> self dist-from-src) 409600.0)
|
||||
(set! (-> self dist-from-dest) 0.0)
|
||||
(vector-copy! (-> self trans) (-> source-slave 0 trans))
|
||||
(set! (-> self fov) (-> source-slave 0 fov))
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-dst))
|
||||
(set! (-> self tracking-status) (cam-track-status track-at-combiner)))
|
||||
((= (-> self tracking-status) (cam-track-status track-at-src))
|
||||
(set! (-> self tracking-status) (cam-track-status use-slave-tracking))
|
||||
0))
|
||||
(cond
|
||||
((= (-> self tracking-status) (cam-track-status track-at-combiner))
|
||||
(cam-calc-follow! (-> self tracking) (-> self trans) #t)
|
||||
(slave-set-rotation! (-> self tracking)
|
||||
(-> self trans)
|
||||
(the-as cam-slave-options (-> self tracking-options))
|
||||
(-> self fov)
|
||||
#t)
|
||||
(matrix-copy! (-> self inv-camera-rot) (-> self tracking inv-mat)))
|
||||
(else
|
||||
(matrix-copy! (-> self inv-camera-rot) (-> source-slave 0 tracking inv-mat))))))))
|
||||
(vector-! (-> self velocity) (-> self trans) previous-position)))
|
||||
(if (and *dproc* *debug-segment*)
|
||||
(add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0) 'camera (new 'static 'rgba :b #xff :a #x80)))
|
||||
(add-frame (-> (current-frame) profile-bar 0) 'camera (new 'static 'rgba :b #xff :a #x80)))
|
||||
(suspend))))
|
||||
|
||||
(defbehavior cam-combiner-init camera-combiner ()
|
||||
@@ -298,7 +275,9 @@
|
||||
(set! *camera-combiner* self)
|
||||
(vector-reset! (-> self trans))
|
||||
(matrix-identity! (-> self inv-camera-rot))
|
||||
(if *math-camera* (set! (-> self fov) (-> *math-camera* fov)) (set! (-> self fov) 11650.845))
|
||||
(if *math-camera*
|
||||
(set! (-> self fov) (-> *math-camera* fov))
|
||||
(set! (-> self fov) 11650.845))
|
||||
(set! (-> self interp-val) 0.0)
|
||||
(set! (-> self interp-step) 0.125)
|
||||
(set! (-> self tracking-status) (cam-track-status use-slave-tracking))
|
||||
|
||||
@@ -29,17 +29,6 @@
|
||||
(define-extern slave-los-state->string (function slave-los-state string))
|
||||
(define-extern cam-debug-reset-coll-tri (function none))
|
||||
|
||||
|
||||
; (declare-type clm basic)
|
||||
; (define-extern *clm* clm)
|
||||
; (define-extern *clm-edit* clm)
|
||||
; (define-extern *clm-focalpull-attr* clm)
|
||||
; (define-extern *clm-index-attr* clm)
|
||||
; (define-extern *clm-intro-attr* clm)
|
||||
; (define-extern *clm-spline-attr* clm)
|
||||
; (define-extern *clm-vol-attr* clm)
|
||||
; (define-extern *clm-select* clm)
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
;; Debug-only rolling histories used by the camera plot display. Each color and
|
||||
@@ -51,8 +40,8 @@
|
||||
(define *redline-index* 0)
|
||||
|
||||
(defun float-save-redline ((value float))
|
||||
"Append value to the 400-sample red debug plot, overwriting the oldest sample
|
||||
when the ring wraps."
|
||||
"Append value to the 400-sample red debug
|
||||
plot, overwriting the oldest sample when the ring wraps."
|
||||
(set! (-> *redline-table* *redline-index*) value)
|
||||
(set! *redline-index* (+ *redline-index* 1))
|
||||
(when (>= *redline-index* 400)
|
||||
@@ -61,17 +50,18 @@
|
||||
(none))
|
||||
|
||||
(defun float-lookup-redline ((position float))
|
||||
"Read the red debug plot at position in its wrapped drawing order: zero is
|
||||
newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *redline-index*) 400))) (-> *redline-table* index)))
|
||||
"Read the red debug plot at position in its
|
||||
wrapped drawing order: zero is newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *redline-index*) 400)))
|
||||
(-> *redline-table* index)))
|
||||
|
||||
(define *blueline-table* (the-as (pointer float) (malloc 'debug 1600)))
|
||||
|
||||
(define *blueline-index* 0)
|
||||
|
||||
(defun float-save-blueline ((value float))
|
||||
"Append value to the 400-sample blue debug plot, overwriting the oldest
|
||||
sample when the ring wraps."
|
||||
"Append value to the 400-sample blue debug
|
||||
plot, overwriting the oldest sample when the ring wraps."
|
||||
(set! (-> *blueline-table* *blueline-index*) value)
|
||||
(set! *blueline-index* (+ *blueline-index* 1))
|
||||
(when (>= *blueline-index* 400)
|
||||
@@ -80,17 +70,18 @@
|
||||
(none))
|
||||
|
||||
(defun float-lookup-blueline ((position float))
|
||||
"Read the blue debug plot at position in its wrapped drawing order: zero is
|
||||
newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *blueline-index*) 400))) (-> *blueline-table* index)))
|
||||
"Read the blue debug plot at position in
|
||||
its wrapped drawing order: zero is newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *blueline-index*) 400)))
|
||||
(-> *blueline-table* index)))
|
||||
|
||||
(define *greenline-table* (the-as (pointer float) (malloc 'debug 1600)))
|
||||
|
||||
(define *greenline-index* 0)
|
||||
|
||||
(defun float-save-greenline ((value float))
|
||||
"Append value to the 400-sample green debug plot, overwriting the oldest
|
||||
sample when the ring wraps."
|
||||
"Append value to the 400-sample green debug
|
||||
plot, overwriting the oldest sample when the ring wraps."
|
||||
(set! (-> *greenline-table* *greenline-index*) value)
|
||||
(set! *greenline-index* (+ *greenline-index* 1))
|
||||
(when (>= *greenline-index* 400)
|
||||
@@ -99,17 +90,18 @@
|
||||
(none))
|
||||
|
||||
(defun float-lookup-greenline ((position float))
|
||||
"Read the green debug plot at position in its wrapped drawing order: zero is
|
||||
newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *greenline-index*) 400))) (-> *greenline-table* index)))
|
||||
"Read the green debug plot at position in
|
||||
its wrapped drawing order: zero is newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *greenline-index*) 400)))
|
||||
(-> *greenline-table* index)))
|
||||
|
||||
(define *yellowline-table* (the-as (pointer float) (malloc 'debug 1600)))
|
||||
|
||||
(define *yellowline-index* 0)
|
||||
|
||||
(defun float-save-yellowline ((value float))
|
||||
"Append value to the 400-sample yellow debug plot, overwriting the oldest
|
||||
sample when the ring wraps."
|
||||
"Append value to the 400-sample yellow
|
||||
debug plot, overwriting the oldest sample when the ring wraps."
|
||||
(set! (-> *yellowline-table* *yellowline-index*) value)
|
||||
(set! *yellowline-index* (+ *yellowline-index* 1))
|
||||
(when (>= *yellowline-index* 400)
|
||||
@@ -118,17 +110,18 @@
|
||||
(none))
|
||||
|
||||
(defun float-lookup-yellowline ((position float))
|
||||
"Read the yellow debug plot at position in its wrapped drawing order: zero is
|
||||
newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *yellowline-index*) 400))) (-> *yellowline-table* index)))
|
||||
"Read the yellow debug plot at position
|
||||
in its wrapped drawing order: zero is newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *yellowline-index*) 400)))
|
||||
(-> *yellowline-table* index)))
|
||||
|
||||
(define *timeplot-table* (the-as (pointer float) (malloc 'debug 1600)))
|
||||
|
||||
(define *timeplot-index* 0)
|
||||
|
||||
(defun float-save-timeplot ((value float))
|
||||
"Append value to the 400-sample time debug plot, overwriting the oldest
|
||||
sample when the ring wraps."
|
||||
"Append value to the 400-sample time debug
|
||||
plot, overwriting the oldest sample when the ring wraps."
|
||||
(set! (-> *timeplot-table* *timeplot-index*) value)
|
||||
(set! *timeplot-index* (+ *timeplot-index* 1))
|
||||
(when (>= *timeplot-index* 400)
|
||||
@@ -137,10 +130,9 @@
|
||||
(none))
|
||||
|
||||
(defun float-lookup-timeplot ((position float))
|
||||
"Read the time debug plot at position in its wrapped drawing order: zero is
|
||||
newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *timeplot-index*) 400))) (-> *timeplot-table* index)))
|
||||
"Read the time debug plot at position in
|
||||
its wrapped drawing order: zero is newest and one starts at the oldest sample."
|
||||
(let ((index (mod (+ (the int position) -1 *timeplot-index*) 400)))
|
||||
(-> *timeplot-table* index)))
|
||||
|
||||
(define-perm *cam-layout* symbol #f)
|
||||
|
||||
0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,11 @@
|
||||
(require "engine/camera/camera-h.gc")
|
||||
(require "engine/math/matrix-h.gc")
|
||||
|
||||
;; NOTE - forward declaration needed for cam-interface
|
||||
(define-extern *camera-dummy-vector* vector)
|
||||
|
||||
(define-extern *camera* camera-master) ;; unknown type
|
||||
;; DECOMP BEGINS
|
||||
|
||||
;; Input gates shared by normal and debug camera states. Camera-layout and
|
||||
;; object editors disable these while they own the controls.
|
||||
(define *camera-read-analog* #t)
|
||||
|
||||
(define *camera-read-buttons* #t)
|
||||
|
||||
;; Allow the debug free camera's shoulder controls to move along camera z.
|
||||
@@ -25,13 +21,10 @@
|
||||
;; The persistent processes that coordinate camera selection and blend the
|
||||
;; active camera behaviors.
|
||||
(define-perm *camera* camera-master #f)
|
||||
|
||||
(define-perm *camera-combiner* camera-combiner #f)
|
||||
|
||||
;; Optional drawable followed by the debug orbit camera.
|
||||
(define-perm *camera-orbit-target* (pointer process-drawable) #f)
|
||||
|
||||
(define-extern position-in-front-of-camera! (function vector float float vector))
|
||||
|
||||
;; TODO - forward declaration for weather-part
|
||||
(define-extern matrix-local->world (function symbol symbol matrix))
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
(require "engine/entity/entity-h.gc")
|
||||
(require "engine/math/transformq-h.gc")
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(defun position-in-front-of-camera! ((out vector) (forward-distance float) (up-distance float))
|
||||
"Place out at forward-distance along the camera's
|
||||
forward axis and up-distance along its up axis, measured from the current camera translation."
|
||||
@@ -20,7 +22,9 @@
|
||||
"Return the camera local-to-world rotation. smooth? selects the
|
||||
smoothed inverse-camera matrix; the second argument is retained for the shared interface but is
|
||||
unused."
|
||||
(if smooth? (-> *math-camera* inv-camera-rot-smooth) (-> *math-camera* inv-camera-rot)))
|
||||
(if smooth?
|
||||
(-> *math-camera* inv-camera-rot-smooth)
|
||||
(-> *math-camera* inv-camera-rot)))
|
||||
|
||||
(defun matrix-world->local ()
|
||||
"Return the current world-to-camera rotation matrix."
|
||||
@@ -32,11 +36,13 @@
|
||||
"Return the active camera position. Prefer the combiner output while a
|
||||
camera transition is active, otherwise use the renderer camera, with a zero-vector fallback
|
||||
before camera initialization."
|
||||
(the-as vector
|
||||
(cond
|
||||
(*camera-combiner* (-> *camera-combiner* stack))
|
||||
(*math-camera* (-> *math-camera* trans))
|
||||
(else *camera-dummy-vector*))))
|
||||
(cond
|
||||
(*camera-combiner*
|
||||
(-> *camera-combiner* trans))
|
||||
(*math-camera*
|
||||
(-> *math-camera* trans))
|
||||
(else
|
||||
*camera-dummy-vector*)))
|
||||
|
||||
(defun math-camera-pos ()
|
||||
"Return the renderer's current camera translation."
|
||||
@@ -50,11 +56,9 @@
|
||||
(atan right-z right-x)))
|
||||
|
||||
(defbehavior camera-teleport-to-entity process ((start-entity entity-actor))
|
||||
"Build a unit-scale camera transform from start-entity's
|
||||
orientation and the position stored in the scale vector of its extra transform, then send it to
|
||||
the camera master as an immediate teleport."
|
||||
"Teleport the camera to the entity position."
|
||||
(let ((teleport-transform (new 'stack 'transformq)))
|
||||
(vector-copy! (-> teleport-transform trans) (-> (the-as transform (-> start-entity extra)) scale))
|
||||
(vector-copy! (-> teleport-transform trans) (-> start-entity extra trans))
|
||||
(quaternion-copy! (-> teleport-transform quat) (-> start-entity quat))
|
||||
(vector-identity! (-> teleport-transform scale))
|
||||
(send-event *camera* 'teleport-to-transformq teleport-transform))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,13 +22,14 @@
|
||||
(behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
||||
(case message
|
||||
(('teleport) #f)
|
||||
(else (cam-standard-event-handler proc argc message block))))
|
||||
(else
|
||||
(cam-standard-event-handler proc argc message block))))
|
||||
:enter
|
||||
(behavior ()
|
||||
(when (not (-> self enter-has-run))
|
||||
(set! (-> self pivot-rad) 40960.0)
|
||||
(set! (-> self blend-from-type) (the-as uint 1))
|
||||
(set! (-> self blend-to-type) (the-as uint 1))))
|
||||
(set! (-> self blend-from-type) (camera-blend-to-type slave-controlled))
|
||||
(set! (-> self blend-to-type) (camera-blend-to-type slave-controlled))))
|
||||
:code
|
||||
(behavior ()
|
||||
(loop
|
||||
@@ -52,13 +53,14 @@
|
||||
(+! (-> translation-delta z) (* 2.0 (-> *CAM_POINT_WATCH-bank* speed) left-y-input)))))
|
||||
(let ((forward (new-stack-vector0)))
|
||||
(let ((rotation-matrix (new-stack-matrix0)))
|
||||
(matrix-axis-angle! rotation-matrix (the-as vector (-> self tracking)) (- (-> rotation-delta x)))
|
||||
(matrix-axis-angle! rotation-matrix (-> self tracking inv-mat vector 0) (- (-> rotation-delta x)))
|
||||
(vector-matrix*! forward (-> self tracking inv-mat vector 2) rotation-matrix)
|
||||
(matrix-axis-angle! rotation-matrix (-> *camera* local-down) (- (-> rotation-delta y)))
|
||||
(vector-matrix*! forward forward rotation-matrix))
|
||||
(forward-down->inv-matrix (-> self tracking inv-mat) forward (-> *camera* local-down)))
|
||||
(set! (-> self pivot-rad) (- (-> self pivot-rad) (-> translation-delta z)))
|
||||
(if (< (-> self pivot-rad) 4096.0) (set! (-> self pivot-rad) 4096.0))
|
||||
(if (< (-> self pivot-rad) 4096.0)
|
||||
(set! (-> self pivot-rad) 4096.0))
|
||||
(set-vector! translation-delta 0.0 0.0 (- (-> self pivot-rad)) 1.0)
|
||||
(vector-matrix*! (-> self trans) translation-delta (-> self tracking inv-mat))))
|
||||
(suspend)
|
||||
@@ -276,8 +278,10 @@
|
||||
Preserve the chosen up direction while yawing when one is supplied; otherwise allow unrestricted
|
||||
yaw. Pitch and roll are then applied in camera-local axes before the local translation is rotated
|
||||
into world space. Return false when the controller is invalid or menus own the camera."
|
||||
(if (logtest? (-> *cpad-list* cpads controller-index valid) 128) (return (the-as vector #f)))
|
||||
(if (= *master-mode* 'menu) (return (the-as vector #f)))
|
||||
(if (logtest? (-> *cpad-list* cpads controller-index valid) 128)
|
||||
(return (the-as vector #f)))
|
||||
(if (= *master-mode* 'menu)
|
||||
(return (the-as vector #f)))
|
||||
(let ((move-info (new 'stack 'camera-free-floating-move-info)))
|
||||
(cam-free-floating-input (-> move-info rv) (-> move-info tv) (not up) controller-index)
|
||||
(cond
|
||||
@@ -309,18 +313,20 @@
|
||||
(behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
||||
(case message
|
||||
(('teleport) #f)
|
||||
(else (cam-standard-event-handler proc argc message block))))
|
||||
(else
|
||||
(cam-standard-event-handler proc argc message block))))
|
||||
:enter
|
||||
(behavior ()
|
||||
(when (not (-> self enter-has-run))
|
||||
(set! (-> self blend-from-type) (the-as uint 1))
|
||||
(set! (-> self blend-to-type) (the-as uint 1))
|
||||
(set! (-> self blend-from-type) (camera-blend-to-type slave-controlled))
|
||||
(set! (-> self blend-to-type) (camera-blend-to-type slave-controlled))
|
||||
(send-event *camera-combiner* 'stop-tracking)))
|
||||
:code
|
||||
(behavior ()
|
||||
(loop
|
||||
(let ((up (-> *camera* local-down)))
|
||||
(if (logtest? (-> self options) 8) (set! up (the-as vector #f)))
|
||||
(if (logtest? (-> self options) (cam-slave-options ALLOW_Z_ROT))
|
||||
(set! up (the-as vector #f)))
|
||||
(cam-free-floating-move (-> self tracking inv-mat) (-> self trans) up (the-as int (-> *CAMERA-bank* joypad))))
|
||||
(suspend))))
|
||||
|
||||
@@ -331,12 +337,14 @@
|
||||
(orbit-off vector :inline)
|
||||
(radius-lerp float)))
|
||||
|
||||
|
||||
(deftype CAM_ORBIT-bank (basic)
|
||||
((RADIUS_MAX float)
|
||||
(RADIUS_MIN float)
|
||||
(TARGET_OFF_ADJUST float)
|
||||
(ORBIT_OFF_ADJUST float)))
|
||||
|
||||
|
||||
(define *CAM_ORBIT-bank*
|
||||
(new 'static 'CAM_ORBIT-bank :RADIUS_MAX 61440.0 :RADIUS_MIN 409.6 :TARGET_OFF_ADJUST 81.92 :ORBIT_OFF_ADJUST 81.92))
|
||||
|
||||
@@ -359,23 +367,26 @@
|
||||
(behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
||||
(case message
|
||||
(('teleport) #f)
|
||||
(else (cam-standard-event-handler proc argc message block))))
|
||||
(else
|
||||
(cam-standard-event-handler proc argc message block))))
|
||||
:enter
|
||||
(behavior ()
|
||||
(when (not (-> self enter-has-run))
|
||||
(if (not *camera-orbit-target*) (cam-slave-go cam-free-floating))
|
||||
(if (not *camera-orbit-target*)
|
||||
(cam-slave-go cam-free-floating))
|
||||
(let ((target-to-camera (new-stack-vector0)))
|
||||
(vector-! target-to-camera (-> self trans) (-> *camera-orbit-target* 0 root trans))
|
||||
(set! (-> *camera-orbit-info* rot) (atan (-> target-to-camera x) (-> target-to-camera z))))
|
||||
(set! (-> self blend-from-type) (the-as uint 1))
|
||||
(set! (-> self blend-to-type) (the-as uint 1))))
|
||||
(set! (-> self blend-from-type) (camera-blend-to-type slave-controlled))
|
||||
(set! (-> self blend-to-type) (camera-blend-to-type slave-controlled))))
|
||||
:exit
|
||||
(behavior ()
|
||||
'())
|
||||
:code
|
||||
(behavior ()
|
||||
(loop
|
||||
(if (not *camera-orbit-target*) (cam-slave-go cam-free-floating))
|
||||
(if (not *camera-orbit-target*)
|
||||
(cam-slave-go cam-free-floating))
|
||||
(when *camera-read-analog*
|
||||
(let ((zoom-input (analog-input (the-as int (-> *cpad-list* cpads 0 righty)) 128.0 32.0 110.0 0.05)))
|
||||
(cond
|
||||
@@ -383,20 +394,23 @@
|
||||
(+! (-> *camera-orbit-info* radius-lerp) (* 0.05 (- 1.0 (-> *camera-orbit-info* radius-lerp)))))
|
||||
((< zoom-input (* 0.05 (- (-> *camera-orbit-info* radius-lerp))))
|
||||
(+! (-> *camera-orbit-info* radius-lerp) (* 0.05 (- (-> *camera-orbit-info* radius-lerp)))))
|
||||
(else (+! (-> *camera-orbit-info* radius-lerp) zoom-input))))
|
||||
(else
|
||||
(+! (-> *camera-orbit-info* radius-lerp) zoom-input))))
|
||||
(set! (-> *camera-orbit-info* radius)
|
||||
(lerp (-> *CAM_ORBIT-bank* RADIUS_MIN) (-> *CAM_ORBIT-bank* RADIUS_MAX) (-> *camera-orbit-info* radius-lerp))))
|
||||
(cond
|
||||
((cpad-hold? 0 l2)
|
||||
(if (cpad-hold? 0 l1)
|
||||
(set! (-> *camera-orbit-info* target-off y)
|
||||
(- (-> *camera-orbit-info* target-off y) (-> *CAM_ORBIT-bank* TARGET_OFF_ADJUST))))
|
||||
(if (cpad-hold? 0 r1) (+! (-> *camera-orbit-info* target-off y) (-> *CAM_ORBIT-bank* TARGET_OFF_ADJUST))))
|
||||
(set! (-> *camera-orbit-info* target-off y)
|
||||
(- (-> *camera-orbit-info* target-off y) (-> *CAM_ORBIT-bank* TARGET_OFF_ADJUST))))
|
||||
(if (cpad-hold? 0 r1)
|
||||
(+! (-> *camera-orbit-info* target-off y) (-> *CAM_ORBIT-bank* TARGET_OFF_ADJUST))))
|
||||
(else
|
||||
(if (cpad-hold? 0 l1)
|
||||
(set! (-> *camera-orbit-info* orbit-off y)
|
||||
(- (-> *camera-orbit-info* orbit-off y) (-> *CAM_ORBIT-bank* ORBIT_OFF_ADJUST))))
|
||||
(if (cpad-hold? 0 r1) (+! (-> *camera-orbit-info* orbit-off y) (-> *CAM_ORBIT-bank* ORBIT_OFF_ADJUST)))))
|
||||
(set! (-> *camera-orbit-info* orbit-off y)
|
||||
(- (-> *camera-orbit-info* orbit-off y) (-> *CAM_ORBIT-bank* ORBIT_OFF_ADJUST))))
|
||||
(if (cpad-hold? 0 r1)
|
||||
(+! (-> *camera-orbit-info* orbit-off y) (-> *CAM_ORBIT-bank* ORBIT_OFF_ADJUST)))))
|
||||
(when *camera-read-analog*
|
||||
(let ((orbit-input (analog-input (the-as int (-> *cpad-list* cpads 0 rightx)) 128.0 32.0 110.0 (* 21845.334 (seconds-per-frame)))))
|
||||
(set! (-> *camera-orbit-info* rot) (the float (sar (shl (the int (+ (-> *camera-orbit-info* rot) orbit-input)) 48) 48)))))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
||||
:bitfield #t
|
||||
(allow-z 0))
|
||||
|
||||
;; DECOMP BEGINS
|
||||
(define *external-cam-options* (external-cam-option))
|
||||
|
||||
;; False for the gameplay camera, or the controller/debug mode that directly
|
||||
@@ -23,17 +24,9 @@
|
||||
;; Alternate field of view, position, inverse rotation, and debug target used
|
||||
;; while *camera-look-through-other* is active.
|
||||
(define-perm *camera-other-fov* bfloat (new 'static 'bfloat :data 11650.845))
|
||||
|
||||
(define-perm *camera-other-trans* vector (vector-reset! (new 'global 'vector)))
|
||||
|
||||
(define-perm *camera-other-matrix* matrix (matrix-identity! (new 'global 'matrix)))
|
||||
|
||||
;; Vertical camera impulse shared by the gameplay and alternate-camera paths.
|
||||
(define-perm *camera-smush-control* smush-control (set-zero! (new 'global 'smush-control)))
|
||||
|
||||
(define-perm *camera-other-root* vector (vector-reset! (new 'global 'vector)))
|
||||
|
||||
;; TODO - actually defined in cam-states-dbg
|
||||
(define-extern cam-free-floating-move (function matrix vector vector int vector))
|
||||
|
||||
(define-extern cam-free-floating-input (function vector vector symbol int vector))
|
||||
|
||||
@@ -36,10 +36,7 @@
|
||||
|
||||
(defun set-point ((point vector) (x float) (y float) (z float))
|
||||
"Set point's xyz coordinates and set w to one."
|
||||
(set! (-> point x) x)
|
||||
(set! (-> point y) y)
|
||||
(set! (-> point z) z)
|
||||
(set! (-> point w) 1.0)
|
||||
(set-vector! point x y z 1.0)
|
||||
(none))
|
||||
|
||||
(defun update-view-planes ((camera math-camera) (planes (inline-array plane)) (scale float))
|
||||
@@ -78,8 +75,7 @@
|
||||
(far-bottom-left-ray (new-stack-vector0))
|
||||
(far-bottom-right-ray (new-stack-vector0)))
|
||||
(set! (-> (new 'stack-no-clear 'vector) quad) (the-as uint128 0))
|
||||
(let ((camera-position (new 'stack-no-clear 'vector)))
|
||||
(set! (-> camera-position quad) (the-as uint128 0))
|
||||
(let ((camera-position (new-stack-vector0)))
|
||||
(set! (-> camera-position quad) (-> camera inv-camera-rot vector 3 quad))
|
||||
(vector-! far-top-left-ray (-> frustum yon-top-left) camera-position)
|
||||
(vector-! far-top-right-ray (-> frustum yon-top-right) camera-position)
|
||||
@@ -136,22 +132,26 @@
|
||||
(set! use-adjacent? (logtest? (vis-info-flag using-this-as-only-vis) (-> adjacent-vis flags)))
|
||||
(if (< (-> adjacent-vis length) (-> adjacent-vis from-bsp current-leaf-idx)) (set! use-adjacent? #f)))
|
||||
use-self?))
|
||||
(if (!= (-> active-level all-visible?) 'loading) (set! (-> active-level all-visible?) #f))
|
||||
(if (!= (-> active-level all-visible?) 'loading)
|
||||
(set! (-> active-level all-visible?) #f))
|
||||
(when (update-vis! active-level self-vis (-> self-vis ramdisk) (-> self-vis string-block))
|
||||
;; A successful update makes every other cached string stale.
|
||||
(countdown (i 8)
|
||||
(let ((vis-info (-> active-level vis-info i)))
|
||||
(when vis-info
|
||||
(if (!= vis-info self-vis) (set! (-> vis-info current-vis-string) (the-as uint -1))))))
|
||||
(if (!= vis-info self-vis)
|
||||
(set! (-> vis-info current-vis-string) (the-as uint -1))))))
|
||||
(set! (-> active-level all-visible?) #f)))
|
||||
(use-adjacent?
|
||||
(if (!= (-> active-level all-visible?) 'loading) (set! (-> active-level all-visible?) #f))
|
||||
(if (!= (-> active-level all-visible?) 'loading)
|
||||
(set! (-> active-level all-visible?) #f))
|
||||
(when (update-vis! active-level adjacent-vis (-> adjacent-vis ramdisk) (-> adjacent-vis string-block))
|
||||
;; The adjacent string follows the same cache rules.
|
||||
(countdown (i 8)
|
||||
(let ((vis-info (-> active-level vis-info i)))
|
||||
(when vis-info
|
||||
(if (!= vis-info adjacent-vis) (set! (-> vis-info current-vis-string) (the-as uint -1))))))
|
||||
(if (!= vis-info adjacent-vis)
|
||||
(set! (-> vis-info current-vis-string) (the-as uint -1))))))
|
||||
(set! (-> active-level all-visible?) #f)))
|
||||
;; Keep the old visibility bits while the next string loads
|
||||
;; during play, avoiding an all-visible flash between strings.
|
||||
@@ -176,14 +176,18 @@
|
||||
(controller-index 0))
|
||||
(cond
|
||||
((= mode 'locked) (set! mode #f))
|
||||
((= mode 'pad-1) (set! controller-index 1))
|
||||
((not *camera-combiner*) (set! mode 'pad-0)))
|
||||
((= mode 'pad-1)
|
||||
(set! controller-index 1))
|
||||
((not *camera-combiner*)
|
||||
(set! mode 'pad-0)))
|
||||
(when mode
|
||||
;; Gravity supplies the camera's down direction. Passing #f for up
|
||||
;; allows a fully free orientation, including roll.
|
||||
(let ((up (vector-negate-in-place! (vector-normalize-copy! (new-stack-vector0) (-> *standard-dynamics* gravity) 1.0))))
|
||||
(if (= (vector-length up) 0.0) (set! (-> up y) -1.0))
|
||||
(if (logtest? *external-cam-options* (external-cam-option allow-z)) (set! up (the-as vector #f)))
|
||||
(if (= (vector-length up) 0.0)
|
||||
(set! (-> up y) -1.0))
|
||||
(if (logtest? *external-cam-options* (external-cam-option allow-z))
|
||||
(set! up (the-as vector #f)))
|
||||
(cam-free-floating-move *save-camera-inv-rot* (-> camera trans) up controller-index))))
|
||||
(matrix-copy! (-> *math-camera* inv-camera-rot) *save-camera-inv-rot*)
|
||||
camera)
|
||||
@@ -242,7 +246,8 @@
|
||||
(-> *target* control trans z))
|
||||
(format #t "Dist = ~F~%" (* 0.00024414062 (vector-vector-xz-distance (-> *target* control trans) *start-pos*)))
|
||||
(set! *start-timer* (the-as int #f)))
|
||||
(if (< 179 *timer-value*) (format *stdcon* "~%~%Time = ~D~%" *timer-value*))
|
||||
(if (< 179 *timer-value*)
|
||||
(format *stdcon* "~%~%Time = ~D~%" *timer-value*))
|
||||
(set! *timer-value* (+ *timer-value* 1)))
|
||||
(when (not *start-timer*)
|
||||
(set! *timer-value* 0)
|
||||
@@ -272,13 +277,14 @@
|
||||
(update! *camera-smush-control*)
|
||||
(cond
|
||||
((or (= *master-mode* 'pause) (= *master-mode* 'progress) *progress-process*))
|
||||
((>= *camera-look-through-other* 2) (set! *camera-look-through-other* 1))
|
||||
((and (= *camera-look-through-other* 1) (!= *master-mode* 'menu)) (set! *camera-look-through-other* 0) 0))
|
||||
;; Priority is external control, the alternate/debug camera, the gameplay
|
||||
;; combiner, then the controller fallback. Alternate and gameplay poses
|
||||
;; also refresh the saved external orientation to avoid a jump on entry.
|
||||
((>= *camera-look-through-other* 2)
|
||||
(set! *camera-look-through-other* 1))
|
||||
((and (= *camera-look-through-other* 1) (!= *master-mode* 'menu))
|
||||
(set! *camera-look-through-other* 0)
|
||||
0))
|
||||
(cond
|
||||
(*external-cam-mode* (move-camera-from-pad *math-camera*))
|
||||
(*external-cam-mode*
|
||||
(move-camera-from-pad *math-camera*))
|
||||
((nonzero? *camera-look-through-other*)
|
||||
(set! (-> *math-camera* fov) (-> *camera-other-fov* data))
|
||||
(vector-copy! (-> *math-camera* trans) *camera-other-trans*)
|
||||
@@ -297,14 +303,15 @@
|
||||
;; reduce the mip factor so zoomed views do not choose overly coarse mips;
|
||||
;; wider views are capped at one.
|
||||
(cond
|
||||
(*camera-no-mip-correction* (set! (-> *math-camera* fov-correction-factor) 1.0))
|
||||
(*camera-no-mip-correction*
|
||||
(set! (-> *math-camera* fov-correction-factor) 1.0))
|
||||
(else
|
||||
(let ((mip-fov (fmin 11650.845 (-> *math-camera* fov))))
|
||||
(set! (-> *math-camera* fov-correction-factor) (* 0.00008583069 mip-fov)))))
|
||||
;; Blend from the saved orientation toward the current pose while smooth-t
|
||||
;; decays. Once complete, keep an exact copy of the current orientation.
|
||||
(if (< 0.0 (-> *math-camera* smooth-t))
|
||||
(set! (-> *math-camera* smooth-t) (- (-> *math-camera* smooth-t) (-> *math-camera* smooth-step))))
|
||||
(set! (-> *math-camera* smooth-t) (- (-> *math-camera* smooth-t) (-> *math-camera* smooth-step))))
|
||||
(cond
|
||||
((< 0.0 (-> *math-camera* smooth-t))
|
||||
(let ((smooth-rotation (new-stack-quaternion0)))
|
||||
@@ -317,11 +324,9 @@
|
||||
(else
|
||||
(matrix-copy! (-> *math-camera* inv-camera-rot-smooth) (-> *math-camera* inv-camera-rot))))
|
||||
(if (and (!= *master-mode* 'menu) *display-camera-info*)
|
||||
(format *stdcon* "cam pos ~M ~M ~M~%" (-> *math-camera* trans x) (-> *math-camera* trans y) (-> *math-camera* trans z)))
|
||||
;; Preserve the old view-projection before rebuilding it. A reset instead
|
||||
;; copies the new matrix afterward, suppressing one frame of camera motion.
|
||||
(when (zero? (-> *math-camera* reset))
|
||||
(matrix-copy! (-> *math-camera* prev-camera-temp) (-> *math-camera* camera-temp)))
|
||||
(format *stdcon* "cam pos ~M ~M ~M~%" (-> *math-camera* trans x) (-> *math-camera* trans y) (-> *math-camera* trans z)))
|
||||
(if (zero? (-> *math-camera* reset))
|
||||
(matrix-copy! (-> *math-camera* prev-camera-temp) (-> *math-camera* camera-temp)))
|
||||
(let ((view-projection (-> *math-camera* camera-temp))
|
||||
(view-matrix (-> *math-camera* camera-rot))
|
||||
(inverse-view-matrix (-> *math-camera* inv-camera-rot))
|
||||
@@ -329,10 +334,11 @@
|
||||
;; Rigid inverse translation is -C transformed by the transposed
|
||||
;; orientation. The inverse view keeps C directly in its fourth row.
|
||||
(let ((negative-camera-position (new-stack-vector0)))
|
||||
(set! (-> negative-camera-position x) (- (-> camera-position x)))
|
||||
(set! (-> negative-camera-position y) (- (-> camera-position y)))
|
||||
(set! (-> negative-camera-position z) (- (-> camera-position z)))
|
||||
(set! (-> negative-camera-position w) 1.0)
|
||||
(set-vector! negative-camera-position
|
||||
(- (-> camera-position x))
|
||||
(- (-> camera-position y))
|
||||
(- (-> camera-position z))
|
||||
1.0)
|
||||
(vector-matrix*! negative-camera-position negative-camera-position view-matrix)
|
||||
(set! (-> view-matrix vector 3 quad) (-> negative-camera-position quad)))
|
||||
(matrix*! view-projection view-matrix (-> *math-camera* perspective))
|
||||
@@ -350,7 +356,7 @@
|
||||
(set! (-> *instance-tie-work* hmge-d y) fog-max)
|
||||
(set! (-> *instance-tie-work* hmge-d z) (* 32.0 near-distance))
|
||||
(set! (-> *instance-tie-work* hmge-d w) (* near-distance (-> *math-camera* hmge-scale w)))
|
||||
(let ((hvdf-offset (-> *math-camera* hvdf-off quad))) (set! (-> *instance-tie-work* hvdf-offset quad) hvdf-offset))
|
||||
(vector-copy! (-> *instance-tie-work* hvdf-offset) (-> *math-camera* hvdf-off))
|
||||
(set! (-> *instance-shrub-work* hmge-d x) fog-min)
|
||||
(set! (-> *instance-shrub-work* hmge-d y) fog-max)
|
||||
(set! (-> *instance-shrub-work* hmge-d z) (* 3.0 near-distance))
|
||||
@@ -362,9 +368,7 @@
|
||||
(set! (-> *instance-shrub-work* billboard-const z) fog-min)
|
||||
(set! (-> *instance-shrub-work* billboard-const w) fog-max))
|
||||
(set! (-> *instance-shrub-work* constants w) (the-as float (-> *math-camera* vis-gifs 0 fog0)))
|
||||
(let ((hvdf-offset (-> *math-camera* hvdf-off quad))) (set! (-> *instance-shrub-work* hvdf-offset quad) hvdf-offset))
|
||||
;; The ordinary side planes cull the view frustum. The four-times-wider
|
||||
;; guard planes give TIE and shrub generation room around the visible area.
|
||||
(vector-copy! (-> *instance-shrub-work* hvdf-offset) (-> *math-camera* hvdf-off))
|
||||
(update-view-planes *math-camera* (-> *math-camera* plane) 1.0)
|
||||
(update-view-planes *math-camera* (-> *math-camera* guard-plane) 4.0)
|
||||
(vector-copy! (-> *instance-shrub-work* guard-plane 0) (-> *math-camera* guard-plane 0))
|
||||
@@ -376,5 +380,6 @@
|
||||
(vector-copy! (-> *instance-tie-work* guard-plane 2) (-> *math-camera* guard-plane 2))
|
||||
(vector-copy! (-> *instance-tie-work* guard-plane 3) (-> *math-camera* guard-plane 3))
|
||||
(update-visible *math-camera*)
|
||||
(if (not (paused?)) (update-wind *wind-work* *wind-scales*))
|
||||
(if (not (paused?))
|
||||
(update-wind *wind-work* *wind-scales*))
|
||||
#f)
|
||||
|
||||
@@ -4,35 +4,6 @@
|
||||
(require "engine/math/vector-h.gc")
|
||||
(require "engine/gfx/hw/display-h.gc")
|
||||
|
||||
;; TODO - for cam-layout
|
||||
(define-extern v-slrp2! (function vector vector vector float vector float vector))
|
||||
|
||||
(define-extern v-slrp3! (function vector vector vector vector float vector))
|
||||
|
||||
(declare-type camera-slave process)
|
||||
|
||||
(declare-type camera-master process)
|
||||
|
||||
(declare-type tracking-point structure)
|
||||
|
||||
(declare-type cam-rotation-tracker structure)
|
||||
|
||||
(declare-type camera-combiner process)
|
||||
|
||||
;; TODO - for cam-master
|
||||
;; TODO - for camera
|
||||
(define-extern camera-line-rel-len (function vector vector float vector4w none))
|
||||
|
||||
(define-extern cam-calc-follow! (function cam-rotation-tracker vector symbol vector))
|
||||
|
||||
(define-extern slave-set-rotation! (function cam-rotation-tracker vector float float symbol none))
|
||||
|
||||
;; TODO - for cam-combiner
|
||||
(define-extern paused? (function symbol))
|
||||
|
||||
;; TODO - for cam-start
|
||||
(define-extern cam-master-init (function none :behavior camera-master))
|
||||
|
||||
(defenum cam-slave-options
|
||||
:bitfield #t
|
||||
(BUTT_CAM)
|
||||
@@ -54,6 +25,28 @@
|
||||
(STICKY_ANGLE)
|
||||
(AIR_EXIT))
|
||||
|
||||
(defenum cam-slave-options-i
|
||||
:bitfield #t
|
||||
:type int32
|
||||
(BUTT_CAM)
|
||||
(SAME_SIDE)
|
||||
(MOVE_SPHERICAL)
|
||||
(ALLOW_Z_ROT)
|
||||
(JUMP_PITCHES)
|
||||
(COLLIDE)
|
||||
(FIND_HIDDEN_TARGET)
|
||||
(DRAG)
|
||||
(PLAYER_MOVING_CAMERA)
|
||||
(LINE_OF_SIGHT)
|
||||
(MOVEMENT_BLOCKED)
|
||||
(SHRINK_MAX_ANGLE)
|
||||
(GOTO_GOOD_POINT)
|
||||
(BLOCK_SHIFT_BUTTONS)
|
||||
(BIKE_MODE)
|
||||
(NO_ROTATE)
|
||||
(STICKY_ANGLE)
|
||||
(AIR_EXIT))
|
||||
|
||||
(defenum cam-index-options
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
@@ -67,6 +60,31 @@
|
||||
(ccw 2)
|
||||
(between 3))
|
||||
|
||||
(defenum cam-track-status
|
||||
:type uint64
|
||||
(use-slave-tracking 0)
|
||||
(track-at-combiner 1)
|
||||
(track-at-dst 2)
|
||||
(track-at-src 3))
|
||||
|
||||
|
||||
(defenum camera-blend-to-type
|
||||
:type uint64
|
||||
(direct 0)
|
||||
(slave-controlled 1)
|
||||
(combiner-tracked 2))
|
||||
|
||||
(defenum cam-master-options
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
(ignore-regions 0)
|
||||
(have-target 1)
|
||||
(switch-only-on-ground 2)
|
||||
(set-combiner-axis 3)
|
||||
(flip-combiner 4)
|
||||
(have-ease-to-pos 5)
|
||||
(in-base-region 6))
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
;; Shared gameplay-camera tuning used for collision movement, input response,
|
||||
@@ -147,17 +165,15 @@
|
||||
(advance-used-point! (_type_ tracking-spline-sampler) none)
|
||||
(prune-most-collinear! (_type_) none)
|
||||
(prune-shallow-points! (_type_ float) none)
|
||||
(add-point! (_type_ vector float float symbol) int)
|
||||
(add-point! (_type_ vector meters meters symbol) int)
|
||||
(accumulate-sample! (_type_ float vector tracking-spline-sampler) vector)
|
||||
(sample-point! (_type_ float vector tracking-spline-sampler) vector)
|
||||
(apply-trail-correction! (_type_ vector int) none)
|
||||
(follow-update! (_type_ vector float float) vector)
|
||||
(trim-to-length! (_type_ float) none)
|
||||
(follow-update! (_type_ vector meters meters) vector)
|
||||
(trim-to-length! (_type_ meters) none)
|
||||
(debug-draw (_type_) none)))
|
||||
|
||||
;; A scalar spring-like seeker. value accelerates toward target and its speed
|
||||
;; is limited by both max-vel and max-partial times the remaining distance, so
|
||||
;; it eases down automatically near the target.
|
||||
|
||||
(deftype cam-float-seeker (structure)
|
||||
((target float)
|
||||
(value float)
|
||||
@@ -173,8 +189,8 @@
|
||||
(jump-to-target! (_type_ float) float)))
|
||||
|
||||
(defmethod init-cam-float-seeker ((this cam-float-seeker) (initial-value float) (accel float) (max-vel float) (max-partial float))
|
||||
"Initialize target and value to initial-value, clear velocity, and set the
|
||||
acceleration and two speed limits."
|
||||
"Initialize target and value to initial-value, clear
|
||||
velocity, and set the acceleration and two speed limits."
|
||||
(set! (-> this target) initial-value)
|
||||
(set! (-> this value) initial-value)
|
||||
(set! (-> this vel) 0.0)
|
||||
@@ -196,24 +212,27 @@
|
||||
(none))
|
||||
|
||||
(defmethod update! ((this cam-float-seeker) (offset float))
|
||||
"Advance one frame toward target plus offset. Acceleration and displacement
|
||||
use the display time ratio, and velocity is capped by the smaller of max-vel
|
||||
and max-partial times the remaining distance."
|
||||
"Advance one frame toward target plus offset. Acceleration and
|
||||
displacement use the display time ratio, and velocity is capped by the
|
||||
smaller of max-vel and max-partial times the remaining distance."
|
||||
0.0
|
||||
0.0
|
||||
(let* ((pos-error (- (+ (-> this target) offset) (-> this value)))
|
||||
(partial-velocity-limit (* (-> this max-partial) (fabs pos-error))))
|
||||
(let ((daccel (* pos-error (* (-> this accel) (-> *display* time-adjust-ratio))))) (+! (-> this vel) daccel))
|
||||
(let ((daccel (* pos-error (* (-> this accel) (-> *display* time-adjust-ratio)))))
|
||||
(+! (-> this vel) daccel))
|
||||
(let ((abs-vel (fabs (-> this vel)))
|
||||
(abs-vel-limit (fmin partial-velocity-limit (-> this max-vel))))
|
||||
(if (< abs-vel-limit abs-vel) (set! (-> this vel) (* (-> this vel) (/ abs-vel-limit abs-vel))))))
|
||||
(let ((dpos (* (-> this vel) (-> *display* time-adjust-ratio)))) (+! (-> this value) dpos))
|
||||
(if (< abs-vel-limit abs-vel)
|
||||
(set! (-> this vel) (* (-> this vel) (/ abs-vel-limit abs-vel))))))
|
||||
(let ((dpos (* (-> this vel) (-> *display* time-adjust-ratio))))
|
||||
(+! (-> this value) dpos))
|
||||
0
|
||||
(none))
|
||||
|
||||
(defmethod jump-to-target! ((this cam-float-seeker) (offset float))
|
||||
"Set value directly to target plus offset, clear velocity, and return the new
|
||||
value."
|
||||
"Set value directly to target plus offset, clear velocity,
|
||||
and return the new value."
|
||||
(set! (-> this value) (+ (-> this target) offset))
|
||||
(set! (-> this vel) 0.0))
|
||||
|
||||
@@ -231,11 +250,15 @@
|
||||
(update! (_type_ vector) none)))
|
||||
|
||||
(defmethod init! ((this cam-vector-seeker) (initial-value vector) (accel float) (max-vel float) (max-partial float))
|
||||
"Initialize target and value from initial-value, or zero when it is false;
|
||||
clear velocity and set the acceleration and speed limits."
|
||||
"Initialize target and value from initial-value, or zero when it is
|
||||
false; clear velocity and set the acceleration and speed limits."
|
||||
(cond
|
||||
(initial-value (vector-copy! (-> this target) initial-value) (vector-copy! (-> this value) initial-value))
|
||||
(else (vector-reset! (-> this target)) (vector-reset! (-> this value))))
|
||||
(initial-value
|
||||
(vector-copy! (-> this target) initial-value)
|
||||
(vector-copy! (-> this value) initial-value))
|
||||
(else
|
||||
(vector-reset! (-> this target))
|
||||
(vector-reset! (-> this value))))
|
||||
(vector-reset! (-> this vel))
|
||||
(set! (-> this accel) accel)
|
||||
(set! (-> this max-vel) max-vel)
|
||||
@@ -244,19 +267,23 @@
|
||||
(none))
|
||||
|
||||
(defmethod update! ((this cam-vector-seeker) (offset vector))
|
||||
"Advance one frame toward target plus optional offset, limiting velocity
|
||||
magnitude by max-vel and the remaining-distance limit."
|
||||
"Advance one frame toward target plus optional offset, limiting
|
||||
velocity magnitude by max-vel and the remaining-distance limit."
|
||||
(let ((error (new 'stack-no-clear 'vector)))
|
||||
0.0
|
||||
(cond
|
||||
(offset (vector+! error (-> this target) offset) (vector-! error error (-> this value)))
|
||||
(else (vector-! error (-> this target) (-> this value))))
|
||||
(offset
|
||||
(vector+! error (-> this target) offset)
|
||||
(vector-! error error (-> this value)))
|
||||
(else
|
||||
(vector-! error (-> this target) (-> this value))))
|
||||
(let ((partial-velocity-limit (* (-> this max-partial) (vector-length error))))
|
||||
(vector-float*! error error (* (-> this accel) (-> *display* time-adjust-ratio)))
|
||||
(vector+! (-> this vel) (-> this vel) error)
|
||||
(let ((velocity (vector-length (-> this vel)))
|
||||
(velocity-limit (fmin partial-velocity-limit (-> this max-vel))))
|
||||
(if (< velocity-limit velocity) (vector-float*! (-> this vel) (-> this vel) (/ velocity-limit velocity)))))
|
||||
(if (< velocity-limit velocity)
|
||||
(vector-float*! (-> this vel) (-> this vel) (/ velocity-limit velocity)))))
|
||||
(vector-float*! error (-> this vel) (-> *display* time-adjust-ratio))
|
||||
(vector+! (-> this value) (-> this value) error))
|
||||
0
|
||||
@@ -286,8 +313,8 @@
|
||||
(dist-from-dest float)
|
||||
(flip-control-axis vector :inline)
|
||||
(velocity vector :inline)
|
||||
(tracking-status uint64)
|
||||
(tracking-options int32)
|
||||
(tracking-status cam-track-status)
|
||||
(tracking-options cam-slave-options-i)
|
||||
(tracking cam-rotation-tracker :inline))
|
||||
(:states
|
||||
cam-combiner-active))
|
||||
@@ -296,9 +323,9 @@
|
||||
;; slave alive together while the combiner transitions between them.
|
||||
(deftype camera-slave (process)
|
||||
((trans vector :inline)
|
||||
(fov float)
|
||||
(fov0 float)
|
||||
(fov1 float)
|
||||
(fov degrees)
|
||||
(fov0 degrees)
|
||||
(fov1 degrees)
|
||||
(fov-index cam-index :inline)
|
||||
(tracking cam-rotation-tracker :inline)
|
||||
(view-off-param float)
|
||||
@@ -314,8 +341,8 @@
|
||||
(circular-follow vector :inline)
|
||||
(max-angle-offset float)
|
||||
(max-angle-curr float)
|
||||
(options uint32)
|
||||
(cam-entity entity)
|
||||
(options cam-slave-options)
|
||||
(cam-entity entity-camera)
|
||||
(velocity vector :inline)
|
||||
(desired-pos vector :inline)
|
||||
(time-dist-too-far uint32)
|
||||
@@ -338,8 +365,8 @@
|
||||
(spline-follow-dist float)
|
||||
(change-event-from (pointer process-drawable))
|
||||
(enter-has-run symbol)
|
||||
(blend-from-type uint64)
|
||||
(blend-to-type uint64)
|
||||
(blend-from-type camera-blend-to-type)
|
||||
(blend-to-type camera-blend-to-type)
|
||||
(have-phony-joystick basic)
|
||||
(phony-joystick-x float)
|
||||
(phony-joystick-y float)
|
||||
@@ -378,10 +405,10 @@
|
||||
;; active slaves, target transforms and tracking trail, and transition state;
|
||||
;; the combiner produces the final rendered camera.
|
||||
(deftype camera-master (process)
|
||||
((master-options uint32)
|
||||
((master-options cam-master-options)
|
||||
(num-slaves int32)
|
||||
(slave (pointer camera-slave) 2)
|
||||
(slave-options uint32)
|
||||
(slave-options cam-slave-options)
|
||||
(view-off-param-save float)
|
||||
(changer uint32)
|
||||
(cam-entity entity)
|
||||
|
||||
@@ -16,15 +16,18 @@
|
||||
|
||||
(define *cam-res-string* (new 'global 'string 64 (the-as string #f)))
|
||||
|
||||
(defun cam-slave-get-vector-with-offset ((source-actor entity-actor) (out vector) (prop-name symbol))
|
||||
(defun cam-slave-get-vector-with-offset ((source-actor entity-camera) (out vector) (prop-name symbol))
|
||||
"Read property from actor, using its live
|
||||
translation or rotation for the matching property names, add an optional property-offset vector,
|
||||
and write out. Return true when a value was available."
|
||||
(local-vars (base-value structure))
|
||||
(cond
|
||||
((= prop-name 'trans) (set! base-value (-> source-actor trans)))
|
||||
((= prop-name 'rot) (set! base-value (-> source-actor quat)))
|
||||
(else (set! base-value (res-lump-struct source-actor prop-name structure))))
|
||||
((= prop-name 'trans)
|
||||
(set! base-value (-> source-actor trans)))
|
||||
((= prop-name 'rot)
|
||||
(set! base-value (-> source-actor quat)))
|
||||
(else
|
||||
(set! base-value (res-lump-struct source-actor prop-name structure))))
|
||||
(let ((struct-getter (method-of-type res-lump get-property-struct)))
|
||||
(format (clear *res-key-string*) "~S~S" prop-name '-offset)
|
||||
(let ((offset-value (struct-getter source-actor
|
||||
@@ -35,8 +38,12 @@
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*)))
|
||||
(cond
|
||||
((and base-value offset-value) (vector+! out (the-as vector base-value) (the-as vector offset-value)) #t)
|
||||
((the-as vector base-value) (vector-copy! out (the-as vector base-value)) #t)
|
||||
((and base-value offset-value)
|
||||
(vector+! out (the-as vector base-value) (the-as vector offset-value))
|
||||
#t)
|
||||
((the-as vector base-value)
|
||||
(set! (-> out quad) (-> (the-as vector base-value) quad))
|
||||
#t)
|
||||
(else #f)))))
|
||||
|
||||
(defun cam-slave-get-flags ((source-entity entity) (prop-name symbol))
|
||||
@@ -62,7 +69,7 @@
|
||||
(the-as uint128 0)
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*)))
|
||||
(logclear (logior base-flags set-flags) clear-flags)))))
|
||||
(the-as cam-slave-options (logclear (logior base-flags set-flags) clear-flags))))))
|
||||
|
||||
(defun cam-slave-get-float ((source-entity entity) (prop-name symbol) (default-value float))
|
||||
"Read property from entity with default-value, add the
|
||||
@@ -92,7 +99,9 @@
|
||||
0.0
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*)))
|
||||
(if (= base-fov 0.0) (+ 11650.845 fov-offset) (+ base-fov fov-offset)))))
|
||||
(if (= base-fov 0.0)
|
||||
(+ 11650.845 fov-offset)
|
||||
(+ base-fov fov-offset)))))
|
||||
|
||||
(defun cam-slave-get-intro-step ((source-entity entity))
|
||||
"Read intro-time plus intro-time-offset and return the
|
||||
@@ -108,7 +117,9 @@
|
||||
0.0
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*))))
|
||||
(if (>= 0.0 duration) 0.004166667 (/ 0.016666668 duration)))))
|
||||
(if (>= 0.0 duration)
|
||||
0.004166667
|
||||
(/ 0.016666668 duration)))))
|
||||
|
||||
(defun cam-slave-get-interp-time ((source-entity entity))
|
||||
"Read interpTime plus interpTime-offset from entity and
|
||||
@@ -124,12 +135,12 @@
|
||||
0.0
|
||||
(the-as (pointer res-tag) #f)
|
||||
*res-static-buf*))))
|
||||
(if (>= 0.001 duration) (set! duration 0.0))
|
||||
(if (>= 0.001 duration)
|
||||
(set! duration 0.0))
|
||||
duration)))
|
||||
|
||||
(defun cam-slave-get-rot ((source-actor entity-actor) (out-matrix matrix))
|
||||
"Convert actor's rotation to out-matrix after composing an optional
|
||||
rot-offset quaternion."
|
||||
(defun cam-slave-get-rot ((source-actor entity-camera) (out-matrix matrix))
|
||||
"Get the rotation of the entity, including optional rotation offset."
|
||||
(let ((struct-getter (method-of-type res-lump get-property-struct))
|
||||
(source-copy source-actor))
|
||||
(format (clear *res-key-string*) "~S~S" 'rot '-offset)
|
||||
@@ -146,7 +157,8 @@
|
||||
(quaternion*! combined-rotation (the-as quaternion rotation-offset) (-> source-actor quat))
|
||||
(quaternion-normalize! combined-rotation)
|
||||
(quaternion->matrix out-matrix combined-rotation)))
|
||||
(else (quaternion->matrix out-matrix (-> source-actor quat))))))
|
||||
(else
|
||||
(quaternion->matrix out-matrix (-> source-actor quat))))))
|
||||
out-matrix)
|
||||
|
||||
(defun cam-state-from-entity ((source-entity entity))
|
||||
@@ -156,12 +168,16 @@
|
||||
(let ((camera-path (new 'stack 'curve)))
|
||||
(the-as state
|
||||
(cond
|
||||
((not source-entity) (the-as (state camera-slave) #f))
|
||||
((not source-entity)
|
||||
(the-as (state camera-slave) #f))
|
||||
((res-lump-struct source-entity 'pivot structure) cam-circular)
|
||||
((res-lump-struct source-entity 'align structure) cam-standoff-read-entity)
|
||||
((res-lump-struct source-entity 'align structure)
|
||||
cam-standoff-read-entity)
|
||||
((get-curve-data! source-entity camera-path 'campath 'campath-k -1000000000.0) cam-spline)
|
||||
((< 0.0 (cam-slave-get-float source-entity 'stringMaxLength 0.0)) *camera-base-mode*)
|
||||
(else cam-fixed-read-entity)))))
|
||||
((< 0.0 (cam-slave-get-float source-entity 'stringMaxLength 0.0))
|
||||
*camera-base-mode*)
|
||||
(else
|
||||
cam-fixed-read-entity)))))
|
||||
|
||||
(defun parameter-ease-none ((value object))
|
||||
"Return value unchanged."
|
||||
@@ -181,8 +197,10 @@
|
||||
((>= t 1.0) 1.0)
|
||||
((>= 0.0 t) 0.0)
|
||||
((>= 0.25 t) (/ t 2))
|
||||
((>= t 0.75) (- 1.0 (* 0.5 (- 1.0 t))))
|
||||
(else (+ 0.125 (* 1.5 (+ -0.25 t))))))
|
||||
((>= t 0.75)
|
||||
(- 1.0 (* 0.5 (- 1.0 t))))
|
||||
(else
|
||||
(+ 0.125 (* 1.5 (+ -0.25 t))))))
|
||||
|
||||
(defun parameter-ease-sqrt-clamp ((t float))
|
||||
"Clamp t to 0..1 and apply the symmetric square-root
|
||||
@@ -190,8 +208,10 @@
|
||||
(cond
|
||||
((>= t 1.0) 1.0)
|
||||
((>= 0.0 t) 0.0)
|
||||
((>= 0.5 t) (* 0.5 (- 1.0 (sqrtf (- 1.0 (* 2.0 t))))))
|
||||
(else (* 0.5 (+ 1.0 (sqrtf (+ -1.0 (* 2.0 t))))))))
|
||||
((>= 0.5 t)
|
||||
(* 0.5 (- 1.0 (sqrtf (- 1.0 (* 2.0 t))))))
|
||||
(else
|
||||
(* 0.5 (+ 1.0 (sqrtf (+ -1.0 (* 2.0 t))))))))
|
||||
|
||||
(defun fourth-power ((x float))
|
||||
"Return x to the fourth power."
|
||||
@@ -207,8 +227,10 @@
|
||||
(cond
|
||||
((>= t 1.0) 1.0)
|
||||
((>= 0.0 t) 0.0)
|
||||
((>= 0.5 t) (* 0.5 (square (* 2.0 t))))
|
||||
(else (- 1.0 (* 0.5 (square (* 2.0 (- 1.0 t))))))))
|
||||
((>= 0.5 t)
|
||||
(* 0.5 (square (* 2.0 t))))
|
||||
(else
|
||||
(- 1.0 (* 0.5 (square (* 2.0 (- 1.0 t))))))))
|
||||
|
||||
(defun parameter-ease-sin-clamp ((t float))
|
||||
"Clamp t to 0..1 and apply a half-cosine ease with zero
|
||||
@@ -216,7 +238,8 @@
|
||||
(cond
|
||||
((>= t 1.0) 1.0)
|
||||
((>= 0.0 t) 0.0)
|
||||
(else (+ 0.5 (* 0.5 (sin (* 182.04445 (+ -90.0 (* 180.0 t)))))))))
|
||||
(else
|
||||
(+ 0.5 (* 0.5 (sin (* 182.04445 (+ -90.0 (* 180.0 t)))))))))
|
||||
|
||||
(defmethod setup-from-entity! ((this cam-index) (prop-name symbol) (source-entity entity) (cam-pos vector) (fallback-curve curve))
|
||||
"Read the two endpoint vectors from entity data or
|
||||
@@ -314,7 +337,11 @@
|
||||
(set! (-> this sample-len) 0.0)
|
||||
(set! (-> this used-count) 1)
|
||||
(vector-copy! (-> this old-position) start-pos)
|
||||
(let ((i 1)) (while (!= i 31) (set! (-> this point i next) (+ i 1)) (+! i 1)) (set! (-> this point i next) -134250495))
|
||||
(let ((i 1))
|
||||
(while (!= i 31)
|
||||
(set! (-> this point i next) (+ i 1))
|
||||
(+! i 1))
|
||||
(set! (-> this point i next) -134250495))
|
||||
0
|
||||
(none))
|
||||
|
||||
@@ -350,7 +377,8 @@
|
||||
(set! (-> this partial-point) (-> sampler partial-pt))
|
||||
(when (= (-> this next-to-last-point) cur-pt)
|
||||
(set! (-> this summed-len) (-> this point cur-pt tp-length))
|
||||
(if (= (-> sampler cur-pt) (-> this end-point)) (set! (-> this partial-point) 0.99999)))
|
||||
(if (= (-> sampler cur-pt) (-> this end-point))
|
||||
(set! (-> this partial-point) 0.99999)))
|
||||
(when (!= (-> sampler cur-pt) cur-pt)
|
||||
(while (and (!= (-> this point cur-pt next) (-> sampler cur-pt)) (!= (-> this point cur-pt next) (-> this next-to-last-point)))
|
||||
(set! (-> this summed-len) (- (-> this summed-len) (-> this point cur-pt tp-length)))
|
||||
@@ -364,7 +392,9 @@
|
||||
(set! (-> this free-point) (-> this used-point))
|
||||
(set! (-> this used-point) (-> sampler cur-pt))
|
||||
(cond
|
||||
((= (-> sampler cur-pt) (-> this end-point)) (set! (-> this partial-point) 0.0) (set! (-> this summed-len) 0.0))
|
||||
((= (-> sampler cur-pt) (-> this end-point))
|
||||
(set! (-> this partial-point) 0.0)
|
||||
(set! (-> this summed-len) 0.0))
|
||||
((= (-> sampler cur-pt) (-> this next-to-last-point))
|
||||
(set! (-> this summed-len) (-> this point (-> this next-to-last-point) tp-length))))))
|
||||
0
|
||||
@@ -379,9 +409,9 @@
|
||||
(set! (-> sampler partial-pt) (-> this partial-point))
|
||||
(sample-point! this (-> this sample-len) (-> sample-pos position) sampler))
|
||||
(if (or (= (-> sampler cur-pt) (-> this end-point))
|
||||
(= (-> sampler cur-pt) (-> this next-to-last-point))
|
||||
(= (-> this point (-> sampler cur-pt) next) (-> this next-to-last-point)))
|
||||
(set! (-> sampler cur-pt) (-> this used-point)))
|
||||
(= (-> sampler cur-pt) (-> this next-to-last-point))
|
||||
(= (-> this point (-> sampler cur-pt) next) (-> this next-to-last-point)))
|
||||
(set! (-> sampler cur-pt) (-> this used-point)))
|
||||
(let ((cur-pt (-> this point (-> sampler cur-pt) next)))
|
||||
(when (!= cur-pt -134250495)
|
||||
(let ((next-pt (-> this point cur-pt next))
|
||||
@@ -396,7 +426,8 @@
|
||||
(set! best-pt cur-pt)))
|
||||
(set! cur-pt next-pt)
|
||||
(set! next-pt (-> this point cur-pt next)))
|
||||
(if (< -2.0 best-dot) (delete-point! this best-pt))))))
|
||||
(if (< -2.0 best-dot)
|
||||
(delete-point! this best-pt))))))
|
||||
0
|
||||
(none))
|
||||
|
||||
@@ -419,17 +450,17 @@
|
||||
(= (-> this point next-pt next) (-> this end-point))
|
||||
(= (-> this point next-pt next) (-> this next-to-last-point))))
|
||||
(if (< (* (-> this point cur-pt tp-length)
|
||||
(+ 1.0
|
||||
(vector-dot (the-as vector (+ (the-as uint (-> this point 0 direction)) (* 48 cur-pt)))
|
||||
(the-as vector (+ (the-as uint (the-as vector (-> this point 0 direction))) (* 48 next-pt))))))
|
||||
budget)
|
||||
(delete-point! this cur-pt)
|
||||
(set! cur-pt next-pt))
|
||||
(+ 1.0
|
||||
(vector-dot (the-as vector (+ (the-as uint (-> this point 0 direction)) (* 48 cur-pt)))
|
||||
(the-as vector (+ (the-as uint (the-as vector (-> this point 0 direction))) (* 48 next-pt))))))
|
||||
budget)
|
||||
(delete-point! this cur-pt)
|
||||
(set! cur-pt next-pt))
|
||||
(set! next-pt (-> this point cur-pt next)))))))
|
||||
0
|
||||
(none))
|
||||
|
||||
(defmethod add-point! ((this tracking-spline) (new-pos vector) (min-dist float) (prune-budget float) (can-prune symbol))
|
||||
(defmethod add-point! ((this tracking-spline) (new-pos vector) (min-dist meters) (prune-budget meters) (can-prune symbol))
|
||||
"Append new-pos when it is at least min-dist from the tail,
|
||||
optionally pruning the trail to obtain a free slot."
|
||||
(let ((free-pt (-> this free-point))
|
||||
@@ -444,7 +475,8 @@
|
||||
(prune-most-collinear! this)
|
||||
(set! free-pt (-> this free-point)))
|
||||
(cond
|
||||
((= free-pt -134250495) (format 0 "ERROR <GMJ>: pos spline overflow~%"))
|
||||
((= free-pt -134250495)
|
||||
(format 0 "ERROR <GMJ>: pos spline overflow~%"))
|
||||
(else
|
||||
(+! (-> this summed-len) (-> this point tail-pt tp-length))
|
||||
(set! (-> this free-point) (-> this point free-pt next))
|
||||
@@ -454,7 +486,8 @@
|
||||
(set! (-> this point free-pt next) -134250495)
|
||||
(vector-copy! (-> this point free-pt position) new-pos)
|
||||
(+! (-> this used-count) 1)
|
||||
(if (< 0.0 prune-budget) (prune-shallow-points! this prune-budget)))))
|
||||
(if (< 0.0 prune-budget)
|
||||
(prune-shallow-points! this prune-budget)))))
|
||||
0)
|
||||
|
||||
(defmethod accumulate-sample! ((this tracking-spline) (arc-len float) (out-pos vector) (sampler tracking-spline-sampler))
|
||||
@@ -496,9 +529,9 @@
|
||||
out-pos)
|
||||
|
||||
(defmethod apply-trail-correction! ((this tracking-spline) (move vector) (stop-pt int))
|
||||
"Bias move along the changes in trail direction before
|
||||
stop-pt. The correction is strongest on short, curved trails and fades as the recorded path
|
||||
becomes straighter."
|
||||
"Bias move along the changes in trail direction
|
||||
before stop-pt. The correction is strongest on short, curved trails and
|
||||
fades as the recorded path becomes straighter."
|
||||
(let ((trail-dir (new 'stack-no-clear 'vector)))
|
||||
(vector-! trail-dir (-> this point (-> this used-point) position) (-> this point (-> this end-point) position))
|
||||
(let* ((chord-len (vector-length trail-dir))
|
||||
@@ -510,7 +543,9 @@
|
||||
((< (-> *CAMERA-bank* min-detectable-velocity) (-> this summed-len))
|
||||
(vector-float*! trail-dir trail-dir (/ 1.0 chord-len))
|
||||
(/ chord-len (-> this summed-len)))
|
||||
(else (vector-reset! trail-dir) 0.0)))
|
||||
(else
|
||||
(vector-reset! trail-dir)
|
||||
0.0)))
|
||||
(straightness-bias (+ -0.2 chord-to-arc))
|
||||
(straightness-scale (* 2.0 straightness-bias))
|
||||
(alignment-weight (fmin 1.0 (fmax 0.05 straightness-scale)))
|
||||
@@ -527,16 +562,17 @@
|
||||
(let ((forward-dot (vector-dot seg-dir trail-dir)))
|
||||
(cond
|
||||
((>= 0.0 forward-dot))
|
||||
(else (set! correction (* correction (fmax 0.0 (- 0.75 (fabs (* alignment-weight forward-dot)))))))))
|
||||
(else
|
||||
(set! correction (* correction (fmax 0.0 (- 0.75 (fabs (* alignment-weight forward-dot)))))))))
|
||||
(cond
|
||||
((< correction 0.0)
|
||||
(if (and *debug-segment* *display-camera-marks*)
|
||||
(camera-line-rel-len (-> this point next-pt position)
|
||||
seg-dir
|
||||
(* -40.96 correction)
|
||||
(-> (new 'static 'inline-array qword 1 (new 'static 'qword :data (new 'static 'array uint32 4 #xff #xff #x0 #x80)))
|
||||
0
|
||||
vector4w)))
|
||||
(camera-line-rel-len (-> this point next-pt position)
|
||||
seg-dir
|
||||
(* -40.96 correction)
|
||||
(-> (new 'static 'inline-array qword 1 (new 'static 'qword :data (new 'static 'array uint32 4 #xff #xff #x0 #x80)))
|
||||
0
|
||||
vector4w)))
|
||||
(vector--float*! move move seg-dir correction))
|
||||
((and *debug-segment* *display-camera-marks*)
|
||||
(camera-line-rel-len (-> this point next-pt position)
|
||||
@@ -549,10 +585,11 @@
|
||||
0
|
||||
(none))
|
||||
|
||||
(defmethod follow-update! ((this tracking-spline) (pos vector) (accel float) (max-speed float))
|
||||
(defmethod follow-update! ((this tracking-spline) (pos vector) (accel meters) (max-speed meters))
|
||||
"Advance the trail follower toward pos using accel and
|
||||
max-speed. Average 64 evenly spaced samples over the adaptive sample window, apply the
|
||||
trail-direction correction, and return the smoothed position."
|
||||
max-speed. Average 64 evenly spaced samples over the adaptive sample
|
||||
window, apply the trail-direction correction, and return the smoothed
|
||||
position."
|
||||
(let ((cur-pt (-> this used-point))
|
||||
(partial (-> this partial-point)))
|
||||
(let ((trail-len (-> this summed-len)))
|
||||
@@ -587,7 +624,7 @@
|
||||
(vector-copy! (-> this old-position) pos)
|
||||
pos)
|
||||
|
||||
(defmethod trim-to-length! ((this tracking-spline) (max-len float))
|
||||
(defmethod trim-to-length! ((this tracking-spline) (max-len meters))
|
||||
"Drop the oldest trail segments until its live length is
|
||||
no greater than max-len."
|
||||
(when (< max-len (-> this summed-len))
|
||||
@@ -611,7 +648,8 @@
|
||||
(+! live-count 1)
|
||||
(set! cur-pt (-> this point cur-pt next)))
|
||||
(when (!= live-count (-> this used-count))
|
||||
(if *debug-segment* (format 0 "ERROR<GMJ>: tracking spline used count ~D actual ~D~%" (-> this used-count) live-count))
|
||||
(if *debug-segment*
|
||||
(format 0 "ERROR<GMJ>: tracking spline used count ~D actual ~D~%" (-> this used-count) live-count))
|
||||
(set! (-> this used-count) live-count))
|
||||
(let ((free-pt (-> this free-point))
|
||||
(free-count 0))
|
||||
@@ -620,7 +658,7 @@
|
||||
(set! free-pt (-> this point free-pt next)))
|
||||
(when (!= free-count (- 32 (-> this used-count)))
|
||||
(if *debug-segment*
|
||||
(format 0 "ERROR<GMJ>: tracking spline free count ~D actual ~D~%" (- 32 (-> this used-count)) free-count))
|
||||
(format 0 "ERROR<GMJ>: tracking spline free count ~D actual ~D~%" (- 32 (-> this used-count)) free-count))
|
||||
(set! (-> this free-point) -134250495)
|
||||
(dotimes (i 32)
|
||||
(when (not (logtest? live-mask 1))
|
||||
@@ -639,14 +677,14 @@
|
||||
(set! (-> self options) (-> *camera* slave-options))
|
||||
(set! (-> self change-event-from) (the-as (pointer process-drawable) (-> *camera* changer))))
|
||||
(else
|
||||
(set! (-> self options) (the-as uint 0))
|
||||
(set! (-> self options) (cam-slave-options))
|
||||
(set! (-> self change-event-from) (the-as (pointer process-drawable) #f))))
|
||||
(cond
|
||||
(*camera-combiner*
|
||||
(vector-copy! (-> self trans) (-> *camera-combiner* trans))
|
||||
(matrix-copy! (-> self tracking inv-mat) (-> *camera-combiner* inv-camera-rot))
|
||||
(when *camera-init-mat*
|
||||
(matrix-copy! (-> self tracking inv-mat) *camera-init-mat*))
|
||||
(if *camera-init-mat*
|
||||
(matrix-copy! (-> self tracking inv-mat) *camera-init-mat*))
|
||||
(set! (-> self fov) (-> *camera-combiner* fov))
|
||||
(vector-copy! (-> self velocity) (-> *camera-combiner* velocity)))
|
||||
(else
|
||||
@@ -676,7 +714,9 @@
|
||||
"Reinitialize the camera slave and immediately enter next-state."
|
||||
(with-pp
|
||||
(cam-slave-init-vars)
|
||||
(let ((enter-fn (the-as (function object) enter-state))) (set! (-> pp next-state) next-state) (enter-fn))
|
||||
(let ((enter-fn (the-as (function object) enter-state)))
|
||||
(set! (-> pp next-state) next-state)
|
||||
(enter-fn))
|
||||
0
|
||||
(none)))
|
||||
|
||||
@@ -686,13 +726,15 @@
|
||||
initial-state current."
|
||||
(stack-size-set! (-> self main-thread) 512)
|
||||
(change-to-last-brother self)
|
||||
(if (and (nonzero? camera-slave-debug) *debug-segment*) (add-connection *debug-engine* self camera-slave-debug self #f #f))
|
||||
(if (and (nonzero? camera-slave-debug) *debug-segment*)
|
||||
(add-connection *debug-engine* self camera-slave-debug self #f #f))
|
||||
(cam-slave-init-vars)
|
||||
(let ((voicebox-state 'cam-voicebox)
|
||||
(call-arg (the-as basic (-> initial-state name))))
|
||||
(cond
|
||||
((= (the-as symbol call-arg) voicebox-state))
|
||||
(camera-entity (set! (-> self cam-entity) camera-entity))
|
||||
(camera-entity
|
||||
(set! (-> self cam-entity) (the-as entity-camera camera-entity)))
|
||||
(else
|
||||
(let ((activation-event (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> activation-event from) self)
|
||||
@@ -703,7 +745,8 @@
|
||||
(set! call-arg *camera*)
|
||||
(send-event-fn (the-as camera-master call-arg) activation-event)))))
|
||||
(let ((state-enter-fn (the-as (function object object) (-> initial-state enter))))
|
||||
(if state-enter-fn (state-enter-fn (the-as symbol call-arg))))
|
||||
(if state-enter-fn
|
||||
(state-enter-fn (the-as symbol call-arg))))
|
||||
(set! (-> self enter-has-run) #t)
|
||||
(set! (-> self event-hook) (-> initial-state event))
|
||||
(let ((enter-state-fn (the-as (function object object) enter-state)))
|
||||
@@ -725,7 +768,8 @@
|
||||
(let ((next-state (the-as object (-> message param 0))))
|
||||
(cam-slave-init-vars)
|
||||
(let ((state-enter-fn (the-as (function object) (-> (the-as state next-state) enter))))
|
||||
(if state-enter-fn (state-enter-fn)))
|
||||
(if state-enter-fn
|
||||
(state-enter-fn)))
|
||||
(set! (-> self enter-has-run) #t)
|
||||
(set! (-> self event-hook) (-> (the-as state next-state) event))
|
||||
(when (= event-type 'change-state)
|
||||
@@ -736,12 +780,14 @@
|
||||
(cond
|
||||
((-> message param 0)
|
||||
(set! (-> self tracking use-point-of-interest) #t)
|
||||
(vector-copy! (-> self tracking point-of-interest) (the-as vector (-> message param 0)))
|
||||
(set! (-> self tracking point-of-interest quad) (-> (the-as vector (-> message param 0)) quad))
|
||||
(set! (-> self tracking point-of-interest-blend target) 1.0))
|
||||
(else (set! (-> self tracking use-point-of-interest) #f) (set! (-> self tracking point-of-interest-blend target) 0.0))))
|
||||
(else
|
||||
(set! (-> self tracking use-point-of-interest) #f)
|
||||
(set! (-> self tracking point-of-interest-blend target) 0.0))))
|
||||
(('teleport)
|
||||
(cam-calc-follow! (-> self tracking) (-> self trans) #f)
|
||||
(slave-set-rotation! (-> self tracking) (-> self trans) (the-as float (-> self options)) (-> self fov) #f))))
|
||||
(slave-set-rotation! (-> self tracking) (-> self trans) (-> self options) (-> self fov) #f))))
|
||||
|
||||
(defbehavior cam-curve-pos camera-slave ((pos vector) (tangent vector) (path curve) (use-follow-point? symbol))
|
||||
"Add the active intro and camera-path offsets to pos. When tangent is
|
||||
@@ -750,10 +796,12 @@
|
||||
(let ((curve-offset (new-stack-vector0)))
|
||||
0.0
|
||||
(let ((tangent-sample (new-stack-vector0)))
|
||||
(if tangent (set! (-> tangent w) 0.0))
|
||||
(if tangent
|
||||
(set! (-> tangent w) 0.0))
|
||||
(when (< (-> self intro-t) 1.0)
|
||||
(+! (-> self intro-t) (* (-> self intro-t-step) (-> *display* time-adjust-ratio)))
|
||||
(if (< 1.0 (-> self intro-t)) (set! (-> self intro-t) 1.0))
|
||||
(if (< 1.0 (-> self intro-t))
|
||||
(set! (-> self intro-t) 1.0))
|
||||
(curve-get-pos! curve-offset (parameter-ease-sin-clamp (-> self intro-t)) (-> self intro-curve))
|
||||
(vector+! curve-offset curve-offset (-> self intro-offset))
|
||||
(vector+! pos pos curve-offset)
|
||||
@@ -773,8 +821,8 @@
|
||||
((not (-> self spline-exists)))
|
||||
((= (-> self spline-follow-dist) 0.0)
|
||||
(let ((spline-t (if use-follow-point?
|
||||
(point->parameter (-> self index) (-> self tracking follow-pt))
|
||||
(point->parameter (-> self index) (-> *camera* tpos-curr-adj)))))
|
||||
(point->parameter (-> self index) (-> self tracking follow-pt))
|
||||
(point->parameter (-> self index) (-> *camera* tpos-curr-adj)))))
|
||||
(curve-get-pos! curve-offset spline-t (-> self spline-curve)))
|
||||
(vector+! curve-offset curve-offset (-> self spline-offset))
|
||||
(vector+! pos pos curve-offset))
|
||||
@@ -782,8 +830,8 @@
|
||||
(let ((reference-pos (new 'stack-no-clear 'vector)))
|
||||
(curve-length (-> self spline-curve))
|
||||
(if use-follow-point?
|
||||
(vector-copy! reference-pos (-> self tracking follow-pt))
|
||||
(vector-copy! reference-pos (-> *camera* tpos-curr-adj)))
|
||||
(vector-copy! reference-pos (-> self tracking follow-pt))
|
||||
(vector-copy! reference-pos (-> *camera* tpos-curr-adj)))
|
||||
(set! (-> self spline-tt)
|
||||
(curve-closest-point (-> self spline-curve) reference-pos (-> self spline-tt) 1024.0 10 (-> self spline-follow-dist))))
|
||||
(curve-get-pos! curve-offset (-> self spline-tt) (-> self spline-curve))
|
||||
@@ -806,9 +854,13 @@
|
||||
(set! (-> self intro-t) 0.0)
|
||||
(set! (-> self intro-t-step) (cam-slave-get-intro-step (-> self cam-entity)))
|
||||
(set! (-> self outro-exit-value) (cam-slave-get-float (-> self cam-entity) 'intro-exitValue 0.0))
|
||||
(if (= (-> self outro-exit-value) 0.0) (set! (-> self outro-exit-value) 0.5)))
|
||||
(else (set! (-> self intro-t) 1.0) (set! (-> self intro-t-step) 0.0)))
|
||||
(if (nonzero? (-> *camera* no-intro)) (set! (-> self intro-t) 1.0))
|
||||
(if (= (-> self outro-exit-value) 0.0)
|
||||
(set! (-> self outro-exit-value) 0.5)))
|
||||
(else
|
||||
(set! (-> self intro-t) 1.0)
|
||||
(set! (-> self intro-t-step) 0.0)))
|
||||
(if (nonzero? (-> *camera* no-intro))
|
||||
(set! (-> self intro-t) 1.0))
|
||||
0
|
||||
(none))
|
||||
|
||||
@@ -851,10 +903,11 @@
|
||||
(view-facing-angle (acos (vector-dot target-from-camera-flat target-facing-flat)))
|
||||
(clamped-angle (fmax 1820.4445 view-facing-angle)))
|
||||
(if (< clamped-angle 8192.0)
|
||||
(vector-float*! desired-offset
|
||||
desired-offset
|
||||
(+ lead-scale
|
||||
(* (/ (- 1.0 lead-scale) (- 1.0 (cos 32768.0))) (+ (- (cos 32768.0)) (cos (* 5.142857 (- 8192.0 clamped-angle)))))))))
|
||||
(vector-float*! desired-offset
|
||||
desired-offset
|
||||
(+ lead-scale
|
||||
(* (/ (- 1.0 lead-scale) (- 1.0 (cos (degrees 180))))
|
||||
(+ (- (cos (degrees 180))) (cos (* 5.142857 (- 8192.0 clamped-angle)))))))))
|
||||
(cond
|
||||
((< (-> *camera* ease-t) 1.0))
|
||||
((< (-> tracker follow-blend) 1.0)
|
||||
@@ -863,7 +916,8 @@
|
||||
(vector-float*! desired-offset desired-offset blend-factor))
|
||||
(+! (-> tracker follow-blend) (/ (-> *display* time-adjust-ratio) 60))
|
||||
(vector+! (-> tracker follow-off) (-> tracker follow-off) desired-offset))
|
||||
(else (vector-copy! (-> tracker follow-off) desired-offset))))
|
||||
(else
|
||||
(vector-copy! (-> tracker follow-off) desired-offset))))
|
||||
(vector+! (-> tracker follow-pt) (-> *camera* tpos-curr-adj) (-> tracker follow-off))
|
||||
(vector--float*! (-> tracker follow-pt)
|
||||
(-> tracker follow-pt)
|
||||
@@ -874,7 +928,8 @@
|
||||
(let ((normal-offset (new-stack-vector0)))
|
||||
(set! (-> tracker follow-blend) 0.0)
|
||||
(cond
|
||||
((-> tracker no-follow) (vector-reset! normal-offset))
|
||||
((-> tracker no-follow)
|
||||
(vector-reset! normal-offset))
|
||||
(else
|
||||
(vector-! normal-offset (-> *camera* tpos-curr-adj) camera-pos)
|
||||
(vector-normalize! normal-offset 1.0)
|
||||
@@ -892,8 +947,8 @@
|
||||
(distance-weight (fmax 0.0 distance-upper)))
|
||||
(vector-float*! normal-offset (-> *camera* tgt-rot-mat vector 2) (* (lerp 2048.0 8192.0 distance-weight) behind-weight))))))
|
||||
(if smooth?
|
||||
(vector-seek-3d-smooth! (-> tracker follow-off) normal-offset (* 20480.0 (seconds-per-frame)) 0.05)
|
||||
(set! (-> tracker follow-off quad) (-> normal-offset quad))))
|
||||
(vector-seek-3d-smooth! (-> tracker follow-off) normal-offset (* 20480.0 (seconds-per-frame)) 0.05)
|
||||
(vector-copy! (-> tracker follow-off) normal-offset)))
|
||||
(vector+! (-> tracker follow-pt) (-> *camera* tpos-curr-adj) (-> tracker follow-off))
|
||||
(vector--float*! (-> tracker follow-pt) (-> tracker follow-pt) (-> *camera* local-down) (-> *camera* target-height))))
|
||||
(-> tracker follow-pt))
|
||||
@@ -912,7 +967,8 @@
|
||||
(when (< up-dot 0.99999)
|
||||
(vector-cross! desired-up (-> camera-matrix vector 1) desired-up)
|
||||
(let ((signed-sine (vector-length desired-up)))
|
||||
(if (< 0.0 (vector-dot desired-up (-> camera-matrix vector 2))) (set! signed-sine (- signed-sine)))
|
||||
(if (< 0.0 (vector-dot desired-up (-> camera-matrix vector 2)))
|
||||
(set! signed-sine (- signed-sine)))
|
||||
(matrix-axis-sin-cos! roll-correction (-> camera-matrix vector 2) signed-sine up-dot))
|
||||
(matrix*! camera-matrix camera-matrix roll-correction)))))
|
||||
camera-matrix)
|
||||
@@ -927,33 +983,43 @@
|
||||
adjusted quaternion step. The step grows with aim-vector distance; options-bits bit 2 selects
|
||||
full three-dimensional rather than local-down-flattened distance."
|
||||
(let ((distance-work (new-stack-vector0))
|
||||
(current-rotation (new-stack-quaternion0)))
|
||||
(let ((target-rotation (new-stack-quaternion0))
|
||||
(delta-rotation (new-stack-quaternion0)))
|
||||
0.0
|
||||
(let* ((aim-distance (cond
|
||||
((logtest? (the-as int options-bits) 4) (vector-length aim-vector))
|
||||
(else (vector-flatten! distance-work aim-vector (-> *camera* local-down)) (vector-length distance-work))))
|
||||
(distance-weight (* 0.00048828125 (+ -1024.0 aim-distance))))
|
||||
(cond
|
||||
((< distance-weight 0.0) (set! distance-weight 0.0))
|
||||
((< 1.0 distance-weight) (set! distance-weight 1.0)))
|
||||
(let ((turn-step (* 364.0889 (-> *display* time-adjust-ratio) distance-weight)))
|
||||
(matrix->quaternion current-rotation current-matrix)
|
||||
(matrix->quaternion target-rotation target-matrix)
|
||||
(quaternion-conjugate! delta-rotation current-rotation)
|
||||
(quaternion*! delta-rotation delta-rotation target-rotation)
|
||||
(quaternion-normalize! delta-rotation)
|
||||
(if (< (-> delta-rotation w) 0.0) (quaternion-negate! delta-rotation delta-rotation))
|
||||
(let ((turn-angle (acos (-> delta-rotation w))))
|
||||
(if (< (* (/ (-> *display* time-adjust-ratio) 4) turn-angle) turn-step)
|
||||
(set! turn-step (* (/ (-> *display* time-adjust-ratio) 4) turn-angle)))
|
||||
(cond
|
||||
((< (-> delta-rotation w) 0.9999999)
|
||||
(quaternion-float*! delta-rotation delta-rotation (/ (sin turn-step) (sin turn-angle)))
|
||||
(set! (-> delta-rotation w) (cos turn-step)))
|
||||
(else (quaternion-identity! delta-rotation))))))
|
||||
(quaternion*! current-rotation current-rotation delta-rotation))
|
||||
(current-rotation (new 'stack-no-clear 'quaternion)))
|
||||
(vector-zero! (-> current-rotation vec))
|
||||
(let ((target-rotation (new 'stack-no-clear 'quaternion)))
|
||||
(vector-zero! (-> target-rotation vec))
|
||||
(let ((delta-rotation (new 'stack-no-clear 'quaternion)))
|
||||
(vector-zero! (-> delta-rotation vec))
|
||||
0.0
|
||||
(let* ((aim-distance (cond
|
||||
((logtest? (the-as int options-bits) 4)
|
||||
(vector-length aim-vector))
|
||||
(else
|
||||
(vector-flatten! distance-work aim-vector (-> *camera* local-down))
|
||||
(vector-length distance-work))))
|
||||
(distance-weight (* 0.00048828125 (+ -1024.0 aim-distance))))
|
||||
(cond
|
||||
((< distance-weight 0.0)
|
||||
(set! distance-weight 0.0))
|
||||
((< 1.0 distance-weight)
|
||||
(set! distance-weight 1.0)))
|
||||
(let ((turn-step (* 364.0889 (-> *display* time-adjust-ratio) distance-weight)))
|
||||
(matrix->quaternion current-rotation current-matrix)
|
||||
(matrix->quaternion target-rotation target-matrix)
|
||||
(quaternion-conjugate! delta-rotation current-rotation)
|
||||
(quaternion*! delta-rotation delta-rotation target-rotation)
|
||||
(quaternion-normalize! delta-rotation)
|
||||
(if (< (-> delta-rotation w) 0.0)
|
||||
(quaternion-negate! delta-rotation delta-rotation))
|
||||
(let ((turn-angle (acos (-> delta-rotation w))))
|
||||
(if (< (* (/ (-> *display* time-adjust-ratio) 4) turn-angle) turn-step)
|
||||
(set! turn-step (* (/ (-> *display* time-adjust-ratio) 4) turn-angle)))
|
||||
(cond
|
||||
((< (-> delta-rotation w) 0.9999999)
|
||||
(quaternion-float*! delta-rotation delta-rotation (/ (sin turn-step) (sin turn-angle)))
|
||||
(set! (-> delta-rotation w) (cos turn-step)))
|
||||
(else
|
||||
(quaternion-identity! delta-rotation))))))
|
||||
(quaternion*! current-rotation current-rotation delta-rotation)))
|
||||
(quaternion-normalize! current-rotation)
|
||||
(quaternion->matrix current-matrix current-rotation)))
|
||||
|
||||
@@ -986,7 +1052,8 @@
|
||||
(let ((right-axis-base (-> camera-matrix vector))
|
||||
(horizontal-scale (* 0.8 (tan (/ fov 2)))))
|
||||
(.lvf vf1 (&-> right-axis-base 0 quad))
|
||||
(let ((horizontal-scale-bits horizontal-scale)) (.mov vf2 horizontal-scale-bits)))
|
||||
(let ((horizontal-scale-bits horizontal-scale))
|
||||
(.mov vf2 horizontal-scale-bits)))
|
||||
(.add.x.vf.w vf1 vf0 vf0)
|
||||
(.mul.x.vf.xyz vf1 vf1 vf2)
|
||||
(.svf (&-> horizontal-edge quad) vf1))
|
||||
@@ -995,7 +1062,7 @@
|
||||
(let ((horizontal-edge-dot (vector-dot frustum-edge (-> camera-matrix vector 0))))
|
||||
(when (< horizontal-edge-dot (fabs horizontal-target-dot))
|
||||
(if (< horizontal-target-dot 0.0)
|
||||
(vector--float*! frustum-edge frustum-edge (-> camera-matrix vector 0) (* 2.0 horizontal-edge-dot)))
|
||||
(vector--float*! frustum-edge frustum-edge (-> camera-matrix vector 0) (* 2.0 horizontal-edge-dot)))
|
||||
(matrix-from-two-vectors! correction-matrix frustum-edge target-dir)
|
||||
(vector-matrix*! (-> camera-matrix vector 2) (-> camera-matrix vector 2) correction-matrix)
|
||||
(vector-cross! (-> camera-matrix vector 0) (-> camera-matrix vector 1) (-> camera-matrix vector 2)))))
|
||||
@@ -1009,7 +1076,8 @@
|
||||
(let ((up-axis (-> camera-matrix vector 1))
|
||||
(vertical-scale (* 0.525 (tan (/ fov 2)))))
|
||||
(.lvf vf1 (&-> up-axis quad))
|
||||
(let ((vertical-scale-bits vertical-scale)) (.mov vf2 vertical-scale-bits)))
|
||||
(let ((vertical-scale-bits vertical-scale))
|
||||
(.mov vf2 vertical-scale-bits)))
|
||||
(.add.x.vf.w vf1 vf0 vf0)
|
||||
(.mul.x.vf.xyz vf1 vf1 vf2)
|
||||
(.svf (&-> vertical-edge quad) vf1))
|
||||
@@ -1035,23 +1103,21 @@
|
||||
(set! rotate-up? #f))
|
||||
((< vertical-dot-limit 0.0)
|
||||
(let ((opposite-head-dot (- (vector-dot frustum-edge target-dir))))
|
||||
(if (< opposite-head-dot vertical-dot-limit) (set! vertical-dot-limit opposite-head-dot)))))))
|
||||
(if (< opposite-head-dot vertical-dot-limit)
|
||||
(set! vertical-dot-limit opposite-head-dot)))))))
|
||||
(let ((correction-angle (if rotate-up? (- (acos vertical-dot-limit)) (acos vertical-dot-limit))))
|
||||
(matrix-axis-angle! correction-matrix (-> camera-matrix vector 0) correction-angle))))
|
||||
(vector-matrix*! (-> camera-matrix vector 2) (-> camera-matrix vector 2) correction-matrix))
|
||||
(vector-cross! (-> camera-matrix vector 1) (-> camera-matrix vector 2) (-> camera-matrix vector 0))))
|
||||
|
||||
(defun slave-set-rotation! ((tracker cam-rotation-tracker) (camera-pos vector) (options-bits float) (fov float) (smooth? symbol))
|
||||
;; ERROR: Unsupported inline assembly instruction kind - [mula.s f0, f3]
|
||||
;; ERROR: Unsupported inline assembly instruction kind - [madda.s f1, f4]
|
||||
;; ERROR: Unsupported inline assembly instruction kind - [madd.s f0, f2, f5]
|
||||
(defun slave-set-rotation! ((tracker cam-rotation-tracker) (camera-pos vector) (options-bits cam-slave-options) (fov float) (smooth? symbol))
|
||||
"Build tracker's inverse camera rotation from its follow point,
|
||||
optional point of interest and tilt; keep the target in frame, optionally blend toward the new
|
||||
orientation, and remove roll. options-bits is a raw cam-slave-options word carried in a float."
|
||||
;; Start from the follow point and blend toward a point of interest without
|
||||
;; changing the aim-vector length. The tilt guard leaves 15 degrees of room
|
||||
;; before either vertical pole so the pitch adjustment cannot flip the view.
|
||||
;; Underwater framing narrows the effective field of view as far as one
|
||||
;; quarter, then the safe-frame correction, optional orientation blend, and
|
||||
;; final roll removal produce the inverse camera rotation.
|
||||
(local-vars (forward-down-dot float) (tilt-matrix matrix))
|
||||
orientation, and remove roll."
|
||||
(local-vars (output-matrix matrix) (forward-down-dot float))
|
||||
(rlet ((vf0 :class vf)
|
||||
(vf4 :class vf)
|
||||
(vf5 :class vf)
|
||||
@@ -1069,46 +1135,52 @@
|
||||
(vector-! point-of-interest-vector (-> tracker point-of-interest) camera-pos)
|
||||
(vector-normalize! point-of-interest-vector (* aim-distance (-> tracker point-of-interest-blend value)))
|
||||
(let ((blended-aim-out aim-vector))
|
||||
(let ((base-aim aim-vector)) (.mov.vf.w vf6 vf0) (.lvf vf4 (&-> base-aim quad)))
|
||||
(let ((base-aim aim-vector))
|
||||
(.mov.vf.w vf6 vf0)
|
||||
(.lvf vf4 (&-> base-aim quad)))
|
||||
(.lvf vf5 (&-> point-of-interest-vector quad))
|
||||
(.add.vf.xyz vf6 vf4 vf5)
|
||||
(.svf (&-> blended-aim-out quad) vf6))
|
||||
(vector-normalize! aim-vector aim-distance))))
|
||||
(else (vector-! aim-vector (-> tracker follow-pt) camera-pos)))
|
||||
(else
|
||||
(vector-! aim-vector (-> tracker follow-pt) camera-pos)))
|
||||
(forward-down->inv-matrix target-matrix aim-vector (-> *camera* local-down))
|
||||
(when (!= tilt-angle 0.0)
|
||||
0.0
|
||||
0.0
|
||||
(set! tilt-matrix (new 'stack-no-clear 'matrix))
|
||||
(let ((aim-direction (new 'stack-no-clear 'vector)))
|
||||
(vector-normalize-copy! aim-direction aim-vector 1.0)
|
||||
(let* ((down-axis (-> *camera* local-down))) (set! forward-down-dot (vector-dot aim-direction down-axis))))
|
||||
(let* ((down-dot forward-down-dot)
|
||||
(vertical-angle (acos (fabs down-dot))))
|
||||
(cond
|
||||
((< 0.0 tilt-angle)
|
||||
(set! tilt-angle
|
||||
(if (< 0.0 down-dot)
|
||||
(fmin tilt-angle (fmax 0.0 (+ -2730.6667 vertical-angle)))
|
||||
(fmin tilt-angle (fmax 0.0 (- 32768.0 (+ 2730.6667 vertical-angle)))))))
|
||||
((< tilt-angle 0.0)
|
||||
(set! tilt-angle
|
||||
(if (< 0.0 down-dot)
|
||||
(fmax tilt-angle (- (fmax 0.0 (- 32768.0 (+ 2730.6667 vertical-angle)))))
|
||||
(fmax tilt-angle (- (fmax 0.0 (+ -2730.6667 vertical-angle)))))))))
|
||||
(matrix-rotate-x! tilt-matrix tilt-angle)
|
||||
(matrix*! target-matrix tilt-matrix target-matrix)))
|
||||
(let ((tilt-matrix (new 'stack-no-clear 'matrix)))
|
||||
(let ((aim-direction (new 'stack-no-clear 'vector)))
|
||||
(vector-normalize-copy! aim-direction aim-vector 1.0)
|
||||
(let* ((down-axis (-> *camera* local-down)))
|
||||
(set! forward-down-dot (vector-dot aim-direction down-axis))))
|
||||
(let* ((down-dot forward-down-dot)
|
||||
(vertical-angle (acos (fabs down-dot))))
|
||||
(cond
|
||||
((< 0.0 tilt-angle)
|
||||
(set! tilt-angle
|
||||
(if (< 0.0 down-dot)
|
||||
(fmin tilt-angle (fmax 0.0 (+ -2730.6667 vertical-angle)))
|
||||
(fmin tilt-angle (fmax 0.0 (- 32768.0 (+ 2730.6667 vertical-angle)))))))
|
||||
((< tilt-angle 0.0)
|
||||
(set! tilt-angle
|
||||
(if (< 0.0 down-dot)
|
||||
(fmax tilt-angle (- (fmax 0.0 (- 32768.0 (+ 2730.6667 vertical-angle)))))
|
||||
(fmax tilt-angle (- (fmax 0.0 (+ -2730.6667 vertical-angle)))))))))
|
||||
(matrix-rotate-x! tilt-matrix tilt-angle)
|
||||
(matrix*! target-matrix tilt-matrix target-matrix))))
|
||||
(if (and (= (-> *camera* under-water) 2) *target* (!= (-> *target* next-state name) 'target-swim-up))
|
||||
(set! (-> tracker underwater-blend target) 1.0)
|
||||
(set! (-> tracker underwater-blend target) 0.0))
|
||||
(set! (-> tracker underwater-blend target) 1.0)
|
||||
(set! (-> tracker underwater-blend target) 0.0))
|
||||
(vector-into-frustum-nosmooth! target-matrix camera-pos (lerp-clamp fov (/ fov 4) (-> tracker underwater-blend value)))
|
||||
(cond
|
||||
(smooth? (slave-matrix-blend-2 (-> tracker inv-mat) options-bits aim-vector target-matrix))
|
||||
(else
|
||||
(matrix-copy! (-> tracker inv-mat) target-matrix))))
|
||||
(set! output-matrix
|
||||
(cond
|
||||
(smooth?
|
||||
(slave-matrix-blend-2 (-> tracker inv-mat) (the-as float options-bits) aim-vector target-matrix)
|
||||
output-matrix)
|
||||
(else
|
||||
(matrix-copy! (-> tracker inv-mat) target-matrix)))))
|
||||
(mat-remove-z-rot (-> tracker inv-mat) (-> *camera* local-down))
|
||||
0
|
||||
(none)))
|
||||
0))
|
||||
|
||||
(defun v-slrp2! ((out vector) (from-vector vector) (to-vector vector) (t float) (plane-normal vector) (max-angle float))
|
||||
"Spherically interpolate from-vector toward to-vector by t while
|
||||
@@ -1119,56 +1191,51 @@
|
||||
;; angular arc without the length collapse of a linear vector blend. With a
|
||||
;; plane normal, only the in-plane direction rotates; the component on the
|
||||
;; normal is restored and interpolated independently.
|
||||
(local-vars
|
||||
(direction-dot float)
|
||||
(to-length float)
|
||||
(from-length float)
|
||||
(angle-limit float)
|
||||
(to-direction vector)
|
||||
(rotation-matrix matrix))
|
||||
(set! angle-limit max-angle)
|
||||
(let ((from-direction (new-stack-vector0)))
|
||||
(set! to-direction (new 'stack-no-clear 'vector))
|
||||
(set! (-> to-direction quad) (the-as uint128 0))
|
||||
(local-vars (direction-dot float) (to-length float) (from-length float))
|
||||
(let ((angle-limit max-angle)
|
||||
(from-direction (new-stack-vector0))
|
||||
(to-direction (new-stack-vector0)))
|
||||
1.0
|
||||
1.0
|
||||
(let ((rotation-axis (new-stack-vector0)))
|
||||
0.0
|
||||
1.0
|
||||
(set! rotation-matrix (new 'stack-no-clear 'matrix))
|
||||
(set! (-> rotation-matrix vector 0 quad) (the-as uint128 0))
|
||||
(set! (-> rotation-matrix vector 1 quad) (the-as uint128 0))
|
||||
(set! (-> rotation-matrix vector 2 quad) (the-as uint128 0))
|
||||
(set! (-> rotation-matrix vector 3 quad) (the-as uint128 0))
|
||||
(cond
|
||||
((< 1.0 t) (set! t 1.0))
|
||||
((< t 0.0) (set! t 0.0)))
|
||||
(cond
|
||||
(plane-normal
|
||||
(vector-flatten! from-direction from-vector plane-normal)
|
||||
(vector-flatten! to-direction to-vector plane-normal)
|
||||
(set! from-length (vector-normalize-ret-len! from-direction 1.0))
|
||||
(set! to-length (vector-normalize-ret-len! to-direction 1.0))
|
||||
(vector-normalize! (vector-cross! rotation-axis to-direction from-direction) 1.0)
|
||||
(let ((axis-side (vector-dot plane-normal rotation-axis)))
|
||||
(vector-normalize-copy! rotation-axis plane-normal 1.0)
|
||||
(if (< axis-side 0.0) (vector-negate! rotation-axis rotation-axis))))
|
||||
(else
|
||||
(set! (-> from-direction quad) (-> from-vector quad))
|
||||
(vector-copy! to-direction to-vector)
|
||||
(set! from-length (vector-normalize-ret-len! from-direction 1.0))
|
||||
(set! to-length (vector-normalize-ret-len! to-direction 1.0))
|
||||
(vector-normalize! (vector-cross! rotation-axis to-vector from-vector) 1.0)))
|
||||
(let ((acos-fn acos))
|
||||
(let* ((from-direction-copy from-direction)) (set! direction-dot (vector-dot from-direction-copy to-direction)))
|
||||
(let* ((angle (acos-fn direction-dot))
|
||||
(step-angle (* t angle)))
|
||||
(when (< angle-limit step-angle)
|
||||
(set! step-angle angle-limit)
|
||||
(set! t (/ angle-limit angle)))
|
||||
(let ((cos-angle (cos step-angle)))
|
||||
(matrix-axis-sin-cos! rotation-matrix rotation-axis (sqrtf (- 1.0 (square cos-angle))) cos-angle))))
|
||||
(vector-matrix*! out from-direction rotation-matrix)
|
||||
(let ((rotation-matrix (new 'stack-no-clear 'matrix)))
|
||||
(set! (-> rotation-matrix vector 0 quad) (the-as uint128 0))
|
||||
(set! (-> rotation-matrix vector 1 quad) (the-as uint128 0))
|
||||
(set! (-> rotation-matrix vector 2 quad) (the-as uint128 0))
|
||||
(set! (-> rotation-matrix vector 3 quad) (the-as uint128 0))
|
||||
(cond
|
||||
((< 1.0 t) (set! t 1.0))
|
||||
((< t 0.0) (set! t 0.0)))
|
||||
(cond
|
||||
(plane-normal
|
||||
(vector-flatten! from-direction from-vector plane-normal)
|
||||
(vector-flatten! to-direction to-vector plane-normal)
|
||||
(set! from-length (vector-normalize-ret-len! from-direction 1.0))
|
||||
(set! to-length (vector-normalize-ret-len! to-direction 1.0))
|
||||
(vector-normalize! (vector-cross! rotation-axis to-direction from-direction) 1.0)
|
||||
(let ((axis-side (vector-dot plane-normal rotation-axis)))
|
||||
(vector-normalize-copy! rotation-axis plane-normal 1.0)
|
||||
(if (< axis-side 0.0)
|
||||
(vector-negate! rotation-axis rotation-axis))))
|
||||
(else
|
||||
(vector-copy! from-direction from-vector)
|
||||
(set! (-> to-direction quad) (-> to-vector quad))
|
||||
(set! from-length (vector-normalize-ret-len! from-direction 1.0))
|
||||
(set! to-length (vector-normalize-ret-len! to-direction 1.0))
|
||||
(vector-normalize! (vector-cross! rotation-axis to-vector from-vector) 1.0)))
|
||||
(let ((acos-fn acos))
|
||||
(let* ((from-direction-copy from-direction))
|
||||
(set! direction-dot (vector-dot from-direction-copy to-direction)))
|
||||
(let* ((angle (acos-fn direction-dot))
|
||||
(step-angle (* t angle)))
|
||||
(when (< angle-limit step-angle)
|
||||
(set! step-angle angle-limit)
|
||||
(set! t (/ angle-limit angle)))
|
||||
(let ((cos-angle (cos step-angle)))
|
||||
(matrix-axis-sin-cos! rotation-matrix rotation-axis (sqrtf (- 1.0 (square cos-angle))) cos-angle))))
|
||||
(vector-matrix*! out from-direction rotation-matrix))
|
||||
(vector-normalize! out (lerp from-length to-length t))
|
||||
(when plane-normal
|
||||
(vector+float*! out out rotation-axis (vector-dot from-vector rotation-axis))
|
||||
@@ -1182,11 +1249,10 @@
|
||||
"Spherically interpolate from-vector toward to-vector by no more than
|
||||
max-angle, using the required angular fraction and interpolating length separately. An optional
|
||||
plane-normal constrains the rotation plane."
|
||||
(local-vars (direction-dot float) (to-length float) (from-length float) (angle-limit float) (to-direction vector))
|
||||
(set! angle-limit max-angle)
|
||||
(let ((from-direction (new-stack-vector0)))
|
||||
(set! to-direction (new 'stack-no-clear 'vector))
|
||||
(set! (-> to-direction quad) (the-as uint128 0))
|
||||
(local-vars (direction-dot float) (to-length float) (from-length float))
|
||||
(let ((angle-limit max-angle)
|
||||
(from-direction (new-stack-vector0))
|
||||
(to-direction (new-stack-vector0)))
|
||||
0.0
|
||||
0.0
|
||||
(let ((rotation-axis (new-stack-vector0))
|
||||
@@ -1202,15 +1268,17 @@
|
||||
(vector-normalize! (vector-cross! rotation-axis to-direction from-direction) 1.0)
|
||||
(let ((axis-side (vector-dot plane-normal rotation-axis)))
|
||||
(vector-normalize-copy! rotation-axis plane-normal 1.0)
|
||||
(if (< axis-side 0.0) (vector-negate! rotation-axis rotation-axis))))
|
||||
(if (< axis-side 0.0)
|
||||
(vector-negate! rotation-axis rotation-axis))))
|
||||
(else
|
||||
(set! (-> from-direction quad) (-> from-vector quad))
|
||||
(vector-copy! to-direction to-vector)
|
||||
(vector-copy! from-direction from-vector)
|
||||
(set! (-> to-direction quad) (-> to-vector quad))
|
||||
(set! from-length (vector-normalize-ret-len! from-direction 1.0))
|
||||
(set! to-length (vector-normalize-ret-len! to-direction 1.0))
|
||||
(vector-normalize! (vector-cross! rotation-axis to-vector from-vector) 1.0)))
|
||||
(let ((acos-fn acos))
|
||||
(let* ((from-direction-copy from-direction)) (set! direction-dot (vector-dot from-direction-copy to-direction)))
|
||||
(let* ((from-direction-copy from-direction))
|
||||
(set! direction-dot (vector-dot from-direction-copy to-direction)))
|
||||
(let ((angle (acos-fn direction-dot)))
|
||||
(when (< angle-limit angle)
|
||||
(set! fraction (/ angle-limit angle))
|
||||
|
||||
Reference in New Issue
Block a user