From 84f8be2fb66ad3c019138baaada480dbdf240794 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:25:23 +0900 Subject: [PATCH 01/29] fix for 1.21.93 --- README.md | 104 ++++++++++++++--- plugin.yml | 6 + src/muqsit/libcamera/CameraInstruction.php | 12 +- src/muqsit/libcamera/libcamera.php | 129 +++++++++++++++++++-- src/muqsit/libcamera/libcameramain.php | 15 +++ 5 files changed, 241 insertions(+), 25 deletions(-) create mode 100644 plugin.yml create mode 100644 src/muqsit/libcamera/libcameramain.php diff --git a/README.md b/README.md index 685f06d..2b48782 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,14 @@ To send instructions to the camera, use the following code: - Set +
+ See demo + +https://github.com/user-attachments/assets/338e4b84-1ded-4424-9ffb-6e94298bc53c + +
+ + ```php use muqsit\libcamera\libcamera; use muqsit\libcamera\CameraInstruction; @@ -74,10 +82,10 @@ if($player instanceof Player && $player->isOnline()){ CameraSetInstructionEaseType::IN_OUT_CUBIC, (float) 5.0 // duration (sec) ), - camera_pos: null, + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace rot: new CameraSetInstructionRotation( - (float)20.0, //pitch - (float)180.0 //yaw + (float)$player->getLocation()->getPitch(), //pitch + (float)$player->getLocation()->getYaw() //yaw ), facing_pos: null )->send($player); @@ -108,24 +116,88 @@ if($player instanceof Player && $player->isOnline()){ - Target +After setting the camera to free mode, you need to explicitly assign a target. +This allows the camera to visually track a specific entity. +Unlike SetActorLinkPacket, it does not follow the entity automatically. + +
+ See demo + +https://github.com/user-attachments/assets/38cd6bf1-f666-4635-870b-2d51b12bfa3f + +
+ ```php -use muqsit\libcamera\libcamera; +use pocketmine\event\player\PlayerInteractEvent; use muqsit\libcamera\CameraInstruction; -use pocketmine\network\mcpe\protocol\types\camera\CameraTargetInstruction; +use pocketmine\entity\Zombie; +use muqsit\libcamera\libcamera; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEase; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEaseType; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionRotation; use pocketmine\math\Vector3; -use pocketmine\player\Player; // ... -if($player instanceof Player && $player->isOnline()){ - /** - * @phpstan-param Vector3|null $targetCenterOffset - * @phpstan-param int $actorUniqueId - */ - CameraInstruction::target( - targetCenterOffset: Vector3::zero(), // no offset - actorUniqueId: $player->getId() // for example target the player - )->send($player); -} + + /** @var array */ + private $set = []; + + public function ina(PlayerInteractEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + + //Removes camera tracking. Note that target and free cameras are managed separately. + if(isset($this->set[$player->getName()])){ + CameraInstruction::removeTarget()->send($player); + CameraInstruction::clear()->send($player); + unset($this->set[$player->getName()]); + return; + } + + //Find the most different zombie entities + $nearest = null; + $nearestDistance = PHP_INT_MAX; + foreach($player->getWorld()->getEntities() as $entity){ + if($entity instanceof Zombie){ + $distance = $player->getPosition()->distance($entity->getPosition()); + if($nearestDistance >= $distance){ + $nearest = $entity; + $nearestDistance = $distance; + } + } + } + + if($nearest === null){ + $player->sendMessage("No Zombie"); + return; + } + + // + CameraInstruction::set( + preset: libcamera::getPresetRegistry()->registered["target"], + ease: new CameraSetInstructionEase( + CameraSetInstructionEaseType::IN_OUT_CUBIC, + (float) 5.0 // duration (sec) + ), + camera_pos: $player->getPosition()->add(0, $player->getEyeHeight(), 0), + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: null + )->send($player); + + //To use CameraInstruction::target you first need to make it a free camera. + CameraInstruction::target( + targetCenterOffset: Vector3::zero(), // no offset + actorUniqueId: $nearest->getId() // for example target the player + )->send($player); + + //Manages which packets have been sent + $this->set[$player->getName()] = true; + } ``` - Remove Target diff --git a/plugin.yml b/plugin.yml new file mode 100644 index 0000000..9baad1d --- /dev/null +++ b/plugin.yml @@ -0,0 +1,6 @@ +--- +name: libCamera +version: 0.0.1 +main: muqsit\libcamera\libcameramain +api: 5.31.0 +... diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index dcb5933..2d88f21 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -37,7 +37,17 @@ public static function set( ?Vector3 $facing_pos = null ) : self{ $preset_id = libcamera::getPresetRegistry()->network_ids[spl_object_id($preset)]; - $instruction = new CameraSetInstruction($preset_id, $ease, $camera_pos, $rot, $facing_pos, null, null, null); + $instruction = new CameraSetInstruction( + preset: $preset_id, + ease: $ease, + cameraPosition: $camera_pos, + rotation: $rot, + facingPosition: $facing_pos, + viewOffset: null, + entityOffset: null, + default: null, + ignoreStartingValuesComponent: false + ); return new self([[$instruction, null, null, null]]); } diff --git a/src/muqsit/libcamera/libcamera.php b/src/muqsit/libcamera/libcamera.php index 841cfa3..c28c634 100644 --- a/src/muqsit/libcamera/libcamera.php +++ b/src/muqsit/libcamera/libcamera.php @@ -32,11 +32,126 @@ public static function isRegistered(): bool{ public static function register(Plugin $plugin) : void{ !self::$registered || throw new BadMethodCallException("Tried to registered an already existing libcamera instance"); $preset_registry = new CameraPresetRegistry([ - "free" => new CameraPreset("minecraft:free", "", null, null, null, null, null, null, null, null, null, null, null, null, null, null, CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, false, false, null), - "first_person" => new CameraPreset("minecraft:first_person", "", null, null, null, null, null, null, null, null, null, null, null, null, null, null, CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, false, false, null), - "third_person" => new CameraPreset("minecraft:third_person", "", null, null, null, null, null, null, null, null, null, null, null, null, null, null, CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, false, false, null), - "third_person_front" => new CameraPreset("minecraft:third_person_front", "", null, null, null, null, null, null, null, null, null, null, null, null, null, null, CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, false, false, null), - "target" => new CameraPreset("minecraft:target", "minecraft:free", null, null, null, null, null, 0.0, true, new Vector2(0.0, 360.0), new Vector2(0.0, 180.0), true, 50.0, null, null, null, CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, false, false, null) + "free" => new CameraPreset( + name: "minecraft:free", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, + playerEffects: false, + aimAssist: null, + controlScheme: null + ), + "first_person" => new CameraPreset( + name: "minecraft:first_person", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, + playerEffects: false, + aimAssist: null, + controlScheme: null + ), + "third_person" => new CameraPreset( + name: "minecraft:third_person", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, + playerEffects: false, + aimAssist: null, + controlScheme: null + ), + "third_person_front" => new CameraPreset( + name: "minecraft:third_person_front", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, + playerEffects: false, + aimAssist: null, + controlScheme: null + ), + "target" => new CameraPreset( + name: "minecraft:target", + parent: "minecraft:free", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: 0.0, + snapToTarget: true, + horizontalRotationLimit: new Vector2(0.0, 360.0), + verticalRotationLimit: new Vector2(0.0, 180.0), + continueTargeting: true, + blockListeningRadius: 50.0, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, + playerEffects: false, + aimAssist: null, + controlScheme: null + ) ]); $packet = CameraPresetsPacket::create(array_values($preset_registry->registered)); Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, function(DataPacketReceiveEvent $event) use($packet) : void{ @@ -48,9 +163,7 @@ public static function register(Plugin $plugin) : void{ foreach($event->getPackets() as $packet){ if($packet instanceof StartGamePacket){ $experiments = $packet->levelSettings->experiments->getExperiments(); - $experiments["focus_target_camera"] = true; - $experiments["third_person_cameras"] = true; - $experiments["cameras"] = true; + $experiments["experimental_creator_camera"] = true;//It seems to work without it. $packet->levelSettings->experiments = new Experiments($experiments, true); } } diff --git a/src/muqsit/libcamera/libcameramain.php b/src/muqsit/libcamera/libcameramain.php new file mode 100644 index 0000000..8956414 --- /dev/null +++ b/src/muqsit/libcamera/libcameramain.php @@ -0,0 +1,15 @@ + Date: Tue, 15 Jul 2025 14:32:24 +0900 Subject: [PATCH 02/29] update README.md --- README.md | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2b48782..7663b31 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,13 @@ if($player instanceof Player && $player->isOnline()){ - Fade +
+ See demo + +https://github.com/user-attachments/assets/01bfc489-16bd-4424-aad0-32abb81d7517 + +
+ ```php use muqsit\libcamera\libcamera; use muqsit\libcamera\CameraInstruction; @@ -103,6 +110,13 @@ use pocketmine\player\Player; // ... if($player instanceof Player && $player->isOnline()){ + $fadeInTime = 5; + $stayTime = 2; + $fadeOutTime = 2; + $r = 0; + $g = 0; + $b = 0; + /** * @phpstan-param CameraFadeInstructionColor|null $color * @phpstan-param CameraFadeInstructionTime|null $time @@ -148,7 +162,7 @@ use pocketmine\math\Vector3; return; } - //Removes camera tracking. Note that target and free cameras are managed separately. + //Removes camera tracking. Note that target and free cameras are managed separately. if(isset($this->set[$player->getName()])){ CameraInstruction::removeTarget()->send($player); CameraInstruction::clear()->send($player); @@ -156,7 +170,7 @@ use pocketmine\math\Vector3; return; } - //Find the most different zombie entities + //Find the most different zombie entities $nearest = null; $nearestDistance = PHP_INT_MAX; foreach($player->getWorld()->getEntities() as $entity){ @@ -174,7 +188,7 @@ use pocketmine\math\Vector3; return; } - // + // CameraInstruction::set( preset: libcamera::getPresetRegistry()->registered["target"], ease: new CameraSetInstructionEase( @@ -189,13 +203,13 @@ use pocketmine\math\Vector3; facing_pos: null )->send($player); - //To use CameraInstruction::target you first need to make it a free camera. + //To use CameraInstruction::target you first need to make it a free camera. CameraInstruction::target( targetCenterOffset: Vector3::zero(), // no offset actorUniqueId: $nearest->getId() // for example target the player )->send($player); - //Manages which packets have been sent + //Manages which packets have been sent $this->set[$player->getName()] = true; } ``` From a2503e80390d7bf7d0ab524a8dfea463ec15cd35 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 15:57:50 +0900 Subject: [PATCH 03/29] update README.md --- README.md | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/README.md b/README.md index 7663b31..51ec89a 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,151 @@ if($player instanceof Player && $player->isOnline()){ } ``` +# camera technic + +- use + +```php +use pocketmine\event\player\PlayerItemUseEvent; +use muqsit\libcamera\CameraInstruction; +use muqsit\libcamera\libcamera; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEase; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEaseType; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionRotation; +use pocketmine\player\Player; +use pocketmine\scheduler\ClosureTask; +use pocketmine\entity\Zombie; +``` + +## ease LINEAR + +Want to move the camera freely? Use ease! + +
+ See demo + +https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 + +
+ +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + if($player instanceof Player&&$player->isOnline()){ + //linear + + $do = $player->getDirectionVector()->multiply(10); + + CameraInstruction::multi( + CameraInstruction::set( + preset: libcamera::getPresetRegistry()->registered["free"], + ease: null, + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: null + ), + CameraInstruction::set( + preset: libcamera::getPresetRegistry()->registered["free"], + ease: new CameraSetInstructionEase( + CameraSetInstructionEaseType::LINEAR, + (float) 7.0 // duration (sec) + ), + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0)->addVector($do), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: null + ) + )->send($player); + + $this->getScheduler()->scheduleDelayedTask(new ClosureTask(function() use ($player){ + CameraInstruction::clear()->send($player); + }), 20 * 7); + } + } +``` + +## facing_pos + +Do you want to move while looking at a point? Use facing_pos! + +
+ See demo + +https://github.com/user-attachments/assets/1f5d73c2-073a-4777-8b13-8ee6c6badefb + +
+ +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + if($player instanceof Player&&$player->isOnline()){ + //linear + + //Find the most different zombie entities + $nearest = null; + $nearestDistance = PHP_INT_MAX; + foreach($player->getWorld()->getEntities() as $entity){ + if($entity instanceof Zombie){ + $distance = $player->getPosition()->distance($entity->getPosition()); + if($nearestDistance >= $distance){ + $nearest = $entity; + $nearestDistance = $distance; + } + } + } + + if($nearest === null){ + $player->sendMessage("No Zombie"); + return; + } + + + $do = $player->getDirectionVector()->multiply(10); + + CameraInstruction::multi( + CameraInstruction::set( + preset: libcamera::getPresetRegistry()->registered["free"], + ease: null, + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: $nearest->getLocation()->asVector3()->add(0, $nearest->getEyeHeight(), 0), + ), + CameraInstruction::set( + preset: libcamera::getPresetRegistry()->registered["free"], + ease: new CameraSetInstructionEase( + CameraSetInstructionEaseType::LINEAR, + (float) 7.0 // duration (sec) + ), + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0)->addVector($do), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: $nearest->getLocation()->asVector3()->add(0, $nearest->getEyeHeight(), 0), + ) + )->send($player); + + $this->getScheduler()->scheduleDelayedTask(new ClosureTask(function() use ($player){ + CameraInstruction::clear()->send($player); + }), 20 * 7); + } + } +``` + ## Roadmap At the moment, there are a few improvements that can be/or are being worked on. Here is a list of some of those From 8065b872239888f8be03f0911bcbc5bf624a0ad0 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:05:16 +0900 Subject: [PATCH 04/29] Our new API --- README.md | 25 +-- src/muqsit/libcamera/CameraInstruction.php | 6 +- src/muqsit/libcamera/CameraPresetRegistry.php | 161 +++++++++++++++-- src/muqsit/libcamera/libcamera.php | 162 ++++-------------- 4 files changed, 196 insertions(+), 158 deletions(-) diff --git a/README.md b/README.md index 51ec89a..af20859 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEaseType; use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionRotation; use pocketmine\network\mcpe\protocol\types\camera\Vector3; use pocketmine\player\Player; +use muqsit\libcamera\CameraPresetRegistry; // ... if($player instanceof Player && $player->isOnline()){ @@ -77,7 +78,7 @@ if($player instanceof Player && $player->isOnline()){ * @phpstan-param Vector3|null $facing_pos */ CameraInstruction::set( - preset: libcamera::getPresetRegistry()->registered["target"], + preset: CameraPresetRegistry::TARGET(), ease: new CameraSetInstructionEase( CameraSetInstructionEaseType::IN_OUT_CUBIC, (float) 5.0 // duration (sec) @@ -150,7 +151,7 @@ use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEase; use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEaseType; use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionRotation; use pocketmine\math\Vector3; - +use muqsit\libcamera\CameraPresetRegistry; // ... /** @var array */ @@ -190,11 +191,8 @@ use pocketmine\math\Vector3; // CameraInstruction::set( - preset: libcamera::getPresetRegistry()->registered["target"], - ease: new CameraSetInstructionEase( - CameraSetInstructionEaseType::IN_OUT_CUBIC, - (float) 5.0 // duration (sec) - ), + preset: CameraPresetRegistry::TARGET(), + ease: null, camera_pos: $player->getPosition()->add(0, $player->getEyeHeight(), 0), rot: new CameraSetInstructionRotation( (float) $player->getLocation()->getPitch(), //pitch @@ -242,6 +240,8 @@ if($player instanceof Player && $player->isOnline()){ - Multi +This doesn't work + ```php use muqsit\libcamera\libcamera; use muqsit\libcamera\CameraInstruction; @@ -279,6 +279,7 @@ use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionRotation; use pocketmine\player\Player; use pocketmine\scheduler\ClosureTask; use pocketmine\entity\Zombie; +use muqsit\libcamera\CameraPresetRegistry; ``` ## ease LINEAR @@ -305,7 +306,7 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 CameraInstruction::multi( CameraInstruction::set( - preset: libcamera::getPresetRegistry()->registered["free"], + preset: CameraPresetRegistry::FREE(), ease: null, camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace rot: new CameraSetInstructionRotation( @@ -315,7 +316,7 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 facing_pos: null ), CameraInstruction::set( - preset: libcamera::getPresetRegistry()->registered["free"], + preset: CameraPresetRegistry::FREE(), ease: new CameraSetInstructionEase( CameraSetInstructionEaseType::LINEAR, (float) 7.0 // duration (sec) @@ -379,7 +380,7 @@ https://github.com/user-attachments/assets/1f5d73c2-073a-4777-8b13-8ee6c6badefb CameraInstruction::multi( CameraInstruction::set( - preset: libcamera::getPresetRegistry()->registered["free"], + preset: CameraPresetRegistry::FREE(), ease: null, camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace rot: new CameraSetInstructionRotation( @@ -389,7 +390,7 @@ https://github.com/user-attachments/assets/1f5d73c2-073a-4777-8b13-8ee6c6badefb facing_pos: $nearest->getLocation()->asVector3()->add(0, $nearest->getEyeHeight(), 0), ), CameraInstruction::set( - preset: libcamera::getPresetRegistry()->registered["free"], + preset: CameraPresetRegistry::FREE(), ease: new CameraSetInstructionEase( CameraSetInstructionEaseType::LINEAR, (float) 7.0 // duration (sec) @@ -415,7 +416,7 @@ https://github.com/user-attachments/assets/1f5d73c2-073a-4777-8b13-8ee6c6badefb At the moment, there are a few improvements that can be/or are being worked on. Here is a list of some of those improvements: -- [ ] Allow registering new camera presets +- [x] Allow registering new camera presets ## Issues diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index 2d88f21..bbfb33c 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -36,7 +36,11 @@ public static function set( ?CameraSetInstructionRotation $rot = null, ?Vector3 $facing_pos = null ) : self{ - $preset_id = libcamera::getPresetRegistry()->network_ids[spl_object_id($preset)]; + if(!libcamera::isRegistered()){ + throw new \RuntimeException("libcamera::register() must be called before using CameraInstruction::set()"); + } + var_dump(libcamera::$network_ids, spl_object_id($preset)); + $preset_id = libcamera::$network_ids[spl_object_id($preset)][1] ?? throw new \InvalidArgumentException("Unknown camera preset, see libcamera::registerPreset()"); $instruction = new CameraSetInstruction( preset: $preset_id, ease: $ease, diff --git a/src/muqsit/libcamera/CameraPresetRegistry.php b/src/muqsit/libcamera/CameraPresetRegistry.php index 2e11141..2c099e3 100644 --- a/src/muqsit/libcamera/CameraPresetRegistry.php +++ b/src/muqsit/libcamera/CameraPresetRegistry.php @@ -5,24 +5,159 @@ namespace muqsit\libcamera; use pocketmine\network\mcpe\protocol\types\camera\CameraPreset; -use function spl_object_id; +use pocketmine\math\Vector2; +use pocketmine\utils\RegistryTrait; +/** + * @method static CameraPreset FREE() + * @method static CameraPreset FIRST_PERSON() + * @method static CameraPreset THIRD_PERSON() + * @method static CameraPreset THIRD_PERSON_FRONT() + * @method static CameraPreset TARGET() + */ final class CameraPresetRegistry{ + use RegistryTrait; + + final private function __construct(){ + //none + } - /** @var array */ - readonly public array $network_ids; /** - * @param array $registered + * @internal Injecting this function will not send more presets! + * @see libcamera::registerPreset() */ - public function __construct( - readonly public array $registered - ){ - $network_ids = []; - $id = 0; - foreach($this->registered as $preset){ - $network_ids[spl_object_id($preset)] = $id++; - } - $this->network_ids = $network_ids; + private static function register(string $name, CameraPreset $member) : void{ + self::_registryRegister($name, $member); + } + + /** @return array */ + public static function getAll() : array{ + return self::_registryGetAll(); + } + + protected static function setup() : void{ + self::register("free", new CameraPreset( + name: "minecraft:free", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, + playerEffects: false, + aimAssist: null, + controlScheme: null + )); + + self::register("first_person", new CameraPreset( + name: "minecraft:first_person", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, + playerEffects: false, + aimAssist: null, + controlScheme: null + )); + self::register("third_person", new CameraPreset( + name: "minecraft:third_person", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, + playerEffects: false, + aimAssist: null, + controlScheme: null + )); + self::register("third_person_front", new CameraPreset( + name: "minecraft:third_person_front", + parent: "", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, + playerEffects: false, + aimAssist: null, + controlScheme: null + )); + + self::register("target", new CameraPreset( + name: "minecraft:target", + parent: "minecraft:free", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: 0.0, + snapToTarget: true, + horizontalRotationLimit: new Vector2(0.0, 360.0), + verticalRotationLimit: new Vector2(0.0, 180.0), + continueTargeting: true, + blockListeningRadius: 50.0, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, + playerEffects: false, + aimAssist: null, + controlScheme: null + )); } } \ No newline at end of file diff --git a/src/muqsit/libcamera/libcamera.php b/src/muqsit/libcamera/libcamera.php index c28c634..f008a50 100644 --- a/src/muqsit/libcamera/libcamera.php +++ b/src/muqsit/libcamera/libcamera.php @@ -23,143 +23,46 @@ final class libcamera{ private static bool $registered = false; - private static CameraPresetRegistry $preset_registry; public static function isRegistered(): bool{ return self::$registered; } + protected static int $idCounter = 0; + /** @var array */ + public static array $network_ids; + private static ?CameraPresetsPacket $packetCache = null; + + public static function newId() : int{ + return self::$idCounter++; + } + + public static function registerPreset(CameraPreset $preset) : void{ + self::$network_ids[spl_object_id($preset)] = [$preset, self::newId()]; + self::$packetCache = null; + } + + private static function updateCache() : void{ + self::$packetCache ??= CameraPresetsPacket::create(array_values(array_column(self::$network_ids, 0))); + } + public static function register(Plugin $plugin) : void{ !self::$registered || throw new BadMethodCallException("Tried to registered an already existing libcamera instance"); - $preset_registry = new CameraPresetRegistry([ - "free" => new CameraPreset( - name: "minecraft:free", - parent: "", - xPosition: null, - yPosition: null, - zPosition: null, - pitch: null, - yaw: null, - rotationSpeed: null, - snapToTarget: null, - horizontalRotationLimit: null, - verticalRotationLimit: null, - continueTargeting: null, - blockListeningRadius: null, - viewOffset: null, - entityOffset: null, - radius: null, - yawLimitMin: null, - yawLimitMax: null, - audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, - playerEffects: false, - aimAssist: null, - controlScheme: null - ), - "first_person" => new CameraPreset( - name: "minecraft:first_person", - parent: "", - xPosition: null, - yPosition: null, - zPosition: null, - pitch: null, - yaw: null, - rotationSpeed: null, - snapToTarget: null, - horizontalRotationLimit: null, - verticalRotationLimit: null, - continueTargeting: null, - blockListeningRadius: null, - viewOffset: null, - entityOffset: null, - radius: null, - yawLimitMin: null, - yawLimitMax: null, - audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, - playerEffects: false, - aimAssist: null, - controlScheme: null - ), - "third_person" => new CameraPreset( - name: "minecraft:third_person", - parent: "", - xPosition: null, - yPosition: null, - zPosition: null, - pitch: null, - yaw: null, - rotationSpeed: null, - snapToTarget: null, - horizontalRotationLimit: null, - verticalRotationLimit: null, - continueTargeting: null, - blockListeningRadius: null, - viewOffset: null, - entityOffset: null, - radius: null, - yawLimitMin: null, - yawLimitMax: null, - audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, - playerEffects: false, - aimAssist: null, - controlScheme: null - ), - "third_person_front" => new CameraPreset( - name: "minecraft:third_person_front", - parent: "", - xPosition: null, - yPosition: null, - zPosition: null, - pitch: null, - yaw: null, - rotationSpeed: null, - snapToTarget: null, - horizontalRotationLimit: null, - verticalRotationLimit: null, - continueTargeting: null, - blockListeningRadius: null, - viewOffset: null, - entityOffset: null, - radius: null, - yawLimitMin: null, - yawLimitMax: null, - audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_PLAYER, - playerEffects: false, - aimAssist: null, - controlScheme: null - ), - "target" => new CameraPreset( - name: "minecraft:target", - parent: "minecraft:free", - xPosition: null, - yPosition: null, - zPosition: null, - pitch: null, - yaw: null, - rotationSpeed: 0.0, - snapToTarget: true, - horizontalRotationLimit: new Vector2(0.0, 360.0), - verticalRotationLimit: new Vector2(0.0, 180.0), - continueTargeting: true, - blockListeningRadius: 50.0, - viewOffset: null, - entityOffset: null, - radius: null, - yawLimitMin: null, - yawLimitMax: null, - audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, - playerEffects: false, - aimAssist: null, - controlScheme: null - ) - ]); - $packet = CameraPresetsPacket::create(array_values($preset_registry->registered)); - Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, function(DataPacketReceiveEvent $event) use($packet) : void{ + + self::registerPreset(CameraPresetRegistry::FREE()); + self::registerPreset(CameraPresetRegistry::FIRST_PERSON()); + self::registerPreset(CameraPresetRegistry::THIRD_PERSON()); + self::registerPreset(CameraPresetRegistry::THIRD_PERSON_FRONT()); + self::registerPreset(CameraPresetRegistry::TARGET()); + self::updateCache(); + + Server::getInstance()->getPluginManager()->registerEvent(DataPacketReceiveEvent::class, function(DataPacketReceiveEvent $event) : void{ + self::updateCache(); if($event->getPacket() instanceof SetLocalPlayerAsInitializedPacket){ - $event->getOrigin()->sendDataPacket($packet); + $event->getOrigin()->sendDataPacket(self::$packetCache ?? throw new \LogicException("Packet cache is null")); } }, EventPriority::MONITOR, $plugin); - Server::getInstance()->getPluginManager()->registerEvent(DataPacketSendEvent::class, function(DataPacketSendEvent $event) use ($packet) : void{ + Server::getInstance()->getPluginManager()->registerEvent(DataPacketSendEvent::class, function(DataPacketSendEvent $event) : void{ foreach($event->getPackets() as $packet){ if($packet instanceof StartGamePacket){ $experiments = $packet->levelSettings->experiments->getExperiments(); @@ -168,14 +71,9 @@ public static function register(Plugin $plugin) : void{ } } }, EventPriority::HIGHEST, $plugin); - self::$preset_registry = $preset_registry; self::$registered = true; } - public static function getPresetRegistry() : CameraPresetRegistry{ - return self::$preset_registry; - } - public static function parseEaseType(string $type) : int{ return match($type){ "linear" => CameraSetInstructionEaseType::LINEAR, From 64cd8dd3ed0de6f021c8e096fd18bc6cc8570fd3 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:22:55 +0900 Subject: [PATCH 05/29] remove var_dumo --- src/muqsit/libcamera/CameraInstruction.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index bbfb33c..8046409 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -39,7 +39,6 @@ public static function set( if(!libcamera::isRegistered()){ throw new \RuntimeException("libcamera::register() must be called before using CameraInstruction::set()"); } - var_dump(libcamera::$network_ids, spl_object_id($preset)); $preset_id = libcamera::$network_ids[spl_object_id($preset)][1] ?? throw new \InvalidArgumentException("Unknown camera preset, see libcamera::registerPreset()"); $instruction = new CameraSetInstruction( preset: $preset_id, From 0b340dbe247280bb5fe372043ba4fd4abd8bf2a5 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:38:57 +0900 Subject: [PATCH 06/29] Update README.md --- README.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index af20859..c2eabf0 100644 --- a/README.md +++ b/README.md @@ -282,7 +282,7 @@ use pocketmine\entity\Zombie; use muqsit\libcamera\CameraPresetRegistry; ``` -## ease LINEAR +## linear-demo Want to move the camera freely? Use ease! @@ -337,6 +337,43 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 } ``` +| Easing Name | Behavior Description | See Demo | +|----------------|----------------------------------------------------------------|-----------------------------| +| in_back | Moves slightly backward before heading to the endpoint | [see](#in_back-demo) | +| out_back | Slightly overshoots the endpoint and returns | [see](#out_back-demo) | +| in_out_back | Combines both in and out behaviors | [see](#in_out_back-demo) | +| in_bounce | Bounces 3 times before heading to the endpoint on the 4th time | [see](#in_bounce-demo) | +| out_bounce | Bounces 3 times and stops at the endpoint on the 4th time | [see](#out_bounce-demo) | +| in_out_bounce | Combines both in and out bounce behaviors | [see](#in_out_bounce-demo) | +| in_circ | Accelerates toward the endpoint | [see](#in_circ-demo) | +| out_circ | Decelerates toward the endpoint | [see](#out_circ-demo) | +| in_out_circ | Combines both in and out circ behaviors | [see](#in_out_circ-demo) | +| in_cubic | Accelerates toward the endpoint | [see](#in_cubic-demo) | +| out_cubic | Decelerates toward the endpoint | [see](#out_cubic-demo) | +| in_out_cubic | Combines both in and out cubic behaviors | [see](#in_out_cubic-demo) | +| in_elastic | Oscillates 3 times and heads to the endpoint on the 4th time | [see](#in_elastic-demo) | +| out_elastic | Oscillates 3 times and stops at the endpoint on the 4th time | [see](#out_elastic-demo) | +| in_out_elastic | Combines both in and out elastic behaviors | [see](#in_out_elastic-demo) | +| in_expo | Accelerates toward the endpoint | [see](#in_expo-demo) | +| out_expo | Decelerates toward the endpoint | [see](#out_expo-demo) | +| in_out_expo | Combines both in and out expo behaviors | [see](#in_out_expo-demo) | +| in_quad | Accelerates toward the endpoint | [see](#in_quad-demo) | +| out_quad | Decelerates toward the endpoint | [see](#out_quad-demo) | +| in_out_quad | Combines both in and out quad behaviors | [see](#in_out_quad-demo) | +| in_quart | Accelerates toward the endpoint | [see](#in_quart-demo) | +| out_quart | Decelerates toward the endpoint | [see](#out_quart-demo) | +| in_out_quart | Combines both in and out quart behaviors | [see](#in_out_quart-demo) | +| in_quint | Accelerates toward the endpoint | [see](#in_quint-demo) | +| out_quint | Decelerates toward the endpoint | [see](#out_quint-demo) | +| in_out_quint | Combines both in and out quint behaviors | [see](#in_out_quint-demo) | +| in_sine | Accelerates toward the endpoint | [see](#in_sine-demo) | +| out_sine | Decelerates toward the endpoint | [see](#out_sine-demo) | +| in_out_sine | Combines both in and out sine behaviors | [see](#in_out_sine-demo) | +| linear | Moves from start to end at constant speed | [see](#linear-demo) | +| spring | Slightly oscillates around the endpoint | [see](#spring-demo) | + + + ## facing_pos Do you want to move while looking at a point? Use facing_pos! From 456456daa75abaac26ec2b7a6c728da4c1c0ddc3 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:39:50 +0900 Subject: [PATCH 07/29] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c2eabf0..22ec418 100644 --- a/README.md +++ b/README.md @@ -336,6 +336,13 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 } } ``` + +Usage Example in Minecraft: +When using minecraft:free with an ease parameter, you can move the free camera smoothly to a specified endpoint over a given duration. +The easing functions listed above determine how the camera moves. + +Reference: +https://bacchigames.club/mc/howtocamera.html | Easing Name | Behavior Description | See Demo | |----------------|----------------------------------------------------------------|-----------------------------| From f0b17cb9e8ae97e5ea79ec9e37da9e06833ca3cd Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:43:57 +0900 Subject: [PATCH 08/29] Update README.md --- README.md | 560 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 526 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 22ec418..69bab48 100644 --- a/README.md +++ b/README.md @@ -344,40 +344,41 @@ The easing functions listed above determine how the camera moves. Reference: https://bacchigames.club/mc/howtocamera.html -| Easing Name | Behavior Description | See Demo | -|----------------|----------------------------------------------------------------|-----------------------------| -| in_back | Moves slightly backward before heading to the endpoint | [see](#in_back-demo) | -| out_back | Slightly overshoots the endpoint and returns | [see](#out_back-demo) | -| in_out_back | Combines both in and out behaviors | [see](#in_out_back-demo) | -| in_bounce | Bounces 3 times before heading to the endpoint on the 4th time | [see](#in_bounce-demo) | -| out_bounce | Bounces 3 times and stops at the endpoint on the 4th time | [see](#out_bounce-demo) | -| in_out_bounce | Combines both in and out bounce behaviors | [see](#in_out_bounce-demo) | -| in_circ | Accelerates toward the endpoint | [see](#in_circ-demo) | -| out_circ | Decelerates toward the endpoint | [see](#out_circ-demo) | -| in_out_circ | Combines both in and out circ behaviors | [see](#in_out_circ-demo) | -| in_cubic | Accelerates toward the endpoint | [see](#in_cubic-demo) | -| out_cubic | Decelerates toward the endpoint | [see](#out_cubic-demo) | -| in_out_cubic | Combines both in and out cubic behaviors | [see](#in_out_cubic-demo) | -| in_elastic | Oscillates 3 times and heads to the endpoint on the 4th time | [see](#in_elastic-demo) | -| out_elastic | Oscillates 3 times and stops at the endpoint on the 4th time | [see](#out_elastic-demo) | -| in_out_elastic | Combines both in and out elastic behaviors | [see](#in_out_elastic-demo) | -| in_expo | Accelerates toward the endpoint | [see](#in_expo-demo) | -| out_expo | Decelerates toward the endpoint | [see](#out_expo-demo) | -| in_out_expo | Combines both in and out expo behaviors | [see](#in_out_expo-demo) | -| in_quad | Accelerates toward the endpoint | [see](#in_quad-demo) | -| out_quad | Decelerates toward the endpoint | [see](#out_quad-demo) | -| in_out_quad | Combines both in and out quad behaviors | [see](#in_out_quad-demo) | -| in_quart | Accelerates toward the endpoint | [see](#in_quart-demo) | -| out_quart | Decelerates toward the endpoint | [see](#out_quart-demo) | -| in_out_quart | Combines both in and out quart behaviors | [see](#in_out_quart-demo) | -| in_quint | Accelerates toward the endpoint | [see](#in_quint-demo) | -| out_quint | Decelerates toward the endpoint | [see](#out_quint-demo) | -| in_out_quint | Combines both in and out quint behaviors | [see](#in_out_quint-demo) | -| in_sine | Accelerates toward the endpoint | [see](#in_sine-demo) | -| out_sine | Decelerates toward the endpoint | [see](#out_sine-demo) | -| in_out_sine | Combines both in and out sine behaviors | [see](#in_out_sine-demo) | -| linear | Moves from start to end at constant speed | [see](#linear-demo) | -| spring | Slightly oscillates around the endpoint | [see](#spring-demo) | + +| Easing Name | Behavior Description | See Demo | IsCrash | +|----------------|----------------------------------------------------------------|-----------------------------|---------| +| in_back | Moves slightly backward before heading to the endpoint | [see](#in_back-demo) | ❌ | +| out_back | Slightly overshoots the endpoint and returns | [see](#out_back-demo) | ✅ | +| in_out_back | Combines both in and out behaviors | [see](#in_out_back-demo) | ✅ | +| in_bounce | Bounces 3 times before heading to the endpoint on the 4th time | [see](#in_bounce-demo) | ❌ | +| out_bounce | Bounces 3 times and stops at the endpoint on the 4th time | [see](#out_bounce-demo) | ❌ | +| in_out_bounce | Combines both in and out bounce behaviors | [see](#in_out_bounce-demo) | ❌ | +| in_circ | Accelerates toward the endpoint | [see](#in_circ-demo) | ❌ | +| out_circ | Decelerates toward the endpoint | [see](#out_circ-demo) | ❌ | +| in_out_circ | Combines both in and out circ behaviors | [see](#in_out_circ-demo) | ❌ | +| in_cubic | Accelerates toward the endpoint | [see](#in_cubic-demo) | ❌ | +| out_cubic | Decelerates toward the endpoint | [see](#out_cubic-demo) | ❌ | +| in_out_cubic | Combines both in and out cubic behaviors | [see](#in_out_cubic-demo) | ❌ | +| in_elastic | Oscillates 3 times and heads to the endpoint on the 4th time | [see](#in_elastic-demo) | ❌ | +| out_elastic | Oscillates 3 times and stops at the endpoint on the 4th time | [see](#out_elastic-demo) | ❌ | +| in_out_elastic | Combines both in and out elastic behaviors | [see](#in_out_elastic-demo) | ❌ | +| in_expo | Accelerates toward the endpoint | [see](#in_expo-demo) | ❌ | +| out_expo | Decelerates toward the endpoint | [see](#out_expo-demo) | ❌ | +| in_out_expo | Combines both in and out expo behaviors | [see](#in_out_expo-demo) | ❌ | +| in_quad | Accelerates toward the endpoint | [see](#in_quad-demo) | ❌ | +| out_quad | Decelerates toward the endpoint | [see](#out_quad-demo) | ❌ | +| in_out_quad | Combines both in and out quad behaviors | [see](#in_out_quad-demo) | ❌ | +| in_quart | Accelerates toward the endpoint | [see](#in_quart-demo) | ❌ | +| out_quart | Decelerates toward the endpoint | [see](#out_quart-demo) | ❌ | +| in_out_quart | Combines both in and out quart behaviors | [see](#in_out_quart-demo) | ❌ | +| in_quint | Accelerates toward the endpoint | [see](#in_quint-demo) | ❌ | +| out_quint | Decelerates toward the endpoint | [see](#out_quint-demo) | ❌ | +| in_out_quint | Combines both in and out quint behaviors | [see](#in_out_quint-demo) | ❌ | +| in_sine | Accelerates toward the endpoint | [see](#in_sine-demo) | ❌ | +| out_sine | Decelerates toward the endpoint | [see](#out_sine-demo) | ❌ | +| in_out_sine | Combines both in and out sine behaviors | [see](#in_out_sine-demo) | ❌ | +| linear | Moves from start to end at constant speed | [see](#linear-demo) | ❌ | +| spring | Slightly oscillates around the endpoint | [see](#spring-demo) | ❌ | @@ -455,6 +456,497 @@ https://github.com/user-attachments/assets/1f5d73c2-073a-4777-8b13-8ee6c6badefb } ``` +# demos + +For convenience, we will use this common code for the demo. + +```php + public function onDemo(Entity $player, int $easeType) : void{ + if($player instanceof Player&&$player->isOnline()){ + //Find the most different zombie entities + $nearest = null; + $nearestDistance = PHP_INT_MAX; + foreach($player->getWorld()->getEntities() as $entity){ + if($entity instanceof Zombie){ + $distance = $player->getPosition()->distance($entity->getPosition()); + if($nearestDistance >= $distance){ + $nearest = $entity; + $nearestDistance = $distance; + } + } + } + + if($nearest === null){ + $player->sendMessage("No Zombie"); + return; + } + + $player->setInvisible(true); + $nearest->despawnFrom($player); + + CameraInstruction::multi( + CameraInstruction::set( + preset: CameraPresetRegistry::FREE(), + ease: null, + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos:null, + ), + CameraInstruction::set( + preset: CameraPresetRegistry::FREE(), + ease: new CameraSetInstructionEase( + $easeType, + (float) 10.0 // duration (sec) + ), + camera_pos: $nearest->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: null, + ) + )->send($player); + + $this->getScheduler()->scheduleDelayedTask(new ClosureTask(function() use ($nearest, $player){ + CameraInstruction::clear()->send($player); + $player->setInvisible(false); + $nearest->despawnFrom($player); + }), 20 * 10); + } + } +``` + + +## in_back-demo + +
+ see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_BACK); + } +``` + +
+ +
+ +
+ See demo + +https://github.com/user-attachments/assets/67924c3f-f7c8-4216-b11f-943bf5149de9 + +
+--- + + +## out_back-demo + + +### WARNING: This will crash the client as of 1.21.93 + +
+ +see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_BACK); +} +``` + +
+ +
+ + + + +--- + +## in_out_back-demo + +### WARNING: This will crash the client as of 1.21.93 + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_BACK); +} +``` + +
+ +
+ + + +--- + +## in_bounce-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_BOUNCE); +} +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/4f55e402-e27f-4e20-897a-3fd199561498 + +
+ +--- + +## out_bounce-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_BOUNCE); +} +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/365555eb-6193-4121-ac71-b300b857edae + +
+ +--- + +## in_out_bounce-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_BOUNCE); +} +``` + +
+ +
+ +
+See demo + +[see](#in_out_bounce-demo) + +
+ +--- + +## in_circ-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_CIRC); +} +``` + +
+ +
+ +
+See demo + +[see](#in_circ-demo) + +
+ +--- + +## out_circ-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_CIRC); +} +``` + +
+ +
+ +
+See demo + +[see](#out_circ-demo) + +
+ +--- + +## in_out_circ-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_CIRC); +} +``` + +
+ +
+ +
+See demo + +[see](#in_out_circ-demo) + +
+ +--- + +## in_cubic-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_CUBIC); +} +``` + +
+ +
+ +
+See demo + +[see](#in_cubic-demo) + +
+ +--- + +## out_cubic-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_CUBIC); +} +``` + +
+ +
+ +
+See demo + +[see](#out_cubic-demo) + +
+ +--- + +## in_out_cubic-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_CUBIC); +} +``` + +
+ +
+ +
+See demo + +[see](#in_out_cubic-demo) + +
+ +--- + +## in_quart-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_QUART); +} +``` + +
+ +
+ +
+See demo + +[see](#in_quart-demo) + +
+ +--- + +## out_quart-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_QUART); +} +``` + +
+ +
+ +
+See demo + +[see](#out_quart-demo) + +
+ +--- + +## in_out_quart-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_QUART); +} +``` + +
+ +
+ +
+See demo + +[see](#in_out_quart-demo) + +
+ + ## Roadmap At the moment, there are a few improvements that can be/or are being worked on. Here is a list of some of those From c65f84111feff7e645c45e3e39d785a1c0f7660b Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:54:16 +0900 Subject: [PATCH 09/29] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 69bab48..a67bbfc 100644 --- a/README.md +++ b/README.md @@ -551,7 +551,7 @@ https://github.com/user-attachments/assets/67924c3f-f7c8-4216-b11f-943bf5149de9 ## out_back-demo -### WARNING: This will crash the client as of 1.21.93 +### WARNING: ⚠️ Crashes client on 1.21.93
@@ -584,7 +584,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ ## in_out_back-demo -### WARNING: This will crash the client as of 1.21.93 +### WARNING: ⚠️ Crashes client on 1.21.93
see Code @@ -690,7 +690,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_out_bounce-demo) +https://github.com/user-attachments/assets/a4a8f132-d31f-4187-9769-b5ea544a5d56
@@ -718,7 +718,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_circ-demo) +https://github.com/user-attachments/assets/8edb854e-ad07-47d6-ab08-792954209ffe
From 010adb18ed8ffae8ae1eb21802ae566e905c3a2f Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 19:15:46 +0900 Subject: [PATCH 10/29] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a67bbfc..95dd8f5 100644 --- a/README.md +++ b/README.md @@ -746,7 +746,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#out_circ-demo) +https://github.com/user-attachments/assets/73c3bae0-1026-49be-855f-fdf53120bb55
@@ -774,7 +774,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_out_circ-demo) +https://github.com/user-attachments/assets/76626fef-d97a-4ed7-aa8a-d54a069c073c
@@ -802,7 +802,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_cubic-demo) +https://github.com/user-attachments/assets/1ec8c85b-2a92-4cf2-9f3c-6b4aa8b150db
@@ -830,7 +830,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#out_cubic-demo) +https://github.com/user-attachments/assets/02d67db4-d6c8-4062-b1f1-9b81f0e99012
@@ -858,7 +858,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_out_cubic-demo) +https://github.com/user-attachments/assets/002867af-8f93-4ca7-b34b-5ab0a9a17855
From 1fa4d87e5476da0ecf3d03e6ac7098c272cb4667 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 19:24:50 +0900 Subject: [PATCH 11/29] Update README.md --- README.md | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 95dd8f5..846ed23 100644 --- a/README.md +++ b/README.md @@ -570,16 +570,6 @@ public function onUse(PlayerItemUseEvent $event) : void{

- - - - --- ## in_out_back-demo @@ -603,13 +593,6 @@ public function onUse(PlayerItemUseEvent $event) : void{
- - --- ## in_bounce-demo @@ -914,7 +897,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#out_quart-demo) +https://github.com/user-attachments/assets/77c0d077-da10-41c1-a010-3f4aa62a984e
@@ -942,7 +925,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_out_quart-demo) +https://github.com/user-attachments/assets/cc72e54d-38fd-4921-89ea-48cc5c5d1f44
From 252a90b4e0f5b571dd3a1566f0226e8e93b2b53a Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:03:04 +0900 Subject: [PATCH 12/29] Update README.md --- README.md | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 287 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 846ed23..45fb6da 100644 --- a/README.md +++ b/README.md @@ -869,7 +869,9 @@ public function onUse(PlayerItemUseEvent $event) : void{
See demo -[see](#in_quart-demo) +https://github.com/user-attachments/assets/01342b32-bd33-4bd3-a0e2-a332914fcd3d + +
@@ -930,6 +932,290 @@ https://github.com/user-attachments/assets/cc72e54d-38fd-4921-89ea-48cc5c5d1f44
+## in_quint-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_QUINT); + } +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/a50bb0d6-770f-4910-be82-05abda073c61 + +
+ +--- + +## out_quint-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_QUINT); + } +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/f921aaa7-e170-4624-964f-b54c9a58b3c2 + +
+ +--- + +## in_out_quint-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_QUINT); + } +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/db433b41-6912-49e2-af7c-7f556d5b38f4 + +
+ +--- + +## in_sine-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_SINE); + } +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/758fcb54-db91-4d83-baa6-b62c724a7ae3 + +
+ +--- + +## out_sine-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_SINE); + } +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/e686b103-274c-4d98-ba18-feccfa563d97 + +
+ +--- + +## in_out_sine-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_SINE); + } +``` + +
+ +
+ +
+See demo + +url + +
+ +--- + +## in_expo-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_EXPO); + } + +``` + +
+ +
+ +
+See demo + +url + +
+ +--- + +## out_expo-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_EXPO); + } + +``` + +
+ +
+ +
+See demo + +url + +
+ +--- + +## in_out_expo-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_EXPO); + } + +``` + +
+ +
+ +
+See demo + +url + +
+ +--- + +## spring-demo + +
+see Code + +```php + public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::SPRING); + } + +``` + +
+ +
+ +
+See demo + +url + +
+ + + ## Roadmap At the moment, there are a few improvements that can be/or are being worked on. Here is a list of some of those From edd86dfceddc373cc69286927a561f2abf008d7b Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:19:13 +0900 Subject: [PATCH 13/29] Update README.md --- README.md | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 45fb6da..2c5a88a 100644 --- a/README.md +++ b/README.md @@ -378,7 +378,7 @@ https://bacchigames.club/mc/howtocamera.html | out_sine | Decelerates toward the endpoint | [see](#out_sine-demo) | ❌ | | in_out_sine | Combines both in and out sine behaviors | [see](#in_out_sine-demo) | ❌ | | linear | Moves from start to end at constant speed | [see](#linear-demo) | ❌ | -| spring | Slightly oscillates around the endpoint | [see](#spring-demo) | ❌ | +| spring | Slightly oscillates around the endpoint | [see](#spring-demo) | ✅ | @@ -1094,7 +1094,7 @@ https://github.com/user-attachments/assets/e686b103-274c-4d98-ba18-feccfa563d97
See demo -url +https://github.com/user-attachments/assets/c32a1034-eec0-4d2c-8a20-33bd03060d88
@@ -1113,7 +1113,6 @@ url } $this->onDemo($player, CameraSetInstructionEaseType::IN_EXPO); } - ``` @@ -1123,7 +1122,7 @@ url
See demo -url +https://github.com/user-attachments/assets/5ae64606-c404-4136-a78b-bee052ba0300
@@ -1142,7 +1141,6 @@ url } $this->onDemo($player, CameraSetInstructionEaseType::OUT_EXPO); } - ``` @@ -1152,7 +1150,7 @@ url
See demo -url +https://github.com/user-attachments/assets/97958704-f087-4894-9888-360e9cf9e758
@@ -1171,7 +1169,6 @@ url } $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_EXPO); } - ``` @@ -1181,7 +1178,7 @@ url
See demo -url +https://github.com/user-attachments/assets/d2b91349-08b2-4273-91e2-f60d14d76423
@@ -1189,6 +1186,8 @@ url ## spring-demo +### WARNING: ⚠️ Crashes client on 1.21.93 +
see Code @@ -1200,21 +1199,10 @@ url } $this->onDemo($player, CameraSetInstructionEaseType::SPRING); } - ```
-
- -
-See demo - -url - -
- - ## Roadmap From 3c99f0dd38fa010b1e1b852b2d766f6c14497d7e Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:39:24 +0900 Subject: [PATCH 14/29] Update README.md --- README.md | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2c5a88a..1bae7f5 100644 --- a/README.md +++ b/README.md @@ -344,7 +344,6 @@ The easing functions listed above determine how the camera moves. Reference: https://bacchigames.club/mc/howtocamera.html - | Easing Name | Behavior Description | See Demo | IsCrash | |----------------|----------------------------------------------------------------|-----------------------------|---------| | in_back | Moves slightly backward before heading to the endpoint | [see](#in_back-demo) | ❌ | @@ -360,8 +359,8 @@ https://bacchigames.club/mc/howtocamera.html | out_cubic | Decelerates toward the endpoint | [see](#out_cubic-demo) | ❌ | | in_out_cubic | Combines both in and out cubic behaviors | [see](#in_out_cubic-demo) | ❌ | | in_elastic | Oscillates 3 times and heads to the endpoint on the 4th time | [see](#in_elastic-demo) | ❌ | -| out_elastic | Oscillates 3 times and stops at the endpoint on the 4th time | [see](#out_elastic-demo) | ❌ | -| in_out_elastic | Combines both in and out elastic behaviors | [see](#in_out_elastic-demo) | ❌ | +| out_elastic | Oscillates 3 times and stops at the endpoint on the 4th time | [see](#out_elastic-demo) | ✅ | +| in_out_elastic | Combines both in and out elastic behaviors | [see](#in_out_elastic-demo) | ✅ | | in_expo | Accelerates toward the endpoint | [see](#in_expo-demo) | ❌ | | out_expo | Decelerates toward the endpoint | [see](#out_expo-demo) | ❌ | | in_out_expo | Combines both in and out expo behaviors | [see](#in_out_expo-demo) | ❌ | @@ -1204,6 +1203,168 @@ https://github.com/user-attachments/assets/d2b91349-08b2-4273-91e2-f60d14d76423 + +## in_quad-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_QUAD); +} +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/ccecf930-6c4e-46c8-b009-c88578d0668e + +
+ +--- + +## out_quad-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_QUAD); +} +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/21d17561-ebb5-44fa-a95e-c4382504f834 + +
+ +--- + +## in_out_quad-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_QUAD); +} +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/76d050d3-6c5e-47f3-9ca8-5386e3e17f00 + +
+ +--- + +## in_out_elastic-demo + +### WARNING: ⚠️ Crashes client on 1.21.93 + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_OUT_ELASTIC); +} +``` + +--- + +## out_elastic-demo + +### WARNING: ⚠️ Crashes client on 1.21.93 + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::OUT_ELASTIC); +} +``` + +
+ +
+ +
+See demo + +url + +
+ +--- + +## in_elastic-demo + +
+see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + $this->onDemo($player, CameraSetInstructionEaseType::IN_ELASTIC); +} +``` + +
+ +
+ +
+See demo + +https://github.com/user-attachments/assets/2290dead-b798-41f5-8cc7-b6d3f28a3760 + +
+ + + ## Roadmap At the moment, there are a few improvements that can be/or are being worked on. Here is a list of some of those From 1d30540ee15eaca1318ca3ecfca3c4bec49e52ba Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:41:18 +0900 Subject: [PATCH 15/29] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 1bae7f5..3d4a3a3 100644 --- a/README.md +++ b/README.md @@ -337,6 +337,8 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 } ``` +# Rases + Usage Example in Minecraft: When using minecraft:free with an ease parameter, you can move the free camera smoothly to a specified endpoint over a given duration. The easing functions listed above determine how the camera moves. @@ -569,6 +571,8 @@ public function onUse(PlayerItemUseEvent $event) : void{

+ + --- ## in_out_back-demo @@ -592,6 +596,9 @@ public function onUse(PlayerItemUseEvent $event) : void{
+ + + --- ## in_bounce-demo From f430938fc3448c5f0b22cd72811a90a6eff3c896 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:41:58 +0900 Subject: [PATCH 16/29] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d4a3a3..16f7a45 100644 --- a/README.md +++ b/README.md @@ -337,7 +337,7 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 } ``` -# Rases +# Eases Usage Example in Minecraft: When using minecraft:free with an ease parameter, you can move the free camera smoothly to a specified endpoint over a given duration. From d50786275d6bd0b5bdc2425b3da4b7777e63ede2 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:56:09 +0900 Subject: [PATCH 17/29] Update README.md --- README.md | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 16f7a45..bcbf5c1 100644 --- a/README.md +++ b/README.md @@ -580,6 +580,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ ### WARNING: ⚠️ Crashes client on 1.21.93
+ see Code ```php @@ -604,6 +605,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ ## in_bounce-demo
+ see Code ```php @@ -632,6 +634,7 @@ https://github.com/user-attachments/assets/4f55e402-e27f-4e20-897a-3fd199561498 ## out_bounce-demo
+ see Code ```php @@ -660,6 +663,7 @@ https://github.com/user-attachments/assets/365555eb-6193-4121-ac71-b300b857edae ## in_out_bounce-demo
+ see Code ```php @@ -688,6 +692,7 @@ https://github.com/user-attachments/assets/a4a8f132-d31f-4187-9769-b5ea544a5d56 ## in_circ-demo
+ see Code ```php @@ -716,6 +721,7 @@ https://github.com/user-attachments/assets/8edb854e-ad07-47d6-ab08-792954209ffe ## out_circ-demo
+ see Code ```php @@ -744,6 +750,7 @@ https://github.com/user-attachments/assets/73c3bae0-1026-49be-855f-fdf53120bb55 ## in_out_circ-demo
+ see Code ```php @@ -772,6 +779,7 @@ https://github.com/user-attachments/assets/76626fef-d97a-4ed7-aa8a-d54a069c073c ## in_cubic-demo
+ see Code ```php @@ -800,6 +808,7 @@ https://github.com/user-attachments/assets/1ec8c85b-2a92-4cf2-9f3c-6b4aa8b150db ## out_cubic-demo
+ see Code ```php @@ -828,6 +837,7 @@ https://github.com/user-attachments/assets/02d67db4-d6c8-4062-b1f1-9b81f0e99012 ## in_out_cubic-demo
+ see Code ```php @@ -856,6 +866,7 @@ https://github.com/user-attachments/assets/002867af-8f93-4ca7-b34b-5ab0a9a17855 ## in_quart-demo
+ see Code ```php @@ -886,6 +897,7 @@ https://github.com/user-attachments/assets/01342b32-bd33-4bd3-a0e2-a332914fcd3d ## out_quart-demo
+ see Code ```php @@ -914,6 +926,7 @@ https://github.com/user-attachments/assets/77c0d077-da10-41c1-a010-3f4aa62a984e ## in_out_quart-demo
+ see Code ```php @@ -941,6 +954,7 @@ https://github.com/user-attachments/assets/cc72e54d-38fd-4921-89ea-48cc5c5d1f44 ## in_quint-demo
+ see Code ```php @@ -969,6 +983,7 @@ https://github.com/user-attachments/assets/a50bb0d6-770f-4910-be82-05abda073c61 ## out_quint-demo
+ see Code ```php @@ -997,6 +1012,7 @@ https://github.com/user-attachments/assets/f921aaa7-e170-4624-964f-b54c9a58b3c2 ## in_out_quint-demo
+ see Code ```php @@ -1025,6 +1041,7 @@ https://github.com/user-attachments/assets/db433b41-6912-49e2-af7c-7f556d5b38f4 ## in_sine-demo
+ see Code ```php @@ -1053,6 +1070,7 @@ https://github.com/user-attachments/assets/758fcb54-db91-4d83-baa6-b62c724a7ae3 ## out_sine-demo
+ see Code ```php @@ -1081,6 +1099,7 @@ https://github.com/user-attachments/assets/e686b103-274c-4d98-ba18-feccfa563d97 ## in_out_sine-demo
+ see Code ```php @@ -1109,6 +1128,7 @@ https://github.com/user-attachments/assets/c32a1034-eec0-4d2c-8a20-33bd03060d88 ## in_expo-demo
+ see Code ```php @@ -1137,6 +1157,7 @@ https://github.com/user-attachments/assets/5ae64606-c404-4136-a78b-bee052ba0300 ## out_expo-demo
+ see Code ```php @@ -1165,6 +1186,7 @@ https://github.com/user-attachments/assets/97958704-f087-4894-9888-360e9cf9e758 ## in_out_expo-demo
+ see Code ```php @@ -1195,6 +1217,7 @@ https://github.com/user-attachments/assets/d2b91349-08b2-4273-91e2-f60d14d76423 ### WARNING: ⚠️ Crashes client on 1.21.93
+ see Code ```php @@ -1214,6 +1237,7 @@ https://github.com/user-attachments/assets/d2b91349-08b2-4273-91e2-f60d14d76423 ## in_quad-demo
+ see Code ```php @@ -1242,6 +1266,7 @@ https://github.com/user-attachments/assets/ccecf930-6c4e-46c8-b009-c88578d0668e ## out_quad-demo
+ see Code ```php @@ -1270,6 +1295,7 @@ https://github.com/user-attachments/assets/21d17561-ebb5-44fa-a95e-c4382504f834 ## in_out_quad-demo
+ see Code ```php @@ -1300,6 +1326,7 @@ https://github.com/user-attachments/assets/76d050d3-6c5e-47f3-9ca8-5386e3e17f00 ### WARNING: ⚠️ Crashes client on 1.21.93
+ see Code ```php @@ -1312,6 +1339,8 @@ public function onUse(PlayerItemUseEvent $event) : void{ } ``` +
+ --- ## out_elastic-demo @@ -1319,6 +1348,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ ### WARNING: ⚠️ Crashes client on 1.21.93
+ see Code ```php @@ -1333,20 +1363,12 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
- -
-See demo - -url - -
- --- ## in_elastic-demo
+ see Code ```php From 710e149f4a2b03cf83c432e6d2993b51eafa5ff2 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:59:23 +0900 Subject: [PATCH 18/29] Update README.md --- README.md | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index bcbf5c1..11a55f3 100644 --- a/README.md +++ b/README.md @@ -546,7 +546,7 @@ For convenience, we will use this common code for the demo. https://github.com/user-attachments/assets/67924c3f-f7c8-4216-b11f-943bf5149de9
---- + ## out_back-demo @@ -573,7 +573,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
---- + ## in_out_back-demo @@ -600,7 +600,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ ---- + ## in_bounce-demo @@ -629,7 +629,7 @@ https://github.com/user-attachments/assets/4f55e402-e27f-4e20-897a-3fd199561498
---- + ## out_bounce-demo @@ -658,7 +658,7 @@ https://github.com/user-attachments/assets/365555eb-6193-4121-ac71-b300b857edae
---- + ## in_out_bounce-demo @@ -687,7 +687,7 @@ https://github.com/user-attachments/assets/a4a8f132-d31f-4187-9769-b5ea544a5d56
---- + ## in_circ-demo @@ -716,7 +716,7 @@ https://github.com/user-attachments/assets/8edb854e-ad07-47d6-ab08-792954209ffe
---- + ## out_circ-demo @@ -745,7 +745,7 @@ https://github.com/user-attachments/assets/73c3bae0-1026-49be-855f-fdf53120bb55
---- + ## in_out_circ-demo @@ -774,7 +774,7 @@ https://github.com/user-attachments/assets/76626fef-d97a-4ed7-aa8a-d54a069c073c
---- + ## in_cubic-demo @@ -803,7 +803,7 @@ https://github.com/user-attachments/assets/1ec8c85b-2a92-4cf2-9f3c-6b4aa8b150db
---- + ## out_cubic-demo @@ -832,7 +832,7 @@ https://github.com/user-attachments/assets/02d67db4-d6c8-4062-b1f1-9b81f0e99012
---- + ## in_out_cubic-demo @@ -861,7 +861,7 @@ https://github.com/user-attachments/assets/002867af-8f93-4ca7-b34b-5ab0a9a17855
---- + ## in_quart-demo @@ -892,7 +892,7 @@ https://github.com/user-attachments/assets/01342b32-bd33-4bd3-a0e2-a332914fcd3d
---- + ## out_quart-demo @@ -921,7 +921,7 @@ https://github.com/user-attachments/assets/77c0d077-da10-41c1-a010-3f4aa62a984e
---- + ## in_out_quart-demo @@ -978,7 +978,7 @@ https://github.com/user-attachments/assets/a50bb0d6-770f-4910-be82-05abda073c61
---- + ## out_quint-demo @@ -1007,7 +1007,7 @@ https://github.com/user-attachments/assets/f921aaa7-e170-4624-964f-b54c9a58b3c2
---- + ## in_out_quint-demo @@ -1036,7 +1036,7 @@ https://github.com/user-attachments/assets/db433b41-6912-49e2-af7c-7f556d5b38f4
---- + ## in_sine-demo @@ -1065,7 +1065,7 @@ https://github.com/user-attachments/assets/758fcb54-db91-4d83-baa6-b62c724a7ae3
---- + ## out_sine-demo @@ -1094,7 +1094,7 @@ https://github.com/user-attachments/assets/e686b103-274c-4d98-ba18-feccfa563d97
---- + ## in_out_sine-demo @@ -1123,7 +1123,7 @@ https://github.com/user-attachments/assets/c32a1034-eec0-4d2c-8a20-33bd03060d88
---- + ## in_expo-demo @@ -1152,7 +1152,7 @@ https://github.com/user-attachments/assets/5ae64606-c404-4136-a78b-bee052ba0300
---- + ## out_expo-demo @@ -1181,7 +1181,7 @@ https://github.com/user-attachments/assets/97958704-f087-4894-9888-360e9cf9e758
---- + ## in_out_expo-demo @@ -1210,7 +1210,7 @@ https://github.com/user-attachments/assets/d2b91349-08b2-4273-91e2-f60d14d76423
---- + ## spring-demo @@ -1261,7 +1261,7 @@ https://github.com/user-attachments/assets/ccecf930-6c4e-46c8-b009-c88578d0668e
---- + ## out_quad-demo @@ -1290,7 +1290,7 @@ https://github.com/user-attachments/assets/21d17561-ebb5-44fa-a95e-c4382504f834
---- + ## in_out_quad-demo @@ -1319,7 +1319,7 @@ https://github.com/user-attachments/assets/76d050d3-6c5e-47f3-9ca8-5386e3e17f00
---- + ## in_out_elastic-demo @@ -1341,7 +1341,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
---- + ## out_elastic-demo @@ -1363,7 +1363,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
---- + ## in_elastic-demo From 9aac2a371e10ce105c0aa364b66bace4bb178c1c Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:01:38 +0900 Subject: [PATCH 19/29] Update README.md --- README.md | 68 +++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 11a55f3..d5be1c7 100644 --- a/README.md +++ b/README.md @@ -527,18 +527,18 @@ For convenience, we will use this common code for the demo. see Code ```php - public function onUse(PlayerItemUseEvent $event) : void{ - $player = $event->getPlayer(); - if(!$player->isSneaking()){ - return; - } - $this->onDemo($player, CameraSetInstructionEaseType::IN_BACK); +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; } + $this->onDemo($player, CameraSetInstructionEaseType::IN_BACK); +} ```
-
+
See demo @@ -570,7 +570,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+ @@ -595,7 +595,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ -
+ @@ -620,7 +620,7 @@ public function onUse(PlayerItemUseEvent $event) : void{ -
+
See demo @@ -649,7 +649,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -678,7 +678,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -707,7 +707,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -736,7 +736,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -765,7 +765,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -794,7 +794,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -823,7 +823,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -852,7 +852,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -881,7 +881,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -912,7 +912,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -941,7 +941,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -969,7 +969,7 @@ https://github.com/user-attachments/assets/cc72e54d-38fd-4921-89ea-48cc5c5d1f44
-
+
See demo @@ -998,7 +998,7 @@ https://github.com/user-attachments/assets/a50bb0d6-770f-4910-be82-05abda073c61
-
+
See demo @@ -1027,7 +1027,7 @@ https://github.com/user-attachments/assets/f921aaa7-e170-4624-964f-b54c9a58b3c2
-
+
See demo @@ -1056,7 +1056,7 @@ https://github.com/user-attachments/assets/db433b41-6912-49e2-af7c-7f556d5b38f4
-
+
See demo @@ -1085,7 +1085,7 @@ https://github.com/user-attachments/assets/758fcb54-db91-4d83-baa6-b62c724a7ae3
-
+
See demo @@ -1114,7 +1114,7 @@ https://github.com/user-attachments/assets/e686b103-274c-4d98-ba18-feccfa563d97
-
+
See demo @@ -1143,7 +1143,7 @@ https://github.com/user-attachments/assets/c32a1034-eec0-4d2c-8a20-33bd03060d88
-
+
See demo @@ -1172,7 +1172,7 @@ https://github.com/user-attachments/assets/5ae64606-c404-4136-a78b-bee052ba0300
-
+
See demo @@ -1201,7 +1201,7 @@ https://github.com/user-attachments/assets/97958704-f087-4894-9888-360e9cf9e758
-
+
See demo @@ -1252,7 +1252,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -1281,7 +1281,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -1310,7 +1310,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo @@ -1383,7 +1383,7 @@ public function onUse(PlayerItemUseEvent $event) : void{
-
+
See demo From f99fea4cbdd264dcd0718eb3a9337b8fc659b225 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 22:03:54 +0900 Subject: [PATCH 20/29] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d5be1c7..bea87de 100644 --- a/README.md +++ b/README.md @@ -342,7 +342,10 @@ https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 Usage Example in Minecraft: When using minecraft:free with an ease parameter, you can move the free camera smoothly to a specified endpoint over a given duration. The easing functions listed above determine how the camera moves. +Here, "in" means the start point and "out" means the end point. + + Reference: https://bacchigames.club/mc/howtocamera.html From 5e156f30b469f976537332ff7c1bf250da6a54b8 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Tue, 15 Jul 2025 22:32:20 +0900 Subject: [PATCH 21/29] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bea87de..04a9ab1 100644 --- a/README.md +++ b/README.md @@ -343,12 +343,15 @@ Usage Example in Minecraft: When using minecraft:free with an ease parameter, you can move the free camera smoothly to a specified endpoint over a given duration. The easing functions listed above determine how the camera moves. Here, "in" means the start point and "out" means the end point. - - Reference: https://bacchigames.club/mc/howtocamera.html +> [!WARNING] +> These demos may stimulate the vestibular system and cause symptoms such as **dizziness or a sensation of head movement (headshake)** that could last for several hours. +> Please proceed only if you are aware of the risks and feel well enough to continue. + + | Easing Name | Behavior Description | See Demo | IsCrash | |----------------|----------------------------------------------------------------|-----------------------------|---------| | in_back | Moves slightly backward before heading to the endpoint | [see](#in_back-demo) | ❌ | From 67579a0484ce4a9599df465f0ebed450ba5d0005 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Wed, 16 Jul 2025 12:22:56 +0900 Subject: [PATCH 22/29] update README.md --- README.md | 235 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 178 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 04a9ab1..a913bd4 100644 --- a/README.md +++ b/README.md @@ -85,8 +85,8 @@ if($player instanceof Player && $player->isOnline()){ ), camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace rot: new CameraSetInstructionRotation( - (float)$player->getLocation()->getPitch(), //pitch - (float)$player->getLocation()->getYaw() //yaw + (float)20, //pitch + (float)180 //yaw ), facing_pos: null )->send($player); @@ -265,6 +265,122 @@ if($player instanceof Player && $player->isOnline()){ } ``` +- registerCustom Preset + +First, build a custom preset registry +CustomCameraPresetRegistry.php +```php + */ + public static function getAll() : array{ + return self::_registryGetAll(); + } + + protected static function setup() : void{ + self::register("CUSTOM_THIRD_PERSON_FRONT", new CameraPreset( + name: "minecraft:test", + parent: "minecraft:third_person_front", + xPosition: null, + yPosition: null, + zPosition: null, + pitch: null, + yaw: null, + rotationSpeed: null, + snapToTarget: null, + horizontalRotationLimit: null, + verticalRotationLimit: null, + continueTargeting: null, + blockListeningRadius: null, + viewOffset: null, + entityOffset: null, + radius: null, + yawLimitMin: null, + yawLimitMax: null, + audioListenerType: CameraPreset::AUDIO_LISTENER_TYPE_CAMERA, + playerEffects: false, + aimAssist: null, + controlScheme: null + )); + } +} +``` + +Next, register the camera preset in the library. + +```php +use muqsit\libcamera\libcamera; + +// ... + +libcamera::registerPreset(CustomCameraPresetRegistry::CUSTOM_FREE()); +``` + +Third, use `CustomCameraPresetRegistry::CUSTOM_FREE()` directly. + +```php +use muqsit\libcamera\libcamera; +use muqsit\libcamera\CameraInstruction; +use pocketmine\network\mcpe\protocol\types\camera\CameraPreset; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEase; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionEaseType; +use pocketmine\network\mcpe\protocol\types\camera\CameraSetInstructionRotation; +use pocketmine\network\mcpe\protocol\types\camera\Vector3; +use pocketmine\player\Player; +use muqsit\libcamera\CameraPresetRegistry; + +// ... +if($player instanceof Player && $player->isOnline()){ + /** + * @phpstan-param CameraPreset $preset + * @phpstan-param CameraSetInstructionEase|null $ease + * @phpstan-param Vector3|null $camera_pos + * @phpstan-param CameraSetInstructionRotation|null $rot + * @phpstan-param Vector3|null $facing_pos + */ + CameraInstruction::set( + preset: CustomCameraPresetRegistry::CUSTOM_FREE(), + ease: new CameraSetInstructionEase( + CameraSetInstructionEaseType::IN_OUT_CUBIC, + (float) 5.0 // duration (sec) + ), + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float)20.0, //pitch + (float)180.0 //yaw + ), + facing_pos: null + )->send($player); +} +``` + # camera technic - use @@ -281,61 +397,6 @@ use pocketmine\scheduler\ClosureTask; use pocketmine\entity\Zombie; use muqsit\libcamera\CameraPresetRegistry; ``` - -## linear-demo - -Want to move the camera freely? Use ease! - -
- See demo - -https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 - -
- -```php - public function onUse(PlayerItemUseEvent $event) : void{ - $player = $event->getPlayer(); - if(!$player->isSneaking()){ - return; - } - if($player instanceof Player&&$player->isOnline()){ - //linear - - $do = $player->getDirectionVector()->multiply(10); - - CameraInstruction::multi( - CameraInstruction::set( - preset: CameraPresetRegistry::FREE(), - ease: null, - camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace - rot: new CameraSetInstructionRotation( - (float) $player->getLocation()->getPitch(), //pitch - (float) $player->getLocation()->getYaw() //yaw - ), - facing_pos: null - ), - CameraInstruction::set( - preset: CameraPresetRegistry::FREE(), - ease: new CameraSetInstructionEase( - CameraSetInstructionEaseType::LINEAR, - (float) 7.0 // duration (sec) - ), - camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0)->addVector($do), //Without it, the camera will teleport into subspace - rot: new CameraSetInstructionRotation( - (float) $player->getLocation()->getPitch(), //pitch - (float) $player->getLocation()->getYaw() //yaw - ), - facing_pos: null - ) - )->send($player); - - $this->getScheduler()->scheduleDelayedTask(new ClosureTask(function() use ($player){ - CameraInstruction::clear()->send($player); - }), 20 * 7); - } - } -``` # Eases @@ -1217,6 +1278,66 @@ https://github.com/user-attachments/assets/d2b91349-08b2-4273-91e2-f60d14d76423
+## linear-demo + +Want to move the camera freely? Use ease! + +
+ +see Code + +```php +public function onUse(PlayerItemUseEvent $event) : void{ + $player = $event->getPlayer(); + if(!$player->isSneaking()){ + return; + } + if($player instanceof Player&&$player->isOnline()){ + //linear + + $do = $player->getDirectionVector()->multiply(10); + + CameraInstruction::multi( + CameraInstruction::set( + preset: CameraPresetRegistry::FREE(), + ease: null, + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: null + ), + CameraInstruction::set( + preset: CameraPresetRegistry::FREE(), + ease: new CameraSetInstructionEase( + CameraSetInstructionEaseType::LINEAR, + (float) 7.0 // duration (sec) + ), + camera_pos: $player->getPosition()->add(0.0, $player->getEyeHeight(), 0.0)->addVector($do), //Without it, the camera will teleport into subspace + rot: new CameraSetInstructionRotation( + (float) $player->getLocation()->getPitch(), //pitch + (float) $player->getLocation()->getYaw() //yaw + ), + facing_pos: null + ) + )->send($player); + + $this->getScheduler()->scheduleDelayedTask(new ClosureTask(function() use ($player){ + CameraInstruction::clear()->send($player); + }), 20 * 7); + } +} +``` + +
+ +
+ See demo + +https://github.com/user-attachments/assets/d5ca8d67-1ac6-4d2c-8051-db3455317cd6 + +
## spring-demo From cbfc2275facb81735595bd8c33c1b98ba33f8b60 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Wed, 16 Jul 2025 12:24:15 +0900 Subject: [PATCH 23/29] not plugin --- plugin.yml | 6 ------ src/muqsit/libcamera/libcameramain.php | 15 --------------- 2 files changed, 21 deletions(-) delete mode 100644 plugin.yml delete mode 100644 src/muqsit/libcamera/libcameramain.php diff --git a/plugin.yml b/plugin.yml deleted file mode 100644 index 9baad1d..0000000 --- a/plugin.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: libCamera -version: 0.0.1 -main: muqsit\libcamera\libcameramain -api: 5.31.0 -... diff --git a/src/muqsit/libcamera/libcameramain.php b/src/muqsit/libcamera/libcameramain.php deleted file mode 100644 index 8956414..0000000 --- a/src/muqsit/libcamera/libcameramain.php +++ /dev/null @@ -1,15 +0,0 @@ - Date: Wed, 16 Jul 2025 12:53:05 +0900 Subject: [PATCH 24/29] private static function newId() --- src/muqsit/libcamera/libcamera.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muqsit/libcamera/libcamera.php b/src/muqsit/libcamera/libcamera.php index f008a50..73cbe7e 100644 --- a/src/muqsit/libcamera/libcamera.php +++ b/src/muqsit/libcamera/libcamera.php @@ -33,7 +33,7 @@ public static function isRegistered(): bool{ public static array $network_ids; private static ?CameraPresetsPacket $packetCache = null; - public static function newId() : int{ + private static function newId() : int{ return self::$idCounter++; } From 9535029061ae9a8e21f2b513c2055f1fa9583041 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:03:53 +0900 Subject: [PATCH 25/29] fixbug in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a913bd4..7b11780 100644 --- a/README.md +++ b/README.md @@ -340,10 +340,10 @@ use muqsit\libcamera\libcamera; // ... -libcamera::registerPreset(CustomCameraPresetRegistry::CUSTOM_FREE()); +libcamera::registerPreset(CustomCameraPresetRegistry::CUSTOM_THIRD_PERSON_FRONT()); ``` -Third, use `CustomCameraPresetRegistry::CUSTOM_FREE()` directly. +Third, use `CustomCameraPresetRegistry::CUSTOM_THIRD_PERSON_FRONT()` directly. ```php use muqsit\libcamera\libcamera; From 822e1c698b9700e46281256da11122f8f87ba71e Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:13:08 +0900 Subject: [PATCH 26/29] WARNING: libcamera is not registered --- src/muqsit/libcamera/CameraInstruction.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index 8046409..159269f 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -37,6 +37,15 @@ public static function set( ?Vector3 $facing_pos = null ) : self{ if(!libcamera::isRegistered()){ + \GlobalLogger::get()->alert("WARNING: libcamera is not registered."); + \GlobalLogger::get()->alert("You must call libcamera::register(\$plugin) before using any camera instructions."); + \GlobalLogger::get()->alert("Example:"); + \GlobalLogger::get()->alert("public function onEnable() : void{"); + \GlobalLogger::get()->alert(" if(!AwaitForm::isRegistered()){ "); + \GlobalLogger::get()->alert(" AwaitForm::register(\$this);"); + \GlobalLogger::get()->alert(" }"); + \GlobalLogger::get()->alert("}"); + throw new \RuntimeException("libcamera::register() must be called before using CameraInstruction::set()"); } $preset_id = libcamera::$network_ids[spl_object_id($preset)][1] ?? throw new \InvalidArgumentException("Unknown camera preset, see libcamera::registerPreset()"); From b400707ee488c7acbb6b28e7a9ae9f459507c60e Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:15:43 +0900 Subject: [PATCH 27/29] fix --- src/muqsit/libcamera/CameraInstruction.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index 159269f..77a6511 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -37,14 +37,15 @@ public static function set( ?Vector3 $facing_pos = null ) : self{ if(!libcamera::isRegistered()){ - \GlobalLogger::get()->alert("WARNING: libcamera is not registered."); - \GlobalLogger::get()->alert("You must call libcamera::register(\$plugin) before using any camera instructions."); - \GlobalLogger::get()->alert("Example:"); - \GlobalLogger::get()->alert("public function onEnable() : void{"); - \GlobalLogger::get()->alert(" if(!AwaitForm::isRegistered()){ "); - \GlobalLogger::get()->alert(" AwaitForm::register(\$this);"); - \GlobalLogger::get()->alert(" }"); - \GlobalLogger::get()->alert("}"); + $looger = \GlobalLogger::get(); + $looger->alert("WARNING: libcamera is not registered."); + $looger->alert("You must call libcamera::register(\$plugin) before using any camera instructions."); + $looger->alert("Example:"); + $looger->alert("public function onEnable() : void{"); + $looger->alert(" if(!AwaitForm::isRegistered()){ "); + $looger->alert(" AwaitForm::register(\$this);"); + $looger->alert(" }"); + $looger->alert("}"); throw new \RuntimeException("libcamera::register() must be called before using CameraInstruction::set()"); } From a8579dccb95eb97426f2ea6b8c76f777441631dd Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:22:05 +0900 Subject: [PATCH 28/29] fixPrefixedLogger --- src/muqsit/libcamera/CameraInstruction.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index 77a6511..a54dccf 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -38,14 +38,15 @@ public static function set( ) : self{ if(!libcamera::isRegistered()){ $looger = \GlobalLogger::get(); - $looger->alert("WARNING: libcamera is not registered."); - $looger->alert("You must call libcamera::register(\$plugin) before using any camera instructions."); - $looger->alert("Example:"); - $looger->alert("public function onEnable() : void{"); - $looger->alert(" if(!AwaitForm::isRegistered()){ "); - $looger->alert(" AwaitForm::register(\$this);"); - $looger->alert(" }"); - $looger->alert("}"); + $looger = new \PrefixedLogger($looger, "libcamera"); + $looger->info("WARNING: libcamera is not registered."); + $looger->info("You must call libcamera::register(\$plugin) before using any camera instructions."); + $looger->info("Example:"); + $looger->info("public function onEnable() : void{"); + $looger->info(" if(!AwaitForm::isRegistered()){ "); + $looger->info(" AwaitForm::register(\$this);"); + $looger->info(" }"); + $looger->info("}"); throw new \RuntimeException("libcamera::register() must be called before using CameraInstruction::set()"); } From d1d0dac188149506c5df6a39affca33053a73c78 Mon Sep 17 00:00:00 2001 From: DaisukeDaisuke <17798680+DaisukeDaisuke@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:23:52 +0900 Subject: [PATCH 29/29] fix typo --- src/muqsit/libcamera/CameraInstruction.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/muqsit/libcamera/CameraInstruction.php b/src/muqsit/libcamera/CameraInstruction.php index a54dccf..40c66e5 100644 --- a/src/muqsit/libcamera/CameraInstruction.php +++ b/src/muqsit/libcamera/CameraInstruction.php @@ -37,16 +37,16 @@ public static function set( ?Vector3 $facing_pos = null ) : self{ if(!libcamera::isRegistered()){ - $looger = \GlobalLogger::get(); - $looger = new \PrefixedLogger($looger, "libcamera"); - $looger->info("WARNING: libcamera is not registered."); - $looger->info("You must call libcamera::register(\$plugin) before using any camera instructions."); - $looger->info("Example:"); - $looger->info("public function onEnable() : void{"); - $looger->info(" if(!AwaitForm::isRegistered()){ "); - $looger->info(" AwaitForm::register(\$this);"); - $looger->info(" }"); - $looger->info("}"); + $logger = \GlobalLogger::get(); + $logger = new \PrefixedLogger($logger, "libcamera"); + $logger->info("WARNING: libcamera is not registered."); + $logger->info("You must call libcamera::register(\$plugin) before using any camera instructions."); + $logger->info("Example:"); + $logger->info("public function onEnable() : void{"); + $logger->info(" if(!AwaitForm::isRegistered()){ "); + $logger->info(" AwaitForm::register(\$this);"); + $logger->info(" }"); + $logger->info("}"); throw new \RuntimeException("libcamera::register() must be called before using CameraInstruction::set()"); }