Jump to content

Render Model face closest player function(s)


Durand1w

Recommended Posts

hello,

 

I'm working on my fourth mini-mod for our server and I have ran into a road block.  I have a working glass block with particle effects that renders a smaller custom model inside of it which I can spin on all 3 axis.  At this point, rather than having it just spin freely, I want it to face the nearest player within X blocks.  For  the model facing the nearest player inside the render class, what functions are available to be used?

 

I have looked at the enchanting table (which is similar but only on one axis) as well as the mob AI faceplayer methods, but I feel like I am reinventing the wheel and likely missing a separate class that was designed specifically for rendered models.

 

I have done some coding attempting to use the line below, but I'm hoping for a better method to look at rather than getting the x,y,z coordinates and trying to run the rotations using loops and some creative math.

 

EntityPlayer entityplayer = this.worldObj.getClosestPlayer(this.xCoord, this.yCoord, this.zCoord, 8.0D);

 

Please let me know if you have any suggestions.  Thanks!

Link to comment
Share on other sites

Hi

 

I think the code is so simple (short) you needn't bother looking too hard.  Just copy it out of the entity facing code which makes (eg) the wolf look at you.  Your code just needs to provide it with the relative [x,y,z] of the nearest player which I think you have figured out already?

 

You need the yaw and the pitch.  EntityLookHelper.onUpdateLook() does the calculations like this, i.e.

 

            
            double d0 = this.posX - this.entity.posX;
            double d1 = this.posY - (this.entity.posY + (double)this.entity.getEyeHeight());
            double d2 = this.posZ - this.entity.posZ;
            double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2);
            float f = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
            float f1 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI));
            this.entity.rotationPitch = this.updateRotation(this.entity.rotationPitch, f1, this.deltaLookPitch);
            this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, f, this.deltaLookYaw);

 

-TGG

Link to comment
Share on other sites

I was able to get the block model to follow the player over the weekend.  I did find a coding issue when there are multiple enderpad blocks...

 

I set the pitch and yaw variables that I need in the renderer to static and used getEnderEyePitch and Yaw in the renderer to pull the variables down so I could use them in the rotation.  The result is that each newly placed enderpad block updates itself to the player and the older blocks mimic the new block, rather than maintaining their own pitch and yaw based on the player. 

 

I don't believe writing NBT data is a good solution since this would involve countless updates per tick.  I also haven't been able to find how this is performed for the enchantment table tile entity/special renderer (which is the same principle but only has one variable, not 2).  The placement of the ender eye model in the block is only cosmetic and does not impact game play, so I don't believe packets are the solution?  I'm trying to determine the best/better way to have each ender pad block model use it's own instance variables.

 

I'm not sure this is needed, but I have posted what I have at the moment.

 

TileEntityEnderPadEye

 

package com.tyr.enderpads;

 

import java.math.RoundingMode;

import java.util.Random;

import net.minecraft.entity.Entity;

import net.minecraft.entity.EntityLiving;

import net.minecraft.entity.EntityLivingBase;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.tileentity.TileEntity;

import net.minecraft.util.MathHelper;

 

public class TileEntityEnderPadEye extends TileEntity

    private EntityPlayer enderpadplayer;

    // The amount of change that is made each update for an entity facing a direction.

    private float enderpadpitch;

    private float enderpadyaw;

//    private float eyeresetspeed = 1.0F;

//    public static float enderpadroll;

 

public boolean anyPlayerInRange()

{

return this.worldObj.getClosestPlayer((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D, 8) != null;

}

 

public void updateEntity()

{

        super.updateEntity();

       

enderpadplayer = this.worldObj.getClosestPlayer((double)((float)this.xCoord + 0.5F), (double)((float)this.yCoord + 0.5F), (double)((float)this.zCoord + 0.5F), 8.0D);

//System.out.println(enderpadplayer);

     

// FUTURE LOGIC FOR SMOOTHLY TRANSITIONING BACK TO DEFAULT POSITION

if (enderpadplayer == null)

{

// while (enderpadyaw != 0.0F)

// {

// enderpadyaw -= eyeresetspeed;

// if (enderpadyaw <= 360)

  //     {

  //         enderpadyaw -= 360;

  //     }

// }

// while (enderpadpitch != 90.0F)

// {

// enderpadpitch += eyeresetspeed;

// if (enderpadpitch <= 360)

  //     {

// enderpadpitch -= 360;

  //     }

// }

enderpadyaw = 0.0F;

enderpadpitch = 90.0F;

// enderpadroll = 180.0F;

}

else if (enderpadplayer != null)

{

// System.out.println("GreenLight");

// Code to follow player while in range

double d0 = this.xCoord +0.5 -  this.enderpadplayer.posX;  // NEED TO ROUND TO REDUCE FLICKER BUT EXISTING BIG DECIMAL METHOD DOESN"T WORK!!!!

        double d1 = this.yCoord + 0.5 - (this.enderpadplayer.posY + (double)this.enderpadplayer.getEyeHeight());

        double d2 = this.zCoord + 0.5 - this.enderpadplayer.posZ;

        double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2);

//        System.out.println("xCoord" + xCoord);

//        System.out.println("yCoord" + yCoord);

//        System.out.println("zCoord" + zCoord);

//        System.out.println("d0" + d0);

//        System.out.println("d1" + d1);

//        System.out.println("d2" + d2);

        enderpadyaw = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;

        enderpadpitch = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI));

//        enderpadroll = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;

//        System.out.println("enderpadyaw" + enderpadyaw);

//        System.out.println("enderpadpitch" + enderpadpitch);

}

}

 

public float getEnderPadYaw()

{

return enderpadyaw;

}

 

public float getEnderPadPitch()

{

return enderpadpitch;

}

 

// public static float getEnderPadRoll()

// {

// return enderpadroll;

// }

 

}

 

 

 

 

RendererEnderPadEye

 

package com.tyr.enderpads;

 

import org.lwjgl.opengl.GL11;

 

import net.minecraft.client.Minecraft;

import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;

import net.minecraft.entity.Entity;

import net.minecraft.entity.EntityLiving;

import net.minecraft.entity.EntityLivingBase;

import net.minecraft.tileentity.TileEntity;

import net.minecraft.util.MathHelper;

import net.minecraft.util.ResourceLocation;

 

public class RendererEnderPadEye extends TileEntitySpecialRenderer

{

private ModelEnderPadEye model = new ModelEnderPadEye();

 

public void TileEntityEnderPadEye()

{

this.model=new ModelEnderPadEye();

}

 

public void renderTileEntityAt(TileEntity entity, double x, double y, double z, float f)

{

GL11.glPushMatrix();

GL11.glTranslated(x+0.5F, y+0.5F, z+0.5F); // Location to start render

 

ResourceLocation textures = (new ResourceLocation(Reference.MODID + ":" + "textures/tileentity/ender_pad_eye.png"));

Minecraft.getMinecraft().renderEngine.bindTexture(textures);

 

        GL11.glPushMatrix();

        // GL11.glRotatef(180F, 0.0F, -1.0F, 1.0F);  //  Manually Rotate to default position

       

       

        //2 values needed in Render class previously defined as static - flagged

        float enderpadyaw = TileEntityEnderPadEye.getEnderPadYaw();

        float enderpadpitch = TileEntityEnderPadEye.getEnderPadPitch();

 

//        if (enderpadyaw == 0.0F || enderpadpitch == 90.0F)  //No Player Around, move to default position

//        {

//        while (resetyaw != enderpadyaw)

//        {

//        resetyaw += eyeresetspeed;

//        if (resetyaw <= 360)

//         {

//             resetyaw -= 360;

//         }

//        GL11.glRotatef(resetyaw, 0.0F, -1.0F, 0.0F);

//        }

//        while (resetpitch != enderpadpitch)

//        {

//        resetpitch += eyeresetspeed;

//        if (resetpitch <= 360)

//         {

//             resetpitch -= 360;

//         }

//                GL11.glRotatef(resetpitch, 1.0F, 0.0F, 0.0F);

//        }

//        }

//        else  //Follow the Player

 

            GL11.glRotatef(enderpadyaw, 0.0F, -1.0F, 0.0F);

            GL11.glRotatef(enderpadpitch, 1.0F, 0.0F, 0.0F);

 

       

//        float enderpadroll = TileEntityEnderPadEye.getEnderPadRoll();

//        GL11.glRotatef(enderpadroll, 0.0F, 0.0F, 1.0F);

           

        this.model.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);

       

GL11.glPopMatrix();

        GL11.glPopMatrix();

}

}

 

 

Link to comment
Share on other sites

Hi

 

I'm not sure I understand why you used static

        float enderpadyaw = TileEntityEnderPadEye.getEnderPadYaw();

        float enderpadpitch = TileEntityEnderPadEye.getEnderPadPitch();

instead of per-tile-entity-instance variables, i.e.

        float enderpadyaw = entity.getEnderPadYaw();

        float enderpadpitch = entity.getEnderPadPitch();

 

Alternatively, your renderer doesn't actually need the tileentity to do the calculations.  The x, y, z passed to your renderTileEntityAt is the relative position of the tile entity compared to the player's eyes, which is enough to calculate which direction the tile entity needs to face to be looking at the player - i.e. the d0, d1, d2 in EntityLookHelper.onUpdateLook()

 

-TGG

 

 

 

 

Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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