camera update
This commit is contained in:
1 parent
1dc2308d2e
commit
62529a352c
5 files changed
+286
-94
No files matched your search
@@ -106,7 +106,6 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
@@ -2865,6 +2864,7 @@ public class CarpetExpression
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockState targetBlock = null;
|
||||
BlockValue.VectorLocator pointLocator;
|
||||
boolean interactable = true;
|
||||
String name;
|
||||
try
|
||||
{
|
||||
@@ -2872,8 +2872,14 @@ public class CarpetExpression
|
||||
name = nameValue instanceof NullValue ? "" : nameValue.getString();
|
||||
pointLocator = BlockValue.locateVec(cc, lv, 1, true);
|
||||
if (lv.size()>pointLocator.offset)
|
||||
targetBlock = BlockValue.fromParams(cc, lv, pointLocator.offset, true).block.getBlockState();
|
||||
|
||||
{
|
||||
BlockValue.LocatorResult blockLocator = BlockValue.fromParams(cc, lv, pointLocator.offset, true, true);
|
||||
if (blockLocator.block != null) targetBlock = blockLocator.block.getBlockState();
|
||||
if (lv.size() > blockLocator.offset)
|
||||
{
|
||||
interactable = lv.get(blockLocator.offset).evalValue(c, Context.BOOLEAN).getBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
@@ -2901,6 +2907,7 @@ public class CarpetExpression
|
||||
armorstand.setNoGravity(true);
|
||||
armorstand.setInvisible(true);
|
||||
armorstand.setInvulnerable(true);
|
||||
armorstand.getDataTracker().set(ArmorStandEntity.ARMOR_STAND_FLAGS, (byte)(interactable?8 : 16|8));
|
||||
cc.s.getWorld().spawnEntity(armorstand);
|
||||
EntityValue result = new EntityValue(armorstand);
|
||||
return (_c, _t) -> result;
|
||||
@@ -3023,7 +3030,7 @@ public class CarpetExpression
|
||||
|
||||
this.expr.addLazyFunction("current_dimension", 0, (c, t, lv) -> {
|
||||
ServerCommandSource s = ((CarpetContext)c).s;
|
||||
Value retval = new StringValue(nameFromRegistryId(Registry.DIMENSION.getId(s.getWorld().dimension.getType())));
|
||||
Value retval = new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.DIMENSION.getId(s.getWorld().dimension.getType())));
|
||||
return (cc, tt) -> retval;
|
||||
});
|
||||
|
||||
|
||||
@@ -1198,16 +1198,14 @@ public class Expression implements Cloneable
|
||||
{
|
||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
if (!v1.getBoolean()) return (cc, tt) -> v1;
|
||||
Value v2 = lv2.evalValue(c, Context.BOOLEAN);
|
||||
return v2.getBoolean() ? ((cc, tt) -> v2) : LazyValue.FALSE;
|
||||
return lv2;
|
||||
});
|
||||
|
||||
addLazyBinaryOperator("||", precedence.get("or||"), false, (c, t, lv1, lv2) ->
|
||||
{
|
||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
if (v1.getBoolean()) return (cc, tt) -> v1;
|
||||
Value v2 = lv2.evalValue(c, Context.BOOLEAN);
|
||||
return v2.getBoolean() ? ((cc, tt) -> v2) : LazyValue.FALSE;
|
||||
return lv2;
|
||||
});
|
||||
|
||||
addBinaryOperator("~", precedence.get("attribute~:"), true, Value::in);
|
||||
@@ -1928,7 +1926,7 @@ public class Expression implements Cloneable
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
LazyValue _val = c.getVariable("_");
|
||||
LazyValue _iter = c.getVariable("_i");
|
||||
LazyValue _ite = c.getVariable("_i");
|
||||
int successCount = 0;
|
||||
for (int i=0; iterator.hasNext(); i++)
|
||||
{
|
||||
@@ -1959,7 +1957,7 @@ public class Expression implements Cloneable
|
||||
//revering scope
|
||||
((AbstractListValue) rval).fatality();
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _iter);
|
||||
c.setVariable("_i", _ite);
|
||||
long promiseWontChange = successCount;
|
||||
return (cc, tt) -> new NumericValue(promiseWontChange);
|
||||
});
|
||||
@@ -1988,15 +1986,18 @@ public class Expression implements Cloneable
|
||||
//scoping
|
||||
LazyValue _val = c.getVariable("_");
|
||||
LazyValue _acc = c.getVariable("_a");
|
||||
LazyValue _ite = c.getVariable("_i");
|
||||
|
||||
while (iterator.hasNext())
|
||||
for (int i=0; iterator.hasNext(); i++)
|
||||
{
|
||||
Value next = iterator.next();
|
||||
String var = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
Value promiseWontChangeYou = acc;
|
||||
int seriously = i;
|
||||
c.setVariable("_a", (cc, tt) -> promiseWontChangeYou.bindTo("_a"));
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||
try
|
||||
{
|
||||
acc = expr.evalValue(c, t);
|
||||
@@ -2016,6 +2017,7 @@ public class Expression implements Cloneable
|
||||
((AbstractListValue) rval).fatality();
|
||||
c.setVariable("_a", _acc);
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _ite);
|
||||
|
||||
Value hopeItsEnoughPromise = acc;
|
||||
return (cc, tt) -> hopeItsEnoughPromise;
|
||||
|
||||
@@ -130,15 +130,24 @@ public class BlockValue extends Value
|
||||
|
||||
public static LocatorResult fromParams(CarpetContext c, List<LazyValue> params, int offset)
|
||||
{
|
||||
return fromParams(c, params,offset, false);
|
||||
return fromParams(c, params,offset, false, false);
|
||||
}
|
||||
|
||||
public static LocatorResult fromParams(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString)
|
||||
{
|
||||
return fromParams(c, params,offset, acceptString, false);
|
||||
}
|
||||
|
||||
public static LocatorResult fromParams(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString, boolean optional)
|
||||
{
|
||||
try
|
||||
{
|
||||
Value v1 = params.get(0 + offset).evalValue(c);
|
||||
//add conditional from string name
|
||||
if (optional && v1 instanceof NullValue)
|
||||
{
|
||||
return new LocatorResult(null, 1+offset);
|
||||
}
|
||||
if (acceptString && v1 instanceof StringValue)
|
||||
{
|
||||
return new LocatorResult(fromString(v1.getString()), 1+offset);
|
||||
|
||||
@@ -772,6 +772,39 @@ public class EntityValue extends Value
|
||||
else
|
||||
e.noClip = v.getBoolean();
|
||||
});
|
||||
put("effect", (e, v) ->
|
||||
{
|
||||
if (!(e instanceof LivingEntity)) return;
|
||||
LivingEntity le = (LivingEntity)e;
|
||||
if (v == null)
|
||||
le.clearPotionEffects();
|
||||
else if (v instanceof ListValue)
|
||||
{
|
||||
List<Value> lv = ((ListValue) v).getItems();
|
||||
if (lv.size() >= 2 && lv.size() <= 5)
|
||||
{
|
||||
String effectName = lv.get(0).getString();
|
||||
if (effectName.startsWith("minecraft:"))
|
||||
effectName = "minecraft:"+effectName;
|
||||
StatusEffect effect = Registry.STATUS_EFFECT.get(new Identifier(effectName));
|
||||
if (effect == null)
|
||||
throw new InternalExpressionException("Wrong effect name: "+effectName);
|
||||
int duration = (int)NumericValue.asNumber(lv.get(1)).getLong();
|
||||
int amplifier = 0;
|
||||
if (lv.size() > 2)
|
||||
amplifier = (int)NumericValue.asNumber(lv.get(2)).getLong();
|
||||
boolean showParticles = true;
|
||||
if (lv.size() > 3)
|
||||
showParticles = lv.get(3).getBoolean();
|
||||
boolean showIcon = true;
|
||||
if (lv.size() > 4)
|
||||
showIcon = lv.get(4).getBoolean();
|
||||
le.addPotionEffect(new StatusEffectInstance(effect, duration, amplifier, showParticles, showIcon));
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new InternalExpressionException("'effect' needs either no arguments (clear) or effect name, duration, and optional amplifier, show particles and show icon");
|
||||
});
|
||||
|
||||
// gamemode
|
||||
// spectate
|
||||
|
||||
@@ -35,31 +35,66 @@ __command() ->
|
||||
''
|
||||
);
|
||||
|
||||
// camera position for the player sticks out of their eyes
|
||||
__camera_position(player) -> (player~'location' + l(0, player~'eye_height',0,0,0));
|
||||
|
||||
__update() ->
|
||||
(
|
||||
undef('global_path_precalculated');
|
||||
global_needs_updating = true;
|
||||
);
|
||||
|
||||
start() ->
|
||||
(
|
||||
p = player();
|
||||
global_points = l(l(p ~ 'location', 0,'sharp'));
|
||||
undef('global_path_precalculated');
|
||||
str('Started path at %.1f %.1f %.1f', p~'x', p~'y', p~'z')
|
||||
global_points = l(l(__camera_position(p), 0,'sharp'));
|
||||
__update();
|
||||
show();
|
||||
str('Started path at %.1f %.1f %.1f', p~'x', p~'y', p~'z');
|
||||
);
|
||||
add(delay) ->
|
||||
(
|
||||
p = player();
|
||||
mode = 'sharp';
|
||||
mode = 'smooth';
|
||||
//mode is currently unused, run_path does always sharp, gauss interpolator is always smooth
|
||||
// but this option could be used could be used at some point by more robust interpolators
|
||||
__add_path_segment(p ~ 'location', delay, mode);
|
||||
str('Added point %d: %.1f %.1f %.1f', length(global_points), p~'x', p~'y', p~'z')
|
||||
__add_path_segment(__camera_position(p), round(60*delay), mode);
|
||||
__print_path_size();
|
||||
);
|
||||
|
||||
prepend(delay) ->
|
||||
(
|
||||
p = player();
|
||||
mode = 'smooth';
|
||||
__prepend_path_segment(__camera_position(p), round(60*delay), mode);
|
||||
__print_path_size();
|
||||
);
|
||||
|
||||
__add_path_segment(vector, duration, mode) ->
|
||||
(
|
||||
undef('global_path_precalculated');
|
||||
if ( (l('sharp','smooth') ~ mode) == null, exit('use smooth or sharp point'));
|
||||
if(!global_points, exit('Cannot add point to path that didn\'t started yet!'));
|
||||
l(v, end_time, m) = global_points:(-1);
|
||||
vector:(-2) = __adjusted_rot(v:(-2) , vector:(-2) );
|
||||
global_points += l(vector, end_time+duration, mode)
|
||||
global_points += l(vector, end_time+duration, mode);
|
||||
__update();
|
||||
);
|
||||
|
||||
__prepend_path_segment(vector, duration, mode) ->
|
||||
(
|
||||
if ( (l('sharp','smooth') ~ mode) == null, exit('use smooth or sharp point'));
|
||||
if(!global_points, exit('Cannot add point to path that didn\'t started yet!'));
|
||||
l(v, start_time, m) = global_points:(-1);
|
||||
vector:(-2) = __adjusted_rot(v:(-2), vector:(-2));
|
||||
new_points = l(l(vector, 0, mode));
|
||||
for (global_points,
|
||||
_:1 += duration;
|
||||
new_points += _;
|
||||
);
|
||||
global_points = new_points;
|
||||
__update();
|
||||
);
|
||||
|
||||
// adjusts current rotation so we don\'t spin around like crazy
|
||||
__adjusted_rot(previous_rot, current_rot) ->
|
||||
(
|
||||
@@ -71,79 +106,80 @@ __adjusted_rot(previous_rot, current_rot) ->
|
||||
|
||||
__print_path_size() ->
|
||||
(
|
||||
__assert_valid_for_motion();
|
||||
print("Path length: %d points, 0.2f secs at 60fps", length(global_points), global_points:(-1):1/60);
|
||||
if (!__assert_valid_for_motion(),
|
||||
print(str('%d points, %.1f secs', length(global_points), global_points:(-1):1/60));
|
||||
);
|
||||
'';
|
||||
);
|
||||
|
||||
repeat(times, last_section_duration) ->
|
||||
(
|
||||
__assert_valid_for_motion();
|
||||
undef('global_path_precalculated');
|
||||
if (err = __assert_valid_for_motion(), exit(err));
|
||||
positions = map(global_points, _:0);
|
||||
modes = map(global_points, _:(-1));
|
||||
durations = map(global_points, global_points:(_i+1):1 - _:1 );
|
||||
durations:(-1) = last_section_duration;
|
||||
durations:(-1) = round(60*last_section_duration);
|
||||
loop(times,
|
||||
loop( length(positions),
|
||||
__add_path_segment(positions:_, durations:_, modes:_)
|
||||
)
|
||||
);
|
||||
__update();
|
||||
__print_path_size();
|
||||
'';
|
||||
);
|
||||
speed(percentage) ->
|
||||
stretch(percentage) ->
|
||||
(
|
||||
__assert_valid_for_motion();
|
||||
if (err = __assert_valid_for_motion(), exit(err));
|
||||
undef('global_path_precalculated');
|
||||
if (percentage < 25 || percentage > 400,
|
||||
exit('path speed can only be speed, or slowed down 4 times. Recall command for larger changes')
|
||||
exit('path speed can only be speed, or slowed down 4 times. Re-call command for larger changes')
|
||||
);
|
||||
ratio = percentage/100;
|
||||
previous_path_length = global_points:(-1):1;
|
||||
for(global_points, _:1 = _:1*ratio );
|
||||
undef('global_path_precalculated');
|
||||
str('path %s from %d to %d ticks (%.2f seconds with 60fps)',
|
||||
__update();
|
||||
str('path %s from %.2f to %.2f seconds',
|
||||
if(ratio<1,'shortened','extended'),
|
||||
previous_path_length,
|
||||
global_points:(-1):1,
|
||||
previous_path_length/60,
|
||||
global_points:(-1):1/60
|
||||
)
|
||||
);
|
||||
|
||||
select_interpolation(method) ->
|
||||
(
|
||||
undef('global_path_precalculated');
|
||||
__prepare_path_if_needed() -> __prepare_path_if_needed_generic();
|
||||
// each supported method needs to specify its __find_position_for_point to trace the path
|
||||
// accepting segment number, and position in the segment
|
||||
// or optionally __prepare_path_if_needed, if path is inefficient to compute point by point
|
||||
if (
|
||||
method == 'linear',
|
||||
(
|
||||
__find_position_for_point(s, p) -> __find_position_for_linear(s, p)
|
||||
),
|
||||
global_interpolator = if (
|
||||
method == 'linear', '__interpolator_linear',
|
||||
method == 'cr', '__interpolator_cr',
|
||||
method == 'gauss', _(s, p) -> __interpolator_gauss(s, p, 0),
|
||||
method ~ '^gauss_',
|
||||
(
|
||||
type = method - 'gauss_';
|
||||
global_interpol_option = if(type=='auto',0,number(type));
|
||||
__find_position_for_point(s, p) -> __find_position_for_gauss(s, p)
|
||||
variance = number(type);
|
||||
_(s, p, outer(variance)) -> __interpolator_gauss(s, p, variance);
|
||||
),
|
||||
|
||||
exit('Choose one of the following methods: linear, gauss:auto, gauss:<deviation>')
|
||||
exit('Choose one of the following methods: linear, gauss, gauss_<deviation>, cr')
|
||||
);
|
||||
__update();
|
||||
'Ok'
|
||||
);
|
||||
select_interpolation('gauss_auto');
|
||||
select_interpolation('cr');
|
||||
|
||||
__assert_valid_for_motion() ->
|
||||
(
|
||||
if(!global_points, exit('Path not defined yet'));
|
||||
if(length(global_points)<2, exit('Path not complete - add more points'));
|
||||
if(!global_points, return('Path not defined yet'));
|
||||
if(length(global_points)<2, return('Path not complete - add more points'));
|
||||
null
|
||||
);
|
||||
__get_path_at(segment, start, index) ->
|
||||
(
|
||||
v = global_path_precalculated:(start+index);
|
||||
if(v == null,
|
||||
v = __find_position_for_point(segment, index);
|
||||
v = call(global_interpolator, segment, index);
|
||||
global_path_precalculated:(start+index) = v
|
||||
);
|
||||
v
|
||||
@@ -153,16 +189,11 @@ __invalidate_points_cache() -> global_path_precalculated = map(range(global_poin
|
||||
global_showing_path = false;
|
||||
global_playing_path = false;
|
||||
|
||||
stop() ->
|
||||
hide() ->
|
||||
(
|
||||
if (!global_playing_path && !global_showing_path, return('You can only stop playing or showing the path'));
|
||||
if (global_showing_path,
|
||||
global_showing_path = false;
|
||||
print('stopped showing path');
|
||||
);
|
||||
if (global_playing_path,
|
||||
global_playing_path = false;
|
||||
print('stopped playing path');
|
||||
print('Stopped showing path');
|
||||
);
|
||||
''
|
||||
);
|
||||
@@ -170,65 +201,177 @@ stop() ->
|
||||
clear() ->
|
||||
(
|
||||
global_points = l();
|
||||
undef('global_path_precalculated');
|
||||
__update();
|
||||
);
|
||||
|
||||
global_needs_updating = false;
|
||||
global_selected_point = null;
|
||||
global_markers = null;
|
||||
|
||||
__distsq(vec1, vec2) -> reduce(vec1 - vec2, _a + _*_, 0);
|
||||
|
||||
__closest_point_to_center(center, points) ->
|
||||
(
|
||||
dd = __distsq(points:0, center);
|
||||
for(points,
|
||||
d = __distsq(_, center);
|
||||
if( d<dd,
|
||||
dd=d;
|
||||
index = _i
|
||||
);
|
||||
);
|
||||
index;
|
||||
);
|
||||
|
||||
select() ->
|
||||
(
|
||||
if (!global_points, return());
|
||||
if (!global_showing_path, return());
|
||||
p = player();
|
||||
selected_point = __closest_point_to_center(
|
||||
p~'pos'+l(0,p~'eye_height',0),
|
||||
map(global_points, slice(_:0, 0, 3))
|
||||
);
|
||||
global_selected_point = if (global_selected_point == selected_point, null, selected_point);
|
||||
global_needs_updating = true;
|
||||
// no need to _update since path is still valid
|
||||
|
||||
);
|
||||
|
||||
__on_player_attacks_entity(p, e) ->
|
||||
(
|
||||
if (e~'type' == 'armor_stand' && query(e, 'has_tag', '__scarpet_marker_camera') && global_markers,
|
||||
for (global_markers,
|
||||
if(_==e,
|
||||
global_selected_point = if (global_selected_point == _i, null, _i);
|
||||
global_needs_updating = true;
|
||||
return();
|
||||
)
|
||||
);
|
||||
);
|
||||
);
|
||||
|
||||
global_show_thread = null;
|
||||
|
||||
show() ->
|
||||
(
|
||||
p = player();
|
||||
__assert_valid_for_motion();
|
||||
__print_path_size();
|
||||
if (global_showing_path, return ());
|
||||
global_showing_path = true;
|
||||
global_needs_updating= false;
|
||||
def __create_markers()->
|
||||
__create_markers() ->
|
||||
(
|
||||
map(global_points,
|
||||
m = create_marker(null, _:0, 'observer');
|
||||
if (global_selected_point && _i == global_selected_point,
|
||||
modify(m,'effect','glowing',72000);
|
||||
map(global_points || l(),
|
||||
is_selected = global_selected_point != null && _i == global_selected_point;
|
||||
caption = if (_i == 0, 'start', str('%.1fs', global_points:_i:1/60); );
|
||||
if (is_selected && _i > 0,
|
||||
caption += str(' (%.1f current segment)', (global_points:_i:1 - global_points:(_i-1):1)/60);
|
||||
);
|
||||
m = create_marker(caption, _:0, 'observer');
|
||||
if (is_selected,
|
||||
modify(m,'effect','glowing',72000, 0, false, false);
|
||||
);
|
||||
m
|
||||
);
|
||||
);
|
||||
__show_path_tick() ->
|
||||
(
|
||||
if (__assert_valid_for_motion(), return());
|
||||
__prepare_path_if_needed();
|
||||
loop(100,
|
||||
segment = floor(rand(length(global_points)-1));
|
||||
particle_type = if ((segment+1) == global_selected_point, 'dust 0.1 0.9 0.1 1','dust 0.6 0.6 0.6 1');
|
||||
start = global_points:segment:1;
|
||||
end = global_points:(segment+1):1;
|
||||
index = floor(rand(end-start));
|
||||
l(x, y, z) = slice(__get_path_at(segment, start, index), 0, 3);
|
||||
particle(particle_type, x, y, z, 1, 0, 0)
|
||||
);
|
||||
null
|
||||
);
|
||||
|
||||
task( _(outer(p)) -> (
|
||||
markers = __create_markers();
|
||||
global_markers = __create_markers();
|
||||
loop(7200,
|
||||
if(!global_showing_path, break());
|
||||
if (global_needs_updating,
|
||||
global_needs_updating = false;
|
||||
for(markers, modify(_,'remove');
|
||||
markers = __create_markers();
|
||||
for(global_markers, modify(_,'remove'));
|
||||
global_markers = __create_markers();
|
||||
);
|
||||
_show_path_tick('dust 0.9 0.1 0.1 1', 100);
|
||||
__show_path_tick();
|
||||
sleep(100);
|
||||
);
|
||||
for(markers, modify(_,'remove');
|
||||
print('Done!');
|
||||
for(global_markers, modify(_,'remove'));
|
||||
global_markers = null;
|
||||
global_showing_path = false;
|
||||
));
|
||||
'';
|
||||
);
|
||||
|
||||
play(fps) ->
|
||||
move() ->
|
||||
(
|
||||
if (global_selected_point == null, return());
|
||||
if (!global_showing_path, return());
|
||||
global_points:global_selected_point:0 = __camera_position(player());
|
||||
__update();
|
||||
);
|
||||
|
||||
duration(amount) ->
|
||||
(
|
||||
if (!global_selected_point, return()); // skip nulls, and 0 (first one)
|
||||
if (!global_showing_path, return());
|
||||
duration = number(amount);
|
||||
new_ticks = round(duration * 60);
|
||||
if (new_ticks < 10, return());
|
||||
previous_ticks = global_points:global_selected_point:1-global_points:(global_selected_point-1):1;
|
||||
delta = new_ticks - previous_ticks;
|
||||
// adjust duration of all points after that.
|
||||
for (range(global_selected_point, length(global_points)),
|
||||
global_points:_:1 += delta;
|
||||
);
|
||||
__update();
|
||||
);
|
||||
|
||||
delete_point() ->
|
||||
(
|
||||
if (global_selected_point == null, return()); // skip nulls, and 0 (first one)
|
||||
if (!global_showing_path, return());
|
||||
if (length(global_points) < 2, clear(); return());
|
||||
if (global_selected_point == 0, global_points:1:1 = 0);
|
||||
global_points = filter(global_points, _i != global_selected_point);
|
||||
__update();
|
||||
);
|
||||
|
||||
trim_path() ->
|
||||
(
|
||||
if (global_selected_point == null, return()); // skip nulls, and 0 (first one)
|
||||
if (!global_showing_path, return());
|
||||
global_points = slice(global_points, 0, global_selected_point);
|
||||
__update();
|
||||
);
|
||||
|
||||
play() ->
|
||||
(
|
||||
p = player();
|
||||
__assert_valid_for_motion();
|
||||
if (err = __assert_valid_for_motion(), exit(err));
|
||||
__prepare_path_if_needed();
|
||||
global_playing_path = true;
|
||||
task( _(outer(fps), outer(p)) -> (
|
||||
sleep(1000);
|
||||
mspt = 1000 / fps;
|
||||
global_playing_path = true;
|
||||
mspt = 1000 / 60;
|
||||
start_time = time();
|
||||
point = 0;
|
||||
player_offset = l(0,p~'eye_height',0,0,0);
|
||||
try (
|
||||
loop( length(global_points)-1, segment = _;
|
||||
if (p~'sneaking', global_playing_path = false);
|
||||
if (!global_playing_path, break());
|
||||
start = global_points:segment:1;
|
||||
end = global_points:(segment+1):1;
|
||||
loop(end-start,
|
||||
v = __get_path_at(segment, start, _);
|
||||
if (p~'sneaking', global_playing_path = false);
|
||||
if (!global_playing_path, throw());
|
||||
v = __get_path_at(segment, start, _)-player_offset;
|
||||
modify(p, 'location', v);
|
||||
point += 1;
|
||||
end_time = time();
|
||||
@@ -237,30 +380,19 @@ play(fps) ->
|
||||
start_time = time()
|
||||
)
|
||||
);
|
||||
);
|
||||
sleep(1000);
|
||||
global_playing_path = false;
|
||||
print('Done!');
|
||||
));
|
||||
'';
|
||||
);
|
||||
_show_path_tick(particle_type, total) ->
|
||||
(
|
||||
__assert_valid_for_motion();
|
||||
__prepare_path_if_needed();
|
||||
loop(total,
|
||||
segment = floor(rand(length(global_points)-1));
|
||||
start = global_points:segment:1;
|
||||
end = global_points:(segment+1):1;
|
||||
index = floor(rand(end-start));
|
||||
l(x, y, z) = slice(__get_path_at(segment, start, index), 0, 3);
|
||||
particle(particle_type, x, y, z, 1, 0, 0)
|
||||
);
|
||||
null
|
||||
);
|
||||
|
||||
__prepare_path_if_needed_generic() ->
|
||||
(
|
||||
if(!global_path_precalculated, __invalidate_points_cache())
|
||||
);
|
||||
__find_position_for_linear(segment, point) ->
|
||||
__interpolator_linear(segment, point) ->
|
||||
(
|
||||
l(va, start, mode_a) = global_points:segment;
|
||||
l(vb, end, mode_b) = global_points:(segment+1);
|
||||
@@ -271,16 +403,14 @@ __find_position_for_linear(segment, point) ->
|
||||
//(1/sqrt(2*pi*d*d))*euler^(-((x-miu)^2)/(2*d*d))
|
||||
// but we will be normalizing anyways, so who cares
|
||||
__norm_prob(x, miu, d) -> euler^(-((x-miu)^2)/(2*d*d));
|
||||
__find_position_for_gauss(from_index, point) ->
|
||||
__interpolator_gauss(from_index, point, deviation) ->
|
||||
(
|
||||
dev = global_interpol_option;
|
||||
components = l();
|
||||
path_point = global_points:from_index:1;
|
||||
|
||||
try(
|
||||
for(range(from_index+1, length(global_points)),
|
||||
l(v,ptime,mode) = global_points:_;
|
||||
dev = if (global_interpol_option > 0, global_interpol_option,
|
||||
dev = if (deviation > 0, deviation,
|
||||
devs = l();
|
||||
if (_+1 < length(global_points), devs += global_points:(_+1):1-ptime);
|
||||
if (_-1 >= 0, devs += ptime-global_points:(_-1):1);
|
||||
@@ -295,7 +425,7 @@ __find_position_for_gauss(from_index, point) ->
|
||||
try(
|
||||
for(range(from_index, -1, -1),
|
||||
l(v,ptime,mode) = global_points:_;
|
||||
dev = if (global_interpol_option > 0, global_interpol_option,
|
||||
dev = if (deviation > 0, deviation,
|
||||
devs = l();
|
||||
if (_+1 < length(global_points), devs += global_points:(_+1):1-ptime);
|
||||
if (_-1 >= 0, devs += ptime-global_points:(_-1):1);
|
||||
@@ -309,4 +439,15 @@ __find_position_for_gauss(from_index, point) ->
|
||||
);
|
||||
total = rtotal+ltotal;
|
||||
reduce(components, _a+_:0*(_:1/total), l(0,0,0,0,0))
|
||||
)
|
||||
);
|
||||
|
||||
__interpolator_cr(from_index, point) ->
|
||||
(
|
||||
total = global_points:(from_index+1):1 - global_points:from_index:1;
|
||||
p__1 = global_points:(if(from_index == 0, 0, from_index-1)):0;
|
||||
p_0 = global_points:from_index:0;
|
||||
p_1 = global_points:(from_index+1):0;
|
||||
p_2 = global_points:(if(from_index == (length(global_points)-2), -1, from_index+2)):0;
|
||||
r = point/total; // ratio within segment
|
||||
(r*((2-r)*r-1) * p__1 + (r*r*(3*r-5)+2) * p_0 + r*((4 - 3*r)*r + 1) * p_1 + (r-1)*r*r * p_2) / 2
|
||||
);
|
||||
Reference in new issue
Block a user