Jump to content

Recommended Posts

Posted (edited)

Right to the question: how minecraft achieves smooth entity rendering? As far as I know and experimented with Logging of entity's position in render method, it is updated, like, 20 times per second, which equals to 1 tick.(No, it isn't!) So it seems like while rendering, minecraft uses entity's speed to determine where it should be, or what?

 

The problem is, while standing still, player's getMotion().toString() returns (0.0, -0.0784000015258789, 0.0). Is this really gives velocity? Is -0.0784... a deviation? If so, what is a unit velocity here? 1 block/tick? 1 px/tick? (Here by px i mean 1/16 block)

 

Ok, here is the problem I met. I need to render an entity at a fixed position for the player, as if it is a part of it.

Here is my render method in renderer class:

public void render(MyEntity entityIn, float entityYaw, float partialTicks, MatrixStack matrixStackIn,
            IRenderTypeBuffer bufferIn, int packedLightIn) {
        if (entityIn.getOwner() != null) {
            PlayerEntity owner = entityIn.world.getPlayerByUuid(entityIn.getOwner().getUniqueID()); //Will optimize that later, nevermind. Owner is a player I should stick to.
//            entityIn.setRawPosition(owner.getPosX(), owner.getPosY(), owner.getPosZ()); (first try to stick entity to player, resulted 20 times per second jumping)
            LOG.info("Entity's position: {}", entityIn.getPositionVec().toString()); //Used to see, that position updates every 3 frames with 60FPS.
            matrixStackIn.push();
//            Vector3d move = owner.getPositionVec().add(entityIn.getPositionVec().scale(-1)).add(owner.getMotion().scale(partialTicks-1f)); //Uses player motion, so while standing still, entity vibrates. I'm sure it's caused my motion, because without last component entity stops vibrating.
//            Vector3d move = owner.getMotion().scale(partialTicks);
          //Upwards you may see other attempts to achieve a goal. None worked.
            Vector3d move = owner.getPositionVec().add(entityIn.getPositionVec().scale(-1)); //
            matrixStackIn.translate(move.x+1D, move.y, move.z); //Tried to move 1 block, to see if it works
            //TODO definitely should find a better way for that!
            LOG.info("Moving matrix a bit: {}, owner's motion: {}", move.toString(), owner.getMotion().toString()); //This is what outputs that strange -0.07... motion.
            model.setRotationAngles(entityIn, partialTicks, 0.0F, -0.1F, 0.0F, 0.0F); // TODO describe (does nothing yet, will describe after achieving smooth)
            IVertexBuilder ivertexbuilder = bufferIn.getBuffer(model.getRenderType(this.getEntityTexture(entityIn))); //Copied form boat renderer, as far as I remember...
            model.render(matrixStackIn, ivertexbuilder, packedLightIn, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F,
                    1.0F);

            matrixStackIn.pop();
        } else {
            LOG.info("Owner is null, not rendering");
        }
        super.render(entityIn, entityYaw, partialTicks, matrixStackIn, bufferIn, packedLightIn);
    }

Also, I included raw

this.setPositionAndUpdate(owner.getPosX(), owner.getPosY(), owner.getPosZ());

to entity's tick() method, and I'm sure it's executed on both client and server (Both Server and Render thread are logging message).

By entity in the world start jumping a bit along player's moving direction, as you start to move. Jump distances are proportional to player's velocity. Obviously, this indicates low position update rate, because while using 20FPS render everything works as I'd like to.

 

Would be graceful for any help about all that, thank you.

Edited by Dzuchun
No, entitys position is not updated 20 times per second, only once per 3 ticks.

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)
  On 7/14/2020 at 9:01 AM, poopoodice said:

From my experience the motion of player is (0.0, -0.0784000015258789, 0.0) when still is because there's gravitational acceleration

Expand  

Yep, I think so too, and now I tried to get speed with:

Vector3d ownerSpeed = new Vector3d(owner_.getPosX() - owner_.lastTickPosX,
                                   owner_.getPosY() - owner_.lastTickPosY,
                                   owner_.getPosZ() - owner_.lastTickPosZ);

and looks like it works correctly. So i determined move vector as:

move = ownerSpeed.scale(partialTicks);

And translated matrixStack with it:

matrixStackIn.translate(move.x, move.y, move.z);

(Of course, I make pushes and pops)

But entity still renders as hell, am I missing something?

 

UPDATE:

I realized, that ownerSpeed vector actually determines player's movement during current partialTicks time. So I removed scale method and assigned directly move=ownerSpeed. Result is a bit better now.

Edited by Dzuchun
Described further actions

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)

I'm definitely doing something wrong, because even setting constant motion to entity (gravitation was asked to be disabled both on client and server) results jumps with a little shaking.

WHAT SHOULD BE DONE, TO MOVE ENTITY SMOOTH??

(I'm really desprate)

Edited by Dzuchun

Everything said above may be absolutely wrong. No rights reserved.

Posted
  On 7/14/2020 at 8:32 AM, Dzuchun said:

Right to the question: how minecraft achieves smooth entity rendering? As far as I know and experimented with Logging of entity's position in render method, it is updated, like, 20 times per second, which equals to 1 tick. So it seems like while rendering, minecraft uses entity's speed to determine where it should be, or what?

Expand  

With entity speed (or how much it moved during last tick) and interpolation.

Interpolation is multiplying the difference in distance in that tick by the partial ticks of that frame, and add that to the previous position to achieve smooth movement.

  • Thanks 1

Some tips:

  Reveal hidden contents

 

Posted (edited)
  On 7/14/2020 at 9:23 PM, poopoodice said:

Are you using render player event to render your own thing? The event is called whenever the player is being rendered hence you can have same update rate as the player.

Expand  

Previous time I've tried to make this mod, I tried to start with this. the problem is, this event is not called, if you're using 1st perspective view (default one). But I want for player to see entity from any perspective.
Of cource, I solved this problem with overriding one more event - something about GUI. But this requires twice as much render methods, and separate matrixStack transformations - GUI matrix at start is bound to camera pos and rotation, when RenderPlayerEvent just to PlayerEntity's position. But yeah, that rendered without any shaking and so on.

  On 7/15/2020 at 1:04 AM, DavidM said:

With entity speed (or how much it moved during last tick) and interpolation.

Expand  

How would I get it? Should I store last tick pos separately, because It looks like Entity.lastTickPos- variables store position at begining of current tick. Actually, I don't really get how Entity.prevPos- and Entity.lastTickPos- differ - as I can see, the only place they are reassigned is Entity#forceSetPosition(double x, double y, double z), and here is reassignment:

this.prevPosX = x;
this.prevPosY = y;
this.prevPosZ = z;
this.lastTickPosX = x;
this.lastTickPosY = y;
this.lastTickPosZ = z;

...

  On 7/15/2020 at 1:04 AM, DavidM said:

Interpolation is multiplying the difference in distance in that tick by the partial ticks of that frame, and add that to the previous position to achieve smooth movement.

Expand  

Isn't it what I've done here?:

  On 7/14/2020 at 8:32 AM, Dzuchun said:
// Vector3d move = owner.getMotion().scale(partialTicks);

 

Expand  

Or again, should I calculate speed by myself? How would I do that? Also, using owner's motion gets less jumping than using it's own motion, I suspect no matter what it's motion is always 0, despite I'm calling

MyEntity.setMotion(owner.getMotion());

every tick on both client and server.

 

EDIT:
And where can I see minecraft doing this things? None of renderers are handling that, they're just using matrixStack to render what they need, not even calling entity#getMotion(). Should I use some event?

Edited by Dzuchun

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)

Now I achieved the end of line: every tick on server, entity sends a custom packet to all tracking clients. Clientside entity instance has separate variables for storing previous tick position and real position change during last tick, for me to use them in rendering. And move vector looks like this:

Vector3d move = entityIn.getRealMotion().scale(partialTicks).add(entityIn.getRealPos().add(entityIn.getPositionVec().scale(-1)));

So, I calculate position change due to moving for last partialTiks (getRealMotion() returns REAL motion I calculated with sending packets) AND add to it difference between my entity position and wherever minecraft thinks entity is. This means, that after matrixStackIn.translate(move.x, move.y, move.z) I am at my coordinates (that were certainly unchanged during last tick) + offset from MY personal calculated speed (that couldn't be changed too).

And in the game, like, 70% of the time it looks flawless, but then entity starts jumping over the movement direction.

Looks like minecraft changes coordinates of the entity during rendering, so even with such a complicated code you can't adapt for it.

 

NOTE: No, I can't use Entity.lastTickPos- variables, because they are updated, like, 6-7 times per second, or once in 3 ticks.

Edited by Dzuchun

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)
  On 7/15/2020 at 9:36 PM, poopoodice said:

Another idea is to see how parrots sit on the player's shoulders.

Expand  

Nope, same render and tick methods as everywhere, except handling dancing near jukebox :D

Edited by Dzuchun

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)
  On 7/15/2020 at 9:36 PM, poopoodice said:

You may find this interesting

Expand  

The problem is, position on client is updated not every tick, but once at ~3 ticks and this update is kinda laggy - breaks any algorythm I create.

Here is how to prove once-at-3-ticks update:

if (prevPos != entityIn.getPositionVec()) {
    Long currentTime = System.currentTimeMillis();
    LOG.info("Render after {}ms at new position", currentTime-prevPosTime);
    prevPosTime = currentTime;
    prevPos = entityIn.getPositionVec();
}

(placed in render method; prevPos and prevPosTime are fields; outputs ~150ms, which is ~3 ticks)

So with suggested code in the article you will get a total hell - 3 times entity jumps back at one position, and this 6-7 times per second.

What's interesting, same applies to PlayerEntity. That's why I am curious, why smooth render in minecraft is even possible.

 

  On 7/15/2020 at 11:57 AM, Dzuchun said:

Now I achieved the end of line

Expand  

Actually, here I have approximately 6 unexpected jumps per second.

 

Let me remind: my entity extends Entity class directly, so I checked BoatEntity class and renderer before writing all that.

Edited by Dzuchun

Everything said above may be absolutely wrong. No rights reserved.

Posted
  On 7/16/2020 at 7:44 AM, Dzuchun said:

Nope, same render and tick methods as everywhere, except handling dancing near jukebox :D

Expand  

Oh yeah, they are actually a part of layers.

Or is it possible instead of getting the position of the player when render, sync the position of custom entity with the owner on server then just render it normally?

Posted
  On 7/16/2020 at 9:11 AM, diesieben07 said:

Position is synced to the client very 3 ticks (usually, depends on the entity, this is called "update frequency").

You need to update the position on server and client every tick. The client needs to do the same calculations. Then the update every 3 ticks only ensures any slight deviation is corrected.

Expand  

Sounds logical, I think I got the idea, and according to it I've updated my code. Now:

Every tick, both on client and server, tick() method of my entity executes folowing:

if (hasOwner()) {
	setPositionAndUpdate(owner.getPosX(), owner.getPosY(), owner.getPosZ());
	setMotion(owner.getPosX()-owner.lastTickPosX, owner.getPosY()-owner.lastTickPosY, owner.getPosZ()-owner.lastTickPosZ);
  	LOG.info("Setting motion {}", getMotion());
}

I am sure, that hasOwner() returns true, and code is executed.

Every frame, at render method I execute folowing:

matrixStackIn.push();
matrixStackIn.translate(entityIn.getMotion().x*partialTicks, entityIn.getMotion().y*partialTicks, entityIn.getMotion().z*partialTicks);
model.setRotationAngles(entityIn, partialTicks, 0.0F, -0.1F, 0.0F, 0.0F); // TODO describe (does nothing yet)
IVertexBuilder ivertexbuilder = bufferIn.getBuffer(model.getRenderType(this.getEntityTexture(entityIn)));
model.render(matrixStackIn, ivertexbuilder, packedLightIn, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F);
matrixStackIn.pop();
super.render(entityIn, entityYaw, partialTicks, matrixStackIn, bufferIn, packedLightIn);

But entity jumps like hell, now with any framerate setting. I'm sure that this render method is used - if change it, entity render changes as well.

Super method is Entity#render, as I can see, It renders nameplate (as I can see), executing it before matrixStackIn.pop() changes nothing (tested).

 

So, how exactly should I

  On 7/16/2020 at 9:11 AM, diesieben07 said:

update the position on server and client every tick.

Expand  

? Am I doing it correctly?

Everything said above may be absolutely wrong. No rights reserved.

Posted
  On 7/16/2020 at 10:18 AM, diesieben07 said:

Why are you translating by motion? That doesn't make any sense.

You also set the motion of your entity to the position of it's owner... Meaning if the owner is at [10, 30, 10] your entity will try to move (travel) 10 blocks x, 30 blocks up, 10 blocks z in the next tick.

Expand  

 

  On 7/16/2020 at 10:11 AM, Dzuchun said:

setMotion(owner.getPosX()-owner.lastTickPosX, owner.getPosY()-owner.lastTickPosY, owner.getPosZ()-owner.lastTickPosZ);

Expand  

 I'm sorry, but I can see here a setting of motion to a difference of two owner's positions.

Everything said above may be absolutely wrong. No rights reserved.

Posted
  On 7/16/2020 at 10:25 AM, diesieben07 said:

I guess I read that wrong, but that still does not make much sense to me.

What are you trying to achieve by that?

Expand  

I'm trying to calculate owner's speed. getMotion() won't work because:

 

  On 7/14/2020 at 8:32 AM, Dzuchun said:

The problem is, while standing still, player's getMotion().toString() returns (0.0, -0.0784000015258789, 0.0).

Expand  

Probably, I should use other fields? Should I store something manually?

Everything said above may be absolutely wrong. No rights reserved.

Posted
  On 7/16/2020 at 10:32 AM, diesieben07 said:

Why do you want the owner's speed? What is the effect you want to achieve?

Expand  

I want to assign the same speed to my entity, to achieve is being rendered as if it is glued to a player. I would like to see it in any perspective, so I can't just render it at RenderPlayerEvent.

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)
  On 7/14/2020 at 8:32 AM, Dzuchun said:

The problem is, while standing still, player's getMotion().toString() returns (0.0, -0.0784000015258789, 0.0)

Expand  

I can't: while standing still, entity falls underground and then jumps back. I've tried to check if player is collided vertically and if so, add this constant vector to result, but that didn't work - Entity.collidedVertically seemed to be false at any time.

Edited by Dzuchun
comas are importaint!

Everything said above may be absolutely wrong. No rights reserved.

Posted (edited)

Code:

if (owner.collidedVertically) {
  setMotion(owner.getMotion().add(MOTION_CONSTANT_1));
} else {
  setMotion(owner.getMotion());
}	
LOG.info("Set motion to entity {}, owner's motion: {}", getMotion(), owner.getMotion());

Output:

  Quote

[m[32m[14:11:11] [Render thread/INFO] [dz.wi.en.mi.WingsEntity/]: Set motion to entity (-0.9237963696043886, 0.0, -0.07976295232791968), owner's motion: (-0.9237963696043886, 0.0, -0.07976295232791968)
[m[32m[14:11:11] [Server thread/INFO] [dz.wi.en.mi.WingsEntity/]: Set motion to entity (0.0, 0.0, 0.0), owner's motion: (0.0, 0.0, 0.0)

Expand  

Me:

HMMMMMMMMM, Player's motion on server is 0? I swear, no changes were applied by my mod. Should I update owner field, probably? Like, every tick get owner by it's UUID?

So that's why with my personal update message sent every tick, entity once in 3 ticks got teleported back.

Edited by Dzuchun

Everything said above may be absolutely wrong. No rights reserved.

Posted

I just realized, that it is impossible to guarantee, that my entity ticks after it's owner, that's why I get it jumping.

Is it possible, somehow, to guarantee that entity ticks after another entity?

 

Everything said above may be absolutely wrong. No rights reserved.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Ignore shrimple, it doesn't work with Oculus. Also, enableShaders was alr true when it said that towards the end of the log. If you could also figure out why my tags are messed up that'd be cool too, but that's a later issue. https://drive.google.com/drive/folders/1ovEKDZECUCl7zZxGfpyQcS4s5PZPQyfa?usp=drive_link
    • accidental duplicate mesage cuz lag
    • https://gnomebot.dev/paste/231527759279685634/1372324909073563730/1372324908629102716 https://gnomebot.dev/paste/231527759279685634/1372320454861262908/1372320454299090996 seems like theres a registry sync error, not sure what that means though, however in an old pack i played on, i actually had a registry sync error happen whenever the world tried too save and it would suddenly stop loading chunks, is there a mod fix for this or some way too bypass registry syncing? is this a server problem? i have no issues with the pack on pc, only on my server.
    • i think the problem is the player animator library but i need it for one of my main mods is there any way i can fix this? The game crashed: rendering overlay Error: java.lang.IllegalArgumentException: Failed to create player model for default heres the crash report: https://pastebin.com/U5Wp8ysb
    • I have been an enthusiastic investor in crypt0currencies for several years, and my digital assets have been integral to my financial strategy. A few months ago, I encountered a distressing predicament when I lost access to my primary cryptocurrency walleet after clicking on an airdrop link that inadvertently connected to my walleet. The dread of potentially losing all my hard-earned funds was overwhelming, leaving me uncertain about where to seek assistance. In my pursuit of solutions, I stumbled upon ChainDigger Retrievers. From our initial consultation to the triumphant recovery of my assets, the team exhibited exceptional expertise. They provided comprehensive explanations of the recovery process, ensuring I was informed at every stage and offering reassurance during this tumultuous time. Their approach was not only meticulous but also compassionate, which significantly alleviated my anxiety. ChainDigger Retrievers unwavering commitment to resolving my issue was evident throughout the process. Leveraging their profound understanding of crypt0currency technology and digital forensics, they initiated an exhaustive investigation to trace the transactions linked to my compromised wallet. Their meticulous analysis and relentless determination were apparent as they left no stone unturned in their quest to recover my funds. After several days of diligent investigation, the team successfully recovered everything I had lost. They uncovered that the link I had clicked contained malware, which scammeers had used to infiltrate my walleet. This revelation was both alarming and enlightening, underscoring the inherent risks associated with crypt0currency transactions when proper precautions are not taken.Thanks to ChainDigger Retrievers, I not only regained everything but also acquired invaluable knowledge about safeguarding my investments. Their expertise and steadfast support transformed a daunting situation into a manageable one, and I am profoundly grateful for their assistance. I can now continue my investment journey with renewed confidence, knowing that I have a trustworthy ally in ChainDigger Retrievers. Their client satisfaction is truly commendable, and I wholeheartedly recommend their services to anyone facing similar challenges in the crypt0currency realm. With their help, I was able to turn a distressing time into a positive outcome, and I will forever be grateful for their support.  
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.