I am trying to recreate the mod in the YouTuber TommyInnit's video "Minecraft’s Laser Eye Mod Is Hilarious" as me and my friends wish to use it but we couldn't find it on the internet, and I have taken code from here for raycasting and also set up a keybind, but I cannot figure out how to setb the block you are looking at. I have tried to manage to get the block and set it but I can only find how to make new blocks that don't yet exist. My code is the following, with the block code being on line 142:
package net.laser.eyes;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.LiteralText;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.event.client.ClientTickCallback;
import net.fabricmc.api.*;
import net.fabricmc.fabric.api.client.rendering.v1.*;
import net.minecraft.block.*;
import net.minecraft.client.*;
import net.minecraft.client.gui.*;
import net.minecraft.client.util.math.*;
import net.minecraft.entity.*;
import net.minecraft.entity.decoration.*;
import net.minecraft.entity.projectile.*;
import net.minecraft.text.*;
import net.minecraft.util.hit.*;
import net.minecraft.util.math.*;
import net.minecraft.world.*;
public class main implements ModInitializer {
#Override
public void onInitialize() {
KeyBinding binding1 = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.laser-eyes.shoot", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, "key.category.laser.eyes"));
HudRenderCallback.EVENT.register(main::displayBoundingBox);
ClientTickCallback.EVENT.register(client -> {
while (binding1.wasPressed()) {
client.player.sendMessage(new LiteralText("Key 1 was pressed!"), false);
}
});
}
private static long lastCalculationTime = 0;
private static boolean lastCalculationExists = false;
private static int lastCalculationMinX = 0;
private static int lastCalculationMinY = 0;
private static int lastCalculationWidth = 0;
private static int lastCalculationHeight = 0;
private static void displayBoundingBox(MatrixStack matrixStack, float tickDelta) {
long currentTime = System.currentTimeMillis();
if(lastCalculationExists && currentTime - lastCalculationTime < 1000/45) {
drawHollowFill(matrixStack, lastCalculationMinX, lastCalculationMinY,
lastCalculationWidth, lastCalculationHeight, 2, 0xffff0000);
return;
}
lastCalculationTime = currentTime;
MinecraftClient client = MinecraftClient.getInstance();
int width = client.getWindow().getScaledWidth();
int height = client.getWindow().getScaledHeight();
Vec3d cameraDirection = client.cameraEntity.getRotationVec(tickDelta);
double fov = client.options.fov;
double angleSize = fov/height;
Vector3f verticalRotationAxis = new Vector3f(cameraDirection);
verticalRotationAxis.cross(Vector3f.POSITIVE_Y);
if(!verticalRotationAxis.normalize()) {
lastCalculationExists = false;
return;
}
Vector3f horizontalRotationAxis = new Vector3f(cameraDirection);
horizontalRotationAxis.cross(verticalRotationAxis);
horizontalRotationAxis.normalize();
verticalRotationAxis = new Vector3f(cameraDirection);
verticalRotationAxis.cross(horizontalRotationAxis);
HitResult hit = client.crosshairTarget;
if (hit.getType() == HitResult.Type.MISS) {
lastCalculationExists = false;
return;
}
int minX = width;
int maxX = 0;
int minY = height;
int maxY = 0;
for(int y = 0; y < height; y +=2) {
for(int x = 0; x < width; x+=2) {
if(minX < x && x < maxX && minY < y && y < maxY) {
continue;
}
Vec3d direction = map(
(float) angleSize,
cameraDirection,
horizontalRotationAxis,
verticalRotationAxis,
x,
y,
width,
height
);
HitResult nextHit = rayTraceInDirection(client, tickDelta, direction);//TODO make less expensive
if(nextHit == null) {
continue;
}
if(nextHit.getType() == HitResult.Type.MISS) {
continue;
}
if(nextHit.getType() != hit.getType()) {
continue;
}
if (nextHit.getType() == HitResult.Type.BLOCK) {
if(!((BlockHitResult) nextHit).getBlockPos().equals(((BlockHitResult) hit).getBlockPos())) {
continue;
}
} else if(nextHit.getType() == HitResult.Type.ENTITY) {
if(!((EntityHitResult) nextHit).getEntity().equals(((EntityHitResult) hit).getEntity())) {
continue;
}
}
if(minX > x) minX = x;
if(minY > y) minY = y;
if(maxX < x) maxX = x;
if(maxY < y) maxY = y;
}
}
lastCalculationExists = true;
lastCalculationMinX = minX;
lastCalculationMinY = minY;
lastCalculationWidth = maxX - minX;
lastCalculationHeight = maxY - minY;
drawHollowFill(matrixStack, minX, minY, maxX - minX, maxY - minY, 2, 0xffff0000);
LiteralText text = new LiteralText("Bounding " + minX + " " + minY + " " + width + " " + height + ": ");
client.player.sendMessage(text.append(getLabel(hit)), true);
//SET THE BLOCK (maybe use hit.getPos(); to find it??)
}
private static void drawHollowFill(MatrixStack matrixStack, int x, int y, int width, int height, int stroke, int color) {
matrixStack.push();
matrixStack.translate(x-stroke, y-stroke, 0);
width += stroke *2;
height += stroke *2;
DrawableHelper.fill(matrixStack, 0, 0, width, stroke, color);
DrawableHelper.fill(matrixStack, width - stroke, 0, width, height, color);
DrawableHelper.fill(matrixStack, 0, height - stroke, width, height, color);
DrawableHelper.fill(matrixStack, 0, 0, stroke, height, color);
matrixStack.pop();
}
private static Text getLabel(HitResult hit) {
if(hit == null) return new LiteralText("null");
switch (hit.getType()) {
case BLOCK:
return getLabelBlock((BlockHitResult) hit);
case ENTITY:
return getLabelEntity((EntityHitResult) hit);
case MISS:
default:
return new LiteralText("null");
}
}
private static Text getLabelEntity(EntityHitResult hit) {
return hit.getEntity().getDisplayName();
}
private static Text getLabelBlock(BlockHitResult hit) {
BlockPos blockPos = hit.getBlockPos();
BlockState blockState = MinecraftClient.getInstance().world.getBlockState(blockPos);
Block block = blockState.getBlock();
return block.getName();
}
private static Vec3d map(float anglePerPixel, Vec3d center, Vector3f horizontalRotationAxis,
Vector3f verticalRotationAxis, int x, int y, int width, int height) {
float horizontalRotation = (x - width/2f) * anglePerPixel;
float verticalRotation = (y - height/2f) * anglePerPixel;
final Vector3f temp2 = new Vector3f(center);
temp2.rotate(verticalRotationAxis.getDegreesQuaternion(verticalRotation));
temp2.rotate(horizontalRotationAxis.getDegreesQuaternion(horizontalRotation));
return new Vec3d(temp2);
}
private static HitResult rayTraceInDirection(MinecraftClient client, float tickDelta, Vec3d direction) {
Entity entity = client.getCameraEntity();
if (entity == null || client.world == null) {
return null;
}
double reachDistance = 5.0F;
HitResult target = rayTrace(entity, reachDistance, tickDelta, false, direction);
boolean tooFar = false;
double extendedReach = 6.0D;
reachDistance = extendedReach;
Vec3d cameraPos = entity.getCameraPosVec(tickDelta);
extendedReach = extendedReach * extendedReach;
if (target != null) {
extendedReach = target.getPos().squaredDistanceTo(cameraPos);
}
Vec3d vec3d3 = cameraPos.add(direction.multiply(reachDistance));
Box box = entity
.getBoundingBox()
.stretch(entity.getRotationVec(1.0F).multiply(reachDistance))
.expand(1.0D, 1.0D, 1.0D);
EntityHitResult entityHitResult = ProjectileUtil.raycast(
entity,
cameraPos,
vec3d3,
box,
(entityx) -> !entityx.isSpectator() && entityx.collides(),
extendedReach
);
if (entityHitResult == null) {
return target;
}
Entity entity2 = entityHitResult.getEntity();
Vec3d hitPos = entityHitResult.getPos();
if (cameraPos.squaredDistanceTo(hitPos) < extendedReach || target == null) {
target = entityHitResult;
if (entity2 instanceof LivingEntity || entity2 instanceof ItemFrameEntity) {
client.targetedEntity = entity2;
}
}
return target;
}
private static HitResult rayTrace(
Entity entity,
double maxDistance,
float tickDelta,
boolean includeFluids,
Vec3d direction
) {
Vec3d end = entity.getCameraPosVec(tickDelta).add(direction.multiply(maxDistance));
return entity.world.raycast(new RaycastContext(
entity.getCameraPosVec(tickDelta),
end,
RaycastContext.ShapeType.OUTLINE,
includeFluids ? RaycastContext.FluidHandling.ANY : RaycastContext.FluidHandling.NONE,
entity
));
}
}
Firstly, I heavily recommend following the standard Java naming conventions as it will make your code more understandable for others.
The technical name for a block present in the world at a specific position is a "Block State", represented by the BlockState class.
You can only change the block state at a specific position on the server-side. Your raycasting code in ran on the client-side, so you need to use the Fabric Networking API. You can see the server-side Javadoc here and the client-side Javadoc here.
Thankfully, Fabric Wiki has a networking tutorial so you don't have to read all that Javadoc. The part that you're interested in is "sending packets to the server and receiving packets on the server".
Here's a guide specific for your use case:
Introduction to Networking
Minecraft operates in two different components; the client and the server.
The client is responsible for doing jobs such as rendering and GUIs, while the server is responsible for handling the world storage, entity AI etc. (talking about logical client and server here)
The physical server and physical client are the actual JAR files that are run.
The physical (dedicated) server contains only the logical server, while a physical client contains both a logical (integrated) server and a logical client.
A diagram that explains it can be found here.
So, the logical client cannot change the state of the logical server (e.g. block states in a world), so packets have to be sent from the client to the server in order for the server to respond.
The following code is only example code, and you shouldn't copy it! You should think about safety precautions like preventing cheat clients from changing every block. Probably one of the most important rules in networking: assume the client is lying.
The Fabric Networking API
Your starting points are ServerPlayNetworking and ClientPlayNetworking. They are the classes that help you send and receive packets.
Register a listener using registerGlobalReceiver, and send a packet by using send.
You first need an Identifier in order to separate your packet from other packets and make sure it is interpreted correctly. An Identifier like this is recommended to be put in a static field in your ModInitializer or a utility class.
public class MyMod implements ModInitializer {
public static final Identifier SET_BLOCK_PACKET = new Identifier("modid", "setblock");
}
(Don't forget to replace modid with your mod ID)
You usually want to pass data with your packets (e.g. block position and block to change to), and you can do so with a PacketByteBuf.
Let's Piece This all Together
So, we have an Identifier. Let's send a packet!
Client-Side
We will start by creating a PacketByteBuf and writing the correct data:
private static void displayBoundingBox(MatrixStack matrixStack, float tickDelta) {
// ...
PacketByteBuf data = PacketByteBufs.create();
buf.writeBlockPos(hit.getPos());
// Minecraft doesn't have a way to write a Block to a packet, so we will write the registry name instead
buf.writeIdentifier(new Identifier("minecraft", "someblock" /*for example, "stone"*/));
}
And now sending the packet
// ...
ClientPlayNetworking.send(SET_BLOCK_PACKET, buf);
Server-Side
A packet with the SET_BLOCK_PACKET ID has been sent, But we also need to listen and receive it on the server-side. We can do that by using ServerPlayNetworking.registerGlobalReceiver:
#Override
public void onInitialize() {
// ...
// This code MUST be in onInitialize
ServerPlayNetworking.registerGlobalReceiver(SET_BLOCK_PACKET, (server, player, handler, buf, sender) -> {
});
}
We are using a lambda expression here. For more info about lambdas, Google is your friend.
When receiving a packet, code inside your lambda will be executed on the network thread. This code is not allowed to modify anything related to in-game logic (i.e. the world). For that, we will use server.execute(Runnable).
You should read the buf on the network thread, though.
ServerPlayNetworking.registerGlobalReceiver(SET_BLOCK_PACKET, (server, player, handler, buf, sender) -> {
BlockPos pos = buf.readBlockPos(); // reads must be done in the same order
Block blockToSet = Registry.BLOCK.get(buf.readIdentifier()); // reading using the identifier
server.execute(() -> { // We are now on the main thread
// In a normal mod, checks will be done here to prevent the client from setting blocks outside the world etc. but this is only example code
player.getServerWorld().setBlockState(pos, blockToSet.getDefaultState()); // changing the block state
});
});
Once again, you should prevent the client from sending invalid locations
Related
I'm trying to edit the Third Person Controller script that's found in the 'Starter Assets' pack created by Unity (https://assetstore.unity.com/packages/essentials/starter-assets-third-person-character-controller-196526)
Note: Just a heads up that I am extremely new to coding, so please be as detailed with your answer as possible. Thanks in advance, I really appreciate it.
Current Situation (note: I'm building for mobile) -
My character moves forwards, diagonally forwards (top left, top right), and both left/right correctly and rotates to face that direction. The follow camera stays behind the character and rotates when the character does. This is all great.
The Problem - When my character moves backwards (pressing 'S' on the keyboard or 'Down on the Joystick' (mobile)) the character rotates causing the camera and character to rotate continuously on the spot. This is also the case when moving diagonally backwards (bottom left, bottom right).
What I Want To Achieve - I want it so that when backward input is detected, but only backwards, the character moves backward with no rotation to either the player or camera. Moving diagonally backwards however I would still like the rotation for the camera (not the player) but in the opposite direction.
Here is the part of the script that I believe controls this. If you could please assist me on how to edit, what to add/remove, that would be amazing.
// normalise input direction
Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
// note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is a move input rotate player when the player is moving
if (_input.move != Vector2.zero)
{
_targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg +
_mainCamera.transform.eulerAngles.y;
float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity,
RotationSmoothTime);
// rotate to face input direction relative to camera position
transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
}
Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
// move the player
_controller.Move(targetDirection.normalized * (_speed * Time.deltaTime) +
new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
Just in case the full script is required to assist me, please see it below;
using UnityEngine;
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
using UnityEngine.InputSystem;
#endif
/* Note: animations are called via the controller for both the character and capsule using animator null checks
*/
namespace StarterAssets
{
[RequireComponent(typeof(CharacterController))]
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
[RequireComponent(typeof(PlayerInput))]
#endif
public class ThirdPersonController : MonoBehaviour
{
[Header("Player")]
[Tooltip("Move speed of the character in m/s")]
public float MoveSpeed = 2.0f;
[Tooltip("Sprint speed of the character in m/s")]
public float SprintSpeed = 5.335f;
[Tooltip("How fast the character turns to face movement direction")]
[Range(0.0f, 0.3f)]
public float RotationSmoothTime = 0.12f;
[Tooltip("Acceleration and deceleration")]
public float SpeedChangeRate = 10.0f;
public AudioClip LandingAudioClip;
public AudioClip[] FootstepAudioClips;
[Range(0, 1)] public float FootstepAudioVolume = 0.5f;
[Space(10)]
[Tooltip("The height the player can jump")]
public float JumpHeight = 1.2f;
[Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
public float Gravity = -15.0f;
[Space(10)]
[Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
public float JumpTimeout = 0.50f;
[Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
public float FallTimeout = 0.15f;
[Header("Player Grounded")]
[Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
public bool Grounded = true;
[Tooltip("Useful for rough ground")]
public float GroundedOffset = -0.14f;
[Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
public float GroundedRadius = 0.28f;
[Tooltip("What layers the character uses as ground")]
public LayerMask GroundLayers;
[Header("Cinemachine")]
[Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
public GameObject CinemachineCameraTarget;
[Tooltip("How far in degrees can you move the camera up")]
public float TopClamp = 70.0f;
[Tooltip("How far in degrees can you move the camera down")]
public float BottomClamp = -30.0f;
[Tooltip("Additional degress to override the camera. Useful for fine tuning camera position when locked")]
public float CameraAngleOverride = 0.0f;
[Tooltip("For locking the camera position on all axis")]
public bool LockCameraPosition = false;
// cinemachine
private float _cinemachineTargetYaw;
private float _cinemachineTargetPitch;
// player
private float _speed;
private float _animationBlend;
private float _targetRotation = 0.0f;
private float _rotationVelocity;
private float _verticalVelocity;
private float _terminalVelocity = 53.0f;
// timeout deltatime
private float _jumpTimeoutDelta;
private float _fallTimeoutDelta;
// animation IDs
private int _animIDSpeed;
private int _animIDGrounded;
private int _animIDJump;
private int _animIDFreeFall;
private int _animIDMotionSpeed;
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
private PlayerInput _playerInput;
#endif
private Animator _animator;
private CharacterController _controller;
private StarterAssetsInputs _input;
private GameObject _mainCamera;
private const float _threshold = 0.01f;
private bool _hasAnimator;
private bool IsCurrentDeviceMouse
{
get
{
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
return _playerInput.currentControlScheme == "KeyboardMouse";
#else
return false;
#endif
}
}
private void Awake()
{
// get a reference to our main camera
if (_mainCamera == null)
{
_mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
}
}
private void Start()
{
_cinemachineTargetYaw = CinemachineCameraTarget.transform.rotation.eulerAngles.y;
_hasAnimator = TryGetComponent(out _animator);
_controller = GetComponent<CharacterController>();
_input = GetComponent<StarterAssetsInputs>();
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
_playerInput = GetComponent<PlayerInput>();
#else
Debug.LogError( "Starter Assets package is missing dependencies. Please use Tools/Starter Assets/Reinstall Dependencies to fix it");
#endif
AssignAnimationIDs();
// reset our timeouts on start
_jumpTimeoutDelta = JumpTimeout;
_fallTimeoutDelta = FallTimeout;
}
private void Update()
{
_hasAnimator = TryGetComponent(out _animator);
JumpAndGravity();
GroundedCheck();
Move();
}
private void LateUpdate()
{
CameraRotation();
}
private void AssignAnimationIDs()
{
_animIDSpeed = Animator.StringToHash("Speed");
_animIDGrounded = Animator.StringToHash("Grounded");
_animIDJump = Animator.StringToHash("Jump");
_animIDFreeFall = Animator.StringToHash("FreeFall");
_animIDMotionSpeed = Animator.StringToHash("MotionSpeed");
}
private void GroundedCheck()
{
// set sphere position, with offset
Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset,
transform.position.z);
Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers,
QueryTriggerInteraction.Ignore);
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDGrounded, Grounded);
}
}
private void CameraRotation()
{
// if there is an input and camera position is not fixed
if (_input.look.sqrMagnitude >= _threshold && !LockCameraPosition)
{
//Don't multiply mouse input by Time.deltaTime;
float deltaTimeMultiplier = IsCurrentDeviceMouse ? 0.1f : Time.deltaTime;
_cinemachineTargetYaw += _input.look.x * deltaTimeMultiplier;
_cinemachineTargetPitch += _input.look.y * deltaTimeMultiplier;
}
// clamp our rotations so our values are limited 360 degrees
_cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
_cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
// Cinemachine will follow this target
CinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride,
_cinemachineTargetYaw, 0.0f);
}
private void Move()
{
// set target speed based on move speed, sprint speed and if sprint is pressed
float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
// a simplistic acceleration and deceleration designed to be easy to remove, replace, or iterate upon
// note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is no input, set the target speed to 0
if (_input.move == Vector2.zero) targetSpeed = 0.0f;
// a reference to the players current horizontal velocity
float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
float speedOffset = 0.1f;
float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 0.0f;
// accelerate or decelerate to target speed
if (currentHorizontalSpeed < targetSpeed - speedOffset ||
currentHorizontalSpeed > targetSpeed + speedOffset)
{
// creates curved result rather than a linear one giving a more organic speed change
// note T in Lerp is clamped, so we don't need to clamp our speed
_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude,
Time.deltaTime * SpeedChangeRate);
// round speed to 3 decimal places
_speed = Mathf.Round(_speed * 1000f) / 1000f;
}
else
{
_speed = targetSpeed;
}
_animationBlend = Mathf.Lerp(_animationBlend, targetSpeed, Time.deltaTime * SpeedChangeRate);
if (_animationBlend < 0.01f) _animationBlend = 0f;
// normalise input direction
Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
// note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
// if there is a move input rotate player when the player is moving
if (_input.move != Vector2.zero)
{
_targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg +
_mainCamera.transform.eulerAngles.y;
float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity,
RotationSmoothTime);
// rotate to face input direction relative to camera position
transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
}
Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
// move the player
_controller.Move(targetDirection.normalized * (_speed * Time.deltaTime) +
new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
// update animator if using character
if (_hasAnimator)
{
_animator.SetFloat(_animIDSpeed, _animationBlend);
_animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
}
}
private void JumpAndGravity()
{
if (Grounded)
{
// reset the fall timeout timer
_fallTimeoutDelta = FallTimeout;
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDJump, false);
_animator.SetBool(_animIDFreeFall, false);
}
// stop our velocity dropping infinitely when grounded
if (_verticalVelocity < 0.0f)
{
_verticalVelocity = -2f;
}
// Jump
if (_input.jump && _jumpTimeoutDelta <= 0.0f)
{
// the square root of H * -2 * G = how much velocity needed to reach desired height
_verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDJump, true);
}
}
// jump timeout
if (_jumpTimeoutDelta >= 0.0f)
{
_jumpTimeoutDelta -= Time.deltaTime;
}
}
else
{
// reset the jump timeout timer
_jumpTimeoutDelta = JumpTimeout;
// fall timeout
if (_fallTimeoutDelta >= 0.0f)
{
_fallTimeoutDelta -= Time.deltaTime;
}
else
{
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDFreeFall, true);
}
}
// if we are not grounded, do not jump
_input.jump = false;
}
// apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
if (_verticalVelocity < _terminalVelocity)
{
_verticalVelocity += Gravity * Time.deltaTime;
}
}
private static float ClampAngle(float lfAngle, float lfMin, float lfMax)
{
if (lfAngle < -360f) lfAngle += 360f;
if (lfAngle > 360f) lfAngle -= 360f;
return Mathf.Clamp(lfAngle, lfMin, lfMax);
}
private void OnDrawGizmosSelected()
{
Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
if (Grounded) Gizmos.color = transparentGreen;
else Gizmos.color = transparentRed;
// when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
Gizmos.DrawSphere(
new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z),
GroundedRadius);
}
private void OnFootstep(AnimationEvent animationEvent)
{
if (animationEvent.animatorClipInfo.weight > 0.5f)
{
if (FootstepAudioClips.Length > 0)
{
var index = Random.Range(0, FootstepAudioClips.Length);
AudioSource.PlayClipAtPoint(FootstepAudioClips[index], transform.TransformPoint(_controller.center), FootstepAudioVolume);
}
}
}
private void OnLand(AnimationEvent animationEvent)
{
if (animationEvent.animatorClipInfo.weight > 0.5f)
{
AudioSource.PlayClipAtPoint(LandingAudioClip, transform.TransformPoint(_controller.center), FootstepAudioVolume);
}
}
}
}
i need to create a Service and a Task to calculate the Mandelbrot and JuliaSet.
The calculation is working pretty good and now we need to give it into a Service and call it inside the task.
I have now the Problem, that every Time the task is executed, the Parameters are different.
I wrote a little Setter Function to parse those Arguments to the Service first.
But i'm not sure if this is the right Way?!
I'm also not sure how to correctly call the service in the main Function?
Now it works like this:
First time the service is executed, everything seems to work, but when i call it a secound Time, nothing seems to happen.....
Just to make sure: A Service can execute the Task multiple Times at the same Time?
Is it also posible with different Parameters?
Code Task:
private MandelbrotRenderOptions mandelbrot;
private JuliaRenderOptions juliaset;
private Canvas leftCanvas;
private Canvas rightCanvas;
//Constructor
public RenderTask(Canvas leftCanvas, Canvas rightCanvas) {
this.leftCanvas = leftCanvas;
this.rightCanvas = rightCanvas;
}
public void setOptions(MandelbrotRenderOptions mandelbrot, JuliaRenderOptions juliaset) {
this.mandelbrot = mandelbrot;
this.juliaset = juliaset;
}
#Override
protected Void call() throws Exception {
try {
System.out.println("HALLO SERVICE");
// instances for rendering the left canvas [pixel.data -> PixelWriter -> WritableImage -> GraphicsContext -> Canvas]
// creates an writable image which contains the dimensions of the canvas
WritableImage wimLeftCanvas = new WritableImage((int) leftCanvas.getWidth(), (int) leftCanvas.getHeight());
// instance which can write data into the image (instance above)
PixelWriter pwLeftCanvas = wimLeftCanvas.getPixelWriter();
// instance which fills the canvas
GraphicsContext gcLeftCanvas = leftCanvas.getGraphicsContext2D();
// instances for rendering the right canvas [pixel.data -> PixelWriter -> WritableImage -> GraphicsContext -> Canvas]
WritableImage wimRightCanvas = new WritableImage((int) rightCanvas.getWidth(), (int) rightCanvas.getHeight());
PixelWriter pwRight = wimRightCanvas.getPixelWriter();
GraphicsContext gcRightCanvas = rightCanvas.getGraphicsContext2D();
gcLeftCanvas.clearRect(0, 0, leftCanvas.getWidth(), leftCanvas.getHeight());
//Pixel[][] pixels; // contains pixel data for rendering canvas
// instances for logging the rendered data
SimpleImage simpleImageLeftCanvas = new SimpleImage((int) leftCanvas.getWidth(), (int) leftCanvas.getHeight());
SimpleImage simpleImageRightCanvas = new SimpleImage((int) rightCanvas.getWidth(), (int) rightCanvas.getHeight());
short dataSimpleImage[] = new short[3]; // contains pixel data for logging rendered data
// fills left canvas (mandelbrot) PixelWriter instance with data
Pixel[][] pixels = mandelbrot.setAllPixels();
FractalLogger.logRenderCall(mandelbrot);
for (int y = 0; y < (int) leftCanvas.getHeight(); y++) {
for (int x = 0; x < (int) leftCanvas.getWidth(); x++) {
// parses color data to PixelWriter instance
Color color = Color.rgb(pixels[y][x].getRed(), pixels[y][x].getGreen(), pixels[y][x].getBlue());
pwLeftCanvas.setColor(x, y, color);
for (int depth = 0; depth < 3; depth++) {
if (depth == 0) {
dataSimpleImage[depth] = pixels[y][x].getRed();
} else if (depth == 1) {
dataSimpleImage[depth] = pixels[y][x].getGreen();
} else {
dataSimpleImage[depth] = pixels[y][x].getBlue();
}
}
try {
simpleImageLeftCanvas.setPixel(x, y, dataSimpleImage); // because data must not be null
} catch (InvalidDepthException e) {
e.printStackTrace();
}
}
}
// logs that rendering of mandelbrot is finished
FractalLogger.logRenderFinished(FractalType.MANDELBROT, simpleImageLeftCanvas);
// fills left canvas (juliaset) PixelWriter instance with data
pixels = juliaset.setAllPixels();
FractalLogger.logRenderCall(mandelbrot);
for (int y = 0; y < (int) rightCanvas.getHeight(); y++) {
for (int x = 0; x < (int) rightCanvas.getWidth(); x++) {
// pareses color to PixelWriter instance
Color color = Color.rgb(pixels[y][x].getRed(), pixels[y][x].getGreen(), pixels[y][x].getBlue());
pwRight.setColor(x, y, color);
for (int depth = 0; depth < 3; depth++) {
if (depth == 0) {
dataSimpleImage[depth] = pixels[y][x].getRed();
} else if (depth == 1) {
dataSimpleImage[depth] = pixels[y][x].getGreen();
} else {
dataSimpleImage[depth] = pixels[y][x].getBlue();
}
}
try {
simpleImageRightCanvas.setPixel(x, y, dataSimpleImage); // because data must not be null
} catch (InvalidDepthException e) {
e.printStackTrace();
}
}
}
// logs that rendering of juliaset is finished
FractalLogger.logRenderFinished(FractalType.JULIA, simpleImageRightCanvas);
// writes data from WriteableImage instance to GraphicsContext instance, which finally parses renders it into the canvas
gcLeftCanvas.drawImage(wimLeftCanvas, 0, 0);
FractalLogger.logDrawDone(FractalType.MANDELBROT);
gcRightCanvas.drawImage(wimRightCanvas, 0, 0);
FractalLogger.logDrawDone(FractalType.JULIA);
return null;
} catch (Exception e) {
System.out.println("ERROR");
System.out.println(e);
return null;
}
}
#Override
protected void cancelled()
{
super.cancelled();
updateMessage("The task was cancelled.");
}
#Override
protected void failed()
{
super.failed();
updateMessage("The task failed.");
}
#Override
public void succeeded()
{
super.succeeded();
updateMessage("The task finished successfully.");
} ```
And i call it like this in the main:
``` Service service = new Service() {
#Override
protected Task createTask() {
return new RenderTask(leftCanvas, rightCanvas);
}
};
task.setOptions(mandelbrot, juliaset);
service.restart(); ```
I were trying to make a camera application, I'm unable to find a way to change camera brightness, contrast using Camera.Parameters
So my question is how to add Brightness and contrast feature to increase/decrease brightness/contrast. For example if I increase the seekbarit increase the brightness. if I decrease the seekbar it decrease the brightness.
Please edit my code or put your seprate answer to help me.
package com.example.beautymaker;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.camera2.CameraCharacteristics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.zomato.photofilters.imageprocessors.Filter;
import com.zomato.photofilters.imageprocessors.subfilters.BrightnessSubFilter;
import java.io.IOException;
import java.util.List;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
/*Camera.Parameters params = camera.getParameters();
final int[] previewFpsRange = new int[2];
params.getPreviewFpsRange(previewFpsRange);
if (previewFpsRange[0] == previewFpsRange[1]) {
final List<int[]> supportedFpsRanges = params.getSupportedPreviewFpsRange();
for (int[] range : supportedFpsRanges) {
if (range[0] != range[1]) {
params.setPreviewFpsRange(range[0], range[1]);
break;
}
}
}*/
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera == null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
setCamera;
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
Camera.Parameters parameters = mCamera.getParameters();
// parameters.setPreviewFpsRange(1500,3000);
parameters.setExposureCompensation(parameters.getMaxExposureCompensation());
if(parameters.isAutoExposureLockSupported())
{
parameters.setAutoExposureLock(false);
}
// parameters.setColorEffect(Camera.Parameters.WHITE_BALANCE_INCANDESCENT);
parameters.getAutoExposureLock();
parameters.set("iso",50);
// parameters.setWhiteBalance();
parameters.setAutoWhiteBalanceLock(true);
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_SHADE);
/*Filter filter = new Filter();
filter.addSubFilter(new BrightnessSubFilter(parameters));*/
mCamera.setParameters(parameters);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
// mCamera.release();
}
//for brightness
public static Bitmap doBrightness(Bitmap src, int value) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// increase/decrease each channel
R += value;
if(R > 255) { R = 255; }
else if(R < 0) { R = 0; }
G += value;
if(G > 255) { G = 255; }
else if(G < 0) { G = 0; }
B += value;
if(B > 255) { B = 255; }
else if(B < 0) { B = 0; }
// apply new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final image
return bmOut;
}
}
there is no method in Camera.Parameters to achieve this. You have to read this documentation for this class to check the available parameters and this class is deprecated in API 21 and above.
Is there an alternative for the getUserPixels method offered by OpenNI in the official Kinect SDK?
How would one implement this functionality with the official Kinect SDK?
The official Kinect for Windows SDK (v1.6) does not support a direct call, such as getUserPixels, to extract a player silhouette but does contain all the information necessary to do so.
You can see this in action, in different ways, by examining two of the examples available from the Kinect for Windows Developer Toolkit.
Basic Interactions-WPF: includes a function to create a simple silhouette of the user being tracked.
Green Screen (-WPF, or -D2D): shows how to perform background subtraction to produce a green screen effect. In this example the data from the RGB camera is superimposed over a image.
The two examples do this in different ways.
Basic Interactions will pull out a BitmapMask of from the depth data which corresponds to the requested player. This has the advantage of only showing tracked users; any object not thought to be a skeleton is ignored.
Green Screen does not look for a particular user, instead opting for motion. This gives the advantage silhouetting any moving object -- such as a ball being passed between two users.
I believe the "Basic Interactions" example will show you how you implement what you are looking for. You'll have to do the work yourself, but it is possible. For example, using the "Basic Interactions" example as a base I created a UserControl that generates a simple silhouette of the user being tracked...
When the skeleton frame is ready, I pull out the player index:
private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null && skeletonFrame.SkeletonArrayLength > 0)
{
if (_skeletons == null || _skeletons.Length != skeletonFrame.SkeletonArrayLength)
{
_skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
}
skeletonFrame.CopySkeletonDataTo(_skeletons);
// grab the tracked skeleton and set the playerIndex for use pulling
// the depth data out for the silhouette.
// NOTE: this assumes only a single tracked skeleton!
this.playerIndex = -1;
for (int i = 0; i < _skeletons.Length; i++)
{
if (_skeletons[i].TrackingState != SkeletonTrackingState.NotTracked)
{
this.playerIndex = i+1;
}
}
}
}
}
Then, when the next depth frame is ready, I pull out BitmapMask for the user that corresponds to playerIndex.
private void OnDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame != null)
{
// check if the format has changed.
bool haveNewFormat = this.lastImageFormat != depthFrame.Format;
if (haveNewFormat)
{
this.pixelData = new short[depthFrame.PixelDataLength];
this.depthFrame32 = new byte[depthFrame.Width * depthFrame.Height * Bgra32BytesPerPixel];
this.convertedDepthBits = new byte[this.depthFrame32.Length];
}
depthFrame.CopyPixelDataTo(this.pixelData);
for (int i16 = 0, i32 = 0; i16 < pixelData.Length && i32 < depthFrame32.Length; i16++, i32 += 4)
{
int player = pixelData[i16] & DepthImageFrame.PlayerIndexBitmask;
if (player == this.playerIndex)
{
convertedDepthBits[i32 + RedIndex] = 0x44;
convertedDepthBits[i32 + GreenIndex] = 0x23;
convertedDepthBits[i32 + BlueIndex] = 0x59;
convertedDepthBits[i32 + 3] = 0x66;
}
else if (player > 0)
{
convertedDepthBits[i32 + RedIndex] = 0xBC;
convertedDepthBits[i32 + GreenIndex] = 0xBE;
convertedDepthBits[i32 + BlueIndex] = 0xC0;
convertedDepthBits[i32 + 3] = 0x66;
}
else
{
convertedDepthBits[i32 + RedIndex] = 0x0;
convertedDepthBits[i32 + GreenIndex] = 0x0;
convertedDepthBits[i32 + BlueIndex] = 0x0;
convertedDepthBits[i32 + 3] = 0x0;
}
}
if (silhouette == null || haveNewFormat)
{
silhouette = new WriteableBitmap(
depthFrame.Width,
depthFrame.Height,
96,
96,
PixelFormats.Bgra32,
null);
SilhouetteImage.Source = silhouette;
}
silhouette.WritePixels(
new Int32Rect(0, 0, depthFrame.Width, depthFrame.Height),
convertedDepthBits,
depthFrame.Width * Bgra32BytesPerPixel,
0);
Silhouette = silhouette;
this.lastImageFormat = depthFrame.Format;
}
}
}
What I end up with is a purple silhouette of the user in a WriteableBitmap, which can be copied to an Image on the control or pulled and used elsewhere. Once you have the BitmapMask you could also map the data the color stream if you wanted a to actually see the RGB data that corresponds to that area.
You can adapt the code to simulate more closely the getUserPixels function if you like. The big part you'd be interested in would be, given a depth frame and a playerIndex:
if (depthFrame != null)
{
// check if the format has changed.
bool haveNewFormat = this.lastImageFormat != depthFrame.Format;
if (haveNewFormat)
{
this.pixelData = new short[depthFrame.PixelDataLength];
this.depthFrame32 = new byte[depthFrame.Width * depthFrame.Height * Bgra32BytesPerPixel];
this.convertedDepthBits = new byte[this.depthFrame32.Length];
}
depthFrame.CopyPixelDataTo(this.pixelData);
for (int i16 = 0, i32 = 0; i16 < pixelData.Length && i32 < depthFrame32.Length; i16++, i32 += 4)
{
int player = pixelData[i16] & DepthImageFrame.PlayerIndexBitmask;
if (player == this.playerIndex)
{
// this pixel "belongs" to the user identified in "playerIndex"
}
else
{
// not the requested user
}
}
}
hi my problem is that in my code i am calling a method that calculates the different between 2 point and then if that distance is less that 7 it will call another class method that should change the color of the target to red... my problem is that in my arraylist i have 3 or five or depends on the user input targets... so how can i specify the object in my arraylist that is going to be change of color>??? this is my code
package project1;
import java.util.*;
import javax.swing.*;
/**
*
* #author Elvis De Abreu
*/
public class TargetGallery
{
/**ArrayList of Targets initialize as a private*/
private ArrayList<Target> mytargets = new ArrayList<>();
/**Static object for the Target class*/
static Target tg = new Target();
/**Static object for the RifleSite class*/
static RifleSite rs = new RifleSite();
/**Static object for the TargetGallery class*/
static TargetGallery tgy = new TargetGallery();
/**the number of targets input by the user as private*/
private int number = 0;
/**array that store the distance between 2 point for each target*/
private double[] total;
/**
* Method that build the background of the canvas
* with a picture as a environment
*/
private void buildWorld()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(75, 130, "bath.jpeg", 450, 285);
}
/**
* Method that draw a weapon in the middle of the
* canvas as a shooter weapon
*/
private void drawShooter()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(125, 0, "weapon.png", 80, 45);
}
/**
* randomly generates X locations for the targets
* add them into the array list
*/
private void createTargets()
{
double x = 125;
double y = 175;
double radius = 7;
String input = JOptionPane.showInputDialog("Type a number" +
"between 2 and 5");
number = Integer.parseInt(input);
for(int i = 0; i < number; i++)
{
Target targ = new Target(x, y, radius);
mytargets.add(targ);
Random rand = new Random();
x = rand.nextInt(400) + 10;
for (Target e: mytargets)
{
if ((e.getX() <= (x+10)) || (e.getX() >= (x-10)))
{
mytargets.clear();
i--;
continue;
}
}
}
}
/**
* Method that run different methods which start the program
*/
public void run()
{
tgy.buildWorld(); //call the buildWorld method
tgy.drawShooter(); //call the drawShooter method
tgy.createTargets(); //call the createTarget method
tgy.simulate(); //call the simulate method
}
/**
* calculates the distance between the RifleSite and the Targets
*/
public void calcDistance()
{
//variable declaration/initialization
double distance;
double distance1;
int i = 0;
total = new double[number];
//for each loop to calculate x and y location of RifleSite and Targets
for (Target e: mytargets)
{
distance = Math.pow(e.getX()-rs.getX(), 2.0);
distance1 = Math.pow(e.getY()-rs.getY(), 2.0);
total[i++] = Math.sqrt(distance + distance1);
}
}
/**
* Method that simulates the game
*/
public void simulate()
{
//Variable declaration/initialization
boolean alive = true;
for(Target e: mytargets)
{
e.drawAlive();
}
rs.drawRifleSite();
//loop that will run while there is still targets alive or user press q
while(alive == true)
{
//if user press a key this
if (StdDraw.hasNextKeyTyped())
{
char ch = StdDraw.nextKeyTyped(); //store the key pressed
//if person press Q will quit the program
if (ch == 'q')
{
int done = JOptionPane.showConfirmDialog(null,
"The Program will close now bye :)");
System.exit(0);
}
else if (ch == 'f')
{
tgy.calcDistance(); //calculates the distance
//if statement to check if the distance if less than radius
for(int i = 0; i < number; i++)
{
if (total[i] <= 7)
{
//THIS IS WHERE MY METHOD SHOULD GO
//SHOULD BE SOMETHING LIKE E.drawDead
}
}
}
}
}
}
/**
* Method for the main of the Program
* #param args the command line arguments
*/
public static void main(String[] args)
{
}
}
Like this:mytargets.get(INDEX GO HERE)
i Hope that helps
(the index starts from 0)
For example:
Target t=mytargets.get(0);
if ((t.getX() > 10) && (t.getY() > 10))
{
//blablabla
}