/// <summary> /// Multiply the matrix with a vec4. Reference: http://mathinsight.org/matrix_vector_multiplication /// /// </summary> /// <param name="matrix"></param> /// <param name="inVal"></param> /// <param name="outVal"></param> /// <returns></returns> public static void MulWithVec4(float[] matrix, Vec4f inVal, Vec4f outVal) { outVal.Set(0, 0, 0, 0); for (int row = 0; row < 4; row++) { for (int col = 0; col < 4; col++) { outVal[row] += matrix[4 * col + row] * inVal[col]; } } }
public void OnRenderFrame(float deltaTime, EnumRenderStage stage) { // before rendering: update our values Mat4f.Invert(InvProjectionMatrix, _mod.CApi.Render.CurrentProjectionMatrix); Mat4f.Invert(InvModelViewMatrix, _mod.CApi.Render.CameraMatrixOriginf); _tempVec4f.Set(0, 0, 0, 1); Mat4f.MulWithVec4(InvModelViewMatrix, _tempVec4f, CameraWorldPosition); DayLight = 1.25f * GameMath.Max( _mod.CApi.World.Calendar.DayLightStrength - _mod.CApi.World.Calendar.MoonLightStrength / 2f, 0.05f); }
public void update(float dt) { if (pinned) { if (pinnedTo != null) { if (pinnedTo.ShouldDespawn && pinnedTo.DespawnReason?.reason != EnumDespawnReason.Unload) { UnPin(); return; } // New ideas: // don't apply force onto the player/entity on compression // apply huge forces onto the player on strong extension (to prevent massive stretching) (just set player motion to 0 or so. or we add a new countermotion field thats used in EntityControlledPhysics?) float weight = pinnedTo.Properties.Weight; float counterTensionStrength = GameMath.Clamp(50f / weight, 0.1f, 2f); bool extraResist = (pinnedTo as EntityAgent)?.Controls.Sneak == true || pinnedTo.AnimManager?.IsAnimationActive("sit") == true || pinnedTo.AnimManager?.IsAnimationActive("sleep") == true; float tensionResistStrength = weight / 10f * (extraResist ? 200 : 0); pinOffsetTransform.Identity(); pinOffsetTransform.RotateY(pinnedTo.SidedPos.Yaw - pinnedToOffsetStartYaw); tmpvec.Set(pinnedToOffset.X, pinnedToOffset.Y, pinnedToOffset.Z, 1); Vec4f outvec = pinOffsetTransform.TransformVector(tmpvec); EntityPos pos = pinnedTo.SidedPos; Pos.Set(pos.X + outvec.X, pos.Y + outvec.Y, pos.Z + outvec.Z); bool pushable = !(pinnedTo is EntityPlayer eplr && eplr.Player.WorldData.CurrentGameMode == EnumGameMode.Creative); if (pushable && extension > 0) // Do not act on compressive force { float f = counterTensionStrength * dt * 0.003f; pos.Motion.Add( GameMath.Clamp(Math.Abs(TensionDirection.X) - tensionResistStrength, 0, 400) * f * Math.Sign(TensionDirection.X), GameMath.Clamp(Math.Abs(TensionDirection.Y) - tensionResistStrength, 0, 400) * f * Math.Sign(TensionDirection.Y), GameMath.Clamp(Math.Abs(TensionDirection.Z) - tensionResistStrength, 0, 400) * f * Math.Sign(TensionDirection.Z) ); } Velocity.Set(0, 0, 0); } else { Velocity.Set(0, 0, 0); accum1s += dt; if (accum1s >= 1) { accum1s = 0; Block block = cs.api.World.BlockAccessor.GetBlock(PinnedToBlockPos); if (!block.HasBehavior <BlockBehaviorRopeTieable>()) { UnPin(); } } } return; } // Calculate the force on this ball Vec3f force = Tension.Clone(); force.Y -= GravityStrength * 10; // Calculate the acceleration Vec3f acceleration = force * (float)InvMass; if (CollideFlags == 0) { acceleration.X += (float)cs.windSpeed.X * InvMass; } // Update velocity Vec3f nextVelocity = Velocity + (acceleration * dt); // Damp the velocity nextVelocity *= dampFactor; // Collision detection float size = 0.1f; cs.pp.HandleBoyancy(Pos, nextVelocity, cs.boyant, GravityStrength, dt, size); CollideFlags = cs.pp.UpdateMotion(Pos, nextVelocity, size); dt *= 0.99f; Pos.Add(nextVelocity.X * dt, nextVelocity.Y * dt, nextVelocity.Z * dt); Velocity.Set(nextVelocity); Tension.Set(0, 0, 0); }