最近は1日1時間ぐらいMODのメンテナンスをやってます。
と言っても殆どは最適化で、それも体感できるような物は少ない感じのコード。
今日はブロックを叩いたときのパーティクルが出ない事に気付いたからコードを見てみると・・・
パーティクルの座標がずれていましたw
このパーティクルは本体のコードaddBlockHitEffectsから貰っているんだけれど、これものすごく無駄があるんですよ
public void addBlockHitEffects(int p_78867_1_, int p_78867_2_, int p_78867_3_, int p_78867_4_) { Block block = this.worldObj.getBlock(p_78867_1_, p_78867_2_, p_78867_3_); if (block.getMaterial() != Material.air) { float f = 0.1F; double d0 = (double)p_78867_1_ + this.rand.nextDouble() * (block.getBlockBoundsMaxX() - block.getBlockBoundsMinX() - (double)(f * 2.0F)) + (double)f + block.getBlockBoundsMinX(); double d1 = (double)p_78867_2_ + this.rand.nextDouble() * (block.getBlockBoundsMaxY() - block.getBlockBoundsMinY() - (double)(f * 2.0F)) + (double)f + block.getBlockBoundsMinY(); double d2 = (double)p_78867_3_ + this.rand.nextDouble() * (block.getBlockBoundsMaxZ() - block.getBlockBoundsMinZ() - (double)(f * 2.0F)) + (double)f + block.getBlockBoundsMinZ(); if (p_78867_4_ == 0) { d1 = (double)p_78867_2_ + block.getBlockBoundsMinY() - (double)f; } if (p_78867_4_ == 1) { d1 = (double)p_78867_2_ + block.getBlockBoundsMaxY() + (double)f; } if (p_78867_4_ == 2) { d2 = (double)p_78867_3_ + block.getBlockBoundsMinZ() - (double)f; } if (p_78867_4_ == 3) { d2 = (double)p_78867_3_ + block.getBlockBoundsMaxZ() + (double)f; } if (p_78867_4_ == 4) { d0 = (double)p_78867_1_ + block.getBlockBoundsMinX() - (double)f; } if (p_78867_4_ == 5) { d0 = (double)p_78867_1_ + block.getBlockBoundsMaxX() + (double)f; } this.addEffect((new EntityDiggingFX(this.worldObj, d0, d1, d2, 0.0D, 0.0D, 0.0D, block, this.worldObj.getBlockMetadata(p_78867_1_, p_78867_2_, p_78867_3_))).applyColourMultiplier(p_78867_1_, p_78867_2_, p_78867_3_).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F)); } }
無駄ってのは第4引数p_78867_4_を評価しているところ。
p_78867_4_は叩かれた面の数字が入るのだけれど、途中で値が変動しないのにも関わらず6面全部を評価しているところ。
まあ、これはデコンパイルされたコードだからこうなってるだけで、本当のコードは違うのかもしれないけどw
レンダリングに関わるところなので1秒間に何度も呼ばれる物だからswitchの方が高速。
なのでうちのコードはこんな感じ
public boolean addHitEffects(World world, MovingObjectPosition target, EffectRenderer effectRenderer) { float range = 0.1F; double pX = (double)target.blockX + world.rand.nextDouble() * (this.getBlockBoundsMaxX() - this.getBlockBoundsMinX() - (double)(range * 2.0F)) + (double)range + this.getBlockBoundsMinX(); double pY = (double)target.blockY + world.rand.nextDouble() * (this.getBlockBoundsMaxY() - this.getBlockBoundsMinY() - (double)(range * 2.0F)) + (double)range + this.getBlockBoundsMinY(); double pZ = (double)target.blockZ + world.rand.nextDouble() * (this.getBlockBoundsMaxZ() - this.getBlockBoundsMinZ() - (double)(range * 2.0F)) + (double)range + this.getBlockBoundsMinZ(); switch (target.sideHit) { case 0: pY = (double)target.blockY + this.getBlockBoundsMinY() - (double)range; break; case 1: pY = (double)target.blockY + this.getBlockBoundsMaxY() + (double)range; break; case 2: pZ = (double)target.blockZ + this.getBlockBoundsMinZ() - (double)range; break; case 3: pZ = (double)target.blockZ + this.getBlockBoundsMaxZ() + (double)range; break; case 4: pX = (double)target.blockX + this.getBlockBoundsMinX() - (double)range; break; case 5: pX = (double)target.blockX + this.getBlockBoundsMaxX() + (double)range; break; } int meta = 0; try { TileEntity_Multibase te = (TileEntity_Multibase)world.getTileEntity(target.blockX, target.blockY, target.blockZ); meta = te.getMeta(); } catch (Exception e) { } effectRenderer.addEffect((new EntityDiggingFX(world, pX, pY, pZ, 0.0D, 0.0D, 0.0D, this, meta, target.sideHit)).applyColourMultiplier(target.blockX, target.blockY, target.blockZ).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F)); return true; }
メソッド名や引数が違うのはコードを使ってる場所が違うだけで内容は全く同じ。
本体のコードと違うところは、叩かれた面によって座標を変動させる所。
さっきも書いたけど、1秒間に何回も呼ばれるメソッドだし、変動しない値を6回も評価するのは無意味なのでswitchで目的の値へ飛ぶ方が速い。
でもまあ、こんな感じで本体のコードから持ってきたヤツも信用せずちゃんと書き換えれば少しは体感できるぐらい軽くなるのかも?
Selectable Paintingsが進まないのもこの辺があってすごく面倒だから・・・
テクスチャの解析に時間が掛かるからって言って当時にできる限りの最適化をやってたからなあー。
最近のコメント