The eye height of cats is too low and does not change when the cat changes from standing/sitting pose. These incorrect eye heights cause the cat to look at a higher point than it actually should look at. Possibly a trivial issue or working as intended
A cat is 0.7 blocks high, this is 11.2 pixels (1 pixel = 1/16 block). The eye height of a cat is specified in code as 0.5 * height: the eye height of a cat is 5.6 pixels. This is incorrect when looking at the model. The cat has two main poses: sitting and standing.
- The eye height of a standing cat is actually 9.5 pixels. This is 3.9 pixels higher than the current eye height
- The eye height of a sitting cat is 3.3 pixels higher than a standing cat. This is 12.8 pixels. This is 7.2 pixels higher than the current eye height.
I've put a tamed cat sitting upon a block. The cat is sitting one block higher than the player is standing. I forgot to make the time daytime so sorry for the dark images.
Cat looking idle (straight forward):
Cat looking at player:
I took Blender and created a sitting and a standing calico-type cat (texture is mirrored somehow). When cats are idle, the cats look straight forward, not looking at any point:
The correct eye heights are way higher than the actual eye heights. For idle cats, this causes no problems, but for cats watching a specific point, they seem to watch over that point:
The standing cat more or less looks at the point but it's easy to see that it's not actually focusing on the point. A common thing a cat looks at is a player's head. The focus point is then moved towards the eye location of the player, or in first person: the camera. It will look like this:
The standing cat here is more or less looking into the camera, but the sitting cat visibly looks over the camera. Using the eye heights that resulted from the calculation above, which are the correct eye heights, the cats will look directly into the camera and the issue is fixed:
I used the code from 1.15.2 with Mojang mappings.
The cat seems to specify getStandingEyeHeight like this:
protected float getStandingEyeHeight( Pose pose, EntityDimensions dimens ) { return dimens.height * .5f; // Wrong eye height }
This is used only to initialize a field eyeHeight in net.minecraft.world.entity.Entity. This field is not final so it can be updated at any time. The cat's eye height should be updated every tick so that it is continuously synchronised with the cat's pose. A working and more correct solution would be:
// Ratio of eye height to full entity height (originally .5f) // Calculate these constants using: eyeHeightPx / blockInPx / adultCatBlock private static final float STANDING_EYE_HEIGHT_RATIO = 9.5f / 16 / .7f; private static final float SITTING_EYE_HEIGHT_RATIO = 12.8f / 16 / .7f; // ... public void tick() { super.tick(); updateEyeHeight(); if ( temptGoal != null && temptGoal.isRunning() && ! isTame() && tickCount % 100 == 0 ) { playSound( SoundEvents.CAT_BEG_FOR_FOOD, 1, 1 ); } handleLieDown(); } private void updateEyeHeight() { EntityDimensions dimens = getDimensions( Pose.STANDING ); eyeHeight = getStandingEyeHeight( Pose.STANDING, dimens ); } // ... protected float getStandingEyeHeight( Pose pose, EntityDimensions dimens ) { float heightRatio = isSitting() ? SITTING_EYE_HEIGHT_RATIO : STANDING_EYE_HEIGHT_RATIO; return dimens.height * heightRatio; }