Moving object based on camera direction

Started by
4 comments, last by MarlboroKing 11 years, 2 months ago

This one is a pickle. Basically, I am trying to keep a 3D object in the center of the camera. I figured the easy way would be to invert the view matrix, add 5 to the mat.Forward member and everything would be O.K. Well, now I don't even see it. My previous attempts were fiddling with the UpDown / LeftRight rotations, they worked for the most part but couldn't get it corrected without really hardcoding the issue (and even then didn't work properly). Been stuck on this for the past 3 or 4 days, really not much else I can think of.


if( nType != EItemType.None )
{
    Matrix matWorld = Matrix.Invert( m_Player.m_Camera.View );
    matWorld.Translation += (matWorld.Forward * 5);

    m_Effect.World = matWorld;
    m_Effect.View = m_Player.m_Camera.View;
    m_Effect.Projection = m_Player.m_Camera.Projection;
    m_Effect.TextureEnabled = true;
    m_Effect.Texture = m_Texture;

    foreach( EffectPass pass in m_Effect.CurrentTechnique.Passes ) 
    {
        pass.Apply();

        m_GraphicsDevice.BlendState = BlendState.AlphaBlend;

        m_GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>( PrimitiveType.TriangleList,    m_Verts.ToArray(), 0, 2 );

    }
}

-Edit- For the most part, this works:


Matrix matWorld = Matrix.Identity *
					Matrix.CreateScale( 2f ) *
					Matrix.CreateRotationZ( -m_Player.m_Camera.UpDownRot ) *
					Matrix.CreateRotationY( m_Player.m_Camera.LeftRightRot - MathHelper.PiOver2 ) *
					Matrix.CreateTranslation( m_Player.Position + (m_Player.LookVector * 0.3f) );

I thought I introduced tearing, but nope. Was able to angle my camera just right and noticed it was my item. Fixed!

Advertisement
if you just want it infront of the camera, set its local to the position you want infront of the cameraa and multiply it with the view matrix.
"There will be major features. none to be thought of yet"

One of the first few things I tried, perhaps I made a mistake on that particular one.. I'll give that a go again.

What bugs me is that the most obvious solutions seems to work, just not as expected, eg;


                Matrix matWorld = Matrix.Identity *
                    Matrix.CreateTranslation( m_Player.Position + m_Player.LookVector );

		m_Effect.World = matWorld;
		m_Effect.View = m_Player.m_Camera.View;
		m_Effect.Projection = m_Player.m_Camera.Projection;
		m_Effect.TextureEnabled = true;
		m_Effect.Texture = m_Texture; 

(Note that this attempt was copy/pasted from a part that determines which object the player is looking at, which works flawlessly, however said part multiplies Look by x)
The result is the object moving when the player looks, but it 'lags' behind (it doesn't keep up with the camera if the camera looks too far around). But, won't appear where the player is looking. It appears to have a different position when the game is running (I mean, when the game starts, I need to turn around completely in order to see it).
The LookVector appears to be correct before Normalizing, as well as Position during debugging.
I'm basically at a stand-still and completely baffled how it works perfectly on ClassA, except ClassB appears to just... Well, not work.

Don't mean to bump/spam/others..

Still haven't quite figured it out, but have found a resource to get this going. Seems pretty solid for anyone looking to do the above.

Needs some tweaks for my purpose, but does make good use of quaternion's (one thing I really need to switch to!).

http://www.dhpoware.com/demos/xnaFirstPersonCamera.html

I'd do something like this:

- when camera moves

- the object you want to keep static to camera -> worldpos = camerapos

- camerapos.z -= 5 or += 5?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

I'd do something like this:

- when camera moves

- the object you want to keep static to camera -> worldpos = camerapos

- camerapos.z -= 5 or += 5?

Tried. I figured something out new.. Well, observed. I imported a model that was designed in 3DWings into my content solution, redid my method and bam, it worked.

It appears I'm missing something (duh!) that the imported model has, that my coded model doesn't. I'm explaining what I've done below, but before I do, please note that I am still new to 3D and my code may not be completely efficient, the second is temporarily :]

I have a tilesheet of textures, used for the UV coordinates. I'm essentially taking the coordinates from the UV and building a array of VertexPositionTexture for the model:

VertexBuilder.BuildVertexFromUV


public static List<VertexPositionTexture> BuildVertexFromUV( Vector3 vecPosition, Vector2[] vecUV )
{
	List<VertexPositionTexture> ret = new List<VertexPositionTexture>();

	foreach( Vector2 uv in vecUV )
		ret.Add( new VertexPositionTexture( vecPosition + new Vector3(uv.X, uv.Y, 0), uv ) );

	return ret;
}

ItemRender.OnChangeItemInHand


public void OnChangeItemInHand( EItemType nType )
{
	if( nType != m_nItemHold )
	{
		m_Verts.Clear();

		m_Verts = BlockVertexBuilder.BuildVertexFromUV( new Vector3(0, 0, 0),
		new Vector3( 1, 0, 2 ),
		ItemTexture.m_UVMappings[(int)nType] );

		m_VB = new VertexBuffer( m_GraphicsDevice, typeof(VertexPositionTexture), m_Verts.Count, BufferUsage.WriteOnly );
		m_VB.SetData( m_Verts.ToArray() );

		m_nItemHold = nType;
	}
}

Again, all fine and dandy. Now, the glorified issue.

ItemRender.RenderItemInHand


public void RenderItemInHand( GameTime gameTime )
{
	EItemType nType = m_Player.PlayerInventory.GetHoldingItemType();
	OnChangeItemInHand( nType ); //Remember, temporarily :]

	if( nType != EItemType.None )
	{
		Matrix matWorld = Matrix.CreateScale( 2f ) *
			Matrix.CreateRotationX( fWeaponRotX ) *
			Matrix.CreateRotationY( fWeaponRotY ) *
			Matrix.CreateRotationZ( fWeaponRotZ ) *
			Matrix.CreateTranslation( vecWeaponRot ) *
			Matrix.CreateRotationZ( -m_Player.m_Camera.UpDownRot ) *
			Matrix.CreateRotationY( m_Player.m_Camera.LeftRightRot - MathHelper.PiOver2 ) *
			Matrix.CreateTranslation( m_Player.Position + (m_Player.LookVector * 0.3f) );

		m_Effect.World = matWorld;
		m_Effect.View = m_Player.m_Camera.View;
		m_Effect.Projection = m_Player.m_Camera.Projection;
		m_Effect.TextureEnabled = true;
		m_Effect.Texture = m_Texture;

		foreach( EffectPass pass in m_Effect.CurrentTechnique.Passes ) 
		{
			pass.Apply();

			m_GraphicsDevice.BlendState = BlendState.AlphaBlend;

			m_GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>( PrimitiveType.TriangleList, m_Verts.ToArray(), 0, 2 );
		}
	}
}
//Values in the rotation/translation above:
float fWeaponRotX = -0.3f;
float fWeaponRotY = 0.1f;
float fWeaponRotZ = -0.1f;
Vector3 vecWeaponRot = new Vector3( 0, -0.25f, -0.2f );

If anyone has any idea, please. In the mean time, I am going to write a small debugger for this so I can check what's happening in-game quicker and easier.

(P.S: I know this question has been posted A LOT on these forums, I have searched.. For days. So I apologize for the repetitiveness!)

This topic is closed to new replies.

Advertisement