|
还没有账号?赶快去注册吧!
您需要 登录 才可以下载或查看,没有账号?立即注册
×
- N& p! G( }1 Y( s' m! a
' Q, i H: P R7 k/ w, Z. ^前情提要:此Mod 现名ANTE (Aphrodite's Nemo's Transit Expansion) 即由 我(Aphrodite) 进行后续更新的NTE 请勿与NTE混为一谈,切忌找zbx问关于ANTE的新特性。
" [9 r8 b- S5 o- a7 \' a' P- ~" g; m
& ~' E: W. b; z# |9 U, [这两天为装饰物件添加了对右击响应的支持。" X1 @* g+ a6 \8 @' |$ Q- X
( E6 y. v; W3 ]4 R3 Q同时我改良了DrawCall系列的继承关系,为自定义DrawCall内容提供了支持。
8 g8 f8 g, W; T- ~: U/ ~' T
8 D* Z6 z4 ^# s; l' @+ F ?为了能不受限于在render函数中添加绘制调用,我为装饰物件和列车的上下文添加了drawCalls(Map<Object, DrawCall>),现在可以在任何时间任何线程添加、修改、删除绘制调用。# N6 F6 B4 j6 x- o- [9 N+ {8 X
8 B* [! A" s! k e3 R7 ~; A) l: q
下面是一段示例代码,实现了在右击装饰物件时(不是用刷子)时在玩家头部生成一个始终面向摄像机并向上匀速运动的面的效果。
/ ~( P/ x- [ E- importPackage(java.nio);
% |4 B. b9 y- q: x, F5 p - " D6 D9 U7 u) p0 `, O
- let model = ModelManager.loadRawModel(Resources.manager(), Resources.idr("face.obj"), null);// 法线 -z: a7 ^4 x* g7 |5 V
- model = ModelManager.uploadVertArrays(model);
2 c4 j; d! Q, H+ S3 r- m. F - ; S" p' r3 E* r# i
- function create(ctx, state, entity) {
, r$ N6 w8 o- \+ F - state.num = 0;
! j% ?8 }: V2 ~ - }
8 j- c9 @. D1 M# t+ F
; Z% Q. u) P9 r- function beClicked(ctx, state, entity, player) {// player: WapperedEntity 包装了 Entity(Player) 为js提供一些基本的方法和属性- s/ a8 t; U8 T; k; v
- let p = player.getPosition();1 M; S& ?, _, n/ K5 T( Y1 `- ?0 }
- p.add(0, 1.5, 0);// 假定头在脚底往上1.5m
1 }; c) U, a8 ]1 Q% w; T2 a7 |2 n - ctx.setDebugInfo("Clicked on ", "shift: " + player.isShiftKeyDown(), "look angle: " + player.getLookAngle(), "from: " + p,"time: " + Date.now(), p);" G5 F+ ?$ P- ~7 x- \3 a
- let ti = Date.now();* [. {0 S/ ?8 _, g) E: h
- // DrawCall为一个接口 仅有一个commit方法
- N9 b2 V! x- [ - let call = new DrawCall({commit: (drawScheduler, basePose, worldPose, light) => {// 差不多是这样的 包含commit方法的对象 -> 转换为DrawCall对象. p' o: t1 D" x* b
- try {: X& U- }' P8 G2 }9 q
- let pose = worldPose.copy();/ l% t5 ]- W1 c; r; ?* ^8 _% O# j
- pose.translate(p);. v/ C, r+ |+ t# g* Y
- pose.translate(0, (Date.now() - ti) / 1000 * 0.4, 0);
$ o/ P# Y1 _0 r) G3 n7 m7 O
3 L5 f7 v6 [" E- let buf = FloatBuffer.allocate(16);+ S$ u6 ]0 t# }. l5 h ~
- pose.store(buf);3 D6 Q2 w W$ @: ^+ |$ b
-
6 Q' `" |; F' x* a; T, e - buf.put(0, 1);
3 j" s R/ u4 D; T) A" r8 g( Q - buf.put(1, 0);
' y) }7 ?2 k+ Q4 p/ p - buf.put(2, 0);
$ r `7 s7 ?. E" _) \+ P - buf.put(3, 0);
) V3 `: o5 H5 C3 } B, u+ y4 p
! K- S9 f; @" z; B0 ~2 N/ C- buf.put(4, 0);4 D$ o/ }! F" O8 J3 h' H8 g; E; U- H
- buf.put(5, 1);
& x) S0 e$ C" Y/ l' ?1 T& [ - buf.put(6, 0);
z# W% F" k0 ] - buf.put(7, 0);% U# p3 }1 h$ v, r! _0 x, f
- , T3 V9 C8 O* s% X, R/ u
- buf.put(8, 0);4 V. Y2 \3 T& R1 F, ^+ `
- buf.put(9, 0);% D" \9 g/ h; \& `
- buf.put(10, 1); d9 p$ |2 h+ K; j
- buf.put(11, 0);, J5 X# ^8 m: V" x0 S# J
- % E9 R4 C( d$ d, i1 X
- pose.load(buf);// 清空旋转信息 始终面向摄像机
% }; E! w" G+ e. h0 Q- x7 q5 M
: X/ D" F& J+ N' V" H- drawScheduler.enqueue(model, pose, light);
6 u3 z+ x$ @4 _1 |3 t; G - } catch (e) {2 @3 i; `- k& @
- ctx.setDebugInfo("Error", e.toString());1 ^9 C9 P+ [, @2 G3 a4 f& h
- }$ Q+ F* y' t6 e$ w6 ^& L2 c+ Y. v
- }});
3 h# X- p6 {: N; N9 w4 s; V1 p, N - ctx.drawCalls.put(state.num, call);
5 ?/ F f2 f) D7 ]1 U - // 亦可以直接使用 ctx.drawCalls.put(state.num, (drawScheduler, basePose, worldPose, light) => {...}); . g2 x: m8 H2 v
- // 即 function -> lambda表达式(java) -> DrawCall对象
f3 X' u E8 W. F; \) Z1 @$ S - state.num++;
0 h. k, {. U: U1 F; m - }
复制代码 : j( q( x% q+ d( ^% L, q: _3 A) @
) a2 [) ~ G f$ _) {, F请注意 beClicked 只会在当前客户端执行一次 若需要多端同步请将数据保存在 entity.data 中(' y! G% C' g1 O0 E9 r0 C
6 b V2 e Q; W2 I4 g+ y8 O |
|