/// <summary> /// Actualiza el Ray de colision en base a la posicion del mouse en la pantalla /// </summary> public void updateRay() { //Crear Ray en base a coordenadas del mouse var sx = Input.Xpos; var sy = Input.Ypos; var w = D3DDevice.Instance.Device.Viewport.Width; var h = D3DDevice.Instance.Device.Viewport.Height; var matProj = D3DDevice.Instance.Device.Transform.Projection; var v = new Mathematica.TGCVector3(); v.X = (2.0f * sx / w - 1) / matProj.M11; v.Y = -(2.0f * sy / h - 1) / matProj.M22; v.Z = 1.0f; //Transform the screen space pick ray into 3D space var m = TGCMatrix.Invert(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View)); var rayDir = new TGCVector3( v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31, v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32, v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33 ); var rayOrig = new TGCVector3(m.M41, m.M42, m.M43); //Picking Ray creado Ray.Origin = rayOrig; Ray.Direction = rayDir; }
/// <summary> /// Renderizar ejes segun posicion actual de la camara /// </summary> public void render() { //Obtener World coordinate de la esquina inferior de la pantalla var w = D3DDevice.Instance.Device.Viewport.Width; var h = D3DDevice.Instance.Device.Viewport.Height; var sx = AXIS_POS_OFFSET; var sy = h - AXIS_POS_OFFSET; var matProj = D3DDevice.Instance.Device.Transform.Projection; var v = new TGCVector3( (2.0f * sx / w - 1) / matProj.M11, -(2.0f * sy / h - 1) / matProj.M22, 1.0f); //Transform the screen space into 3D space var m = TGCMatrix.Invert(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View)); var rayDir = new TGCVector3( v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31, v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32, v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33); var rayOrig = new TGCVector3(m.M41, m.M42, m.M43); var worldCoordPos = rayOrig + AXIS_POS_DISTANCE * rayDir; //Renderizar TexturesManager.Instance.clear(0); TexturesManager.Instance.clear(1); D3DDevice.Instance.Device.Material = D3DDevice.DEFAULT_MATERIAL; D3DDevice.Instance.Device.Transform.World = TGCMatrix.Translation(worldCoordPos).ToMatrix(); D3DDevice.Instance.Device.VertexFormat = CustomVertex.PositionColored.Format; D3DDevice.Instance.Device.SetStreamSource(0, vertexBuffer, 0); D3DDevice.Instance.Device.DrawPrimitives(PrimitiveType.LineList, 0, 3); D3DDevice.Instance.Device.Transform.World = TGCMatrix.Identity.ToMatrix(); }
/// <summary> /// Cargar todas la matrices generales que necesita el shader. /// </summary> public void SetShaderMatrix(Effect effect, TGCMatrix world) { var matWorldView = world.ToMatrix() * D3DDevice.Device.Transform.View; var matWorldViewProj = matWorldView * D3DDevice.Device.Transform.Projection; effect.SetValue("matWorld", world.ToMatrix()); effect.SetValue("matWorldView", matWorldView); effect.SetValue("matWorldViewProj", matWorldViewProj); effect.SetValue("matInverseTransposeWorld", TGCMatrix.TransposeMatrix(TGCMatrix.Invert(world)).ToMatrix()); }
/// <summary> /// Actualiza la matriz de transformacion /// </summary> public void updateValues() { var rotationMatrix = TGCMatrix.RotationYawPitchRoll(rotation.Y, rotation.X, rotation.Z); //la matriz Transformation se usa para ubicar los vertices y calcular el vector HalfHeight Transform = TGCMatrix.Scaling(Radius, HalfLength, Radius) * rotationMatrix * TGCMatrix.Translation(center); //la matriz AntiTransformation convierte el cilindro a uno generico de radio 1 y altura 2 AntiTransformationMatrix = TGCMatrix.Invert(Transform); //la matriz AntiRotation sirve para alinear el cilindro con los ejes AntiRotationMatrix = TGCMatrix.Translation(-center) * TGCMatrix.Invert(rotationMatrix) * TGCMatrix.Translation(center); }
/// <summary> /// Configuracion inicial del esquleto /// </summary> protected void setupSkeleton() { //Actualizar jerarquia for (var i = 0; i < bones.Length; i++) { var bone = bones[i]; //Es hijo o padre if (bone.ParentBone == null) { bone.MatFinal = bone.MatLocal; } else { //Multiplicar por la matriz del padre bone.MatFinal = bone.MatLocal * bone.ParentBone.MatFinal; } //Almacenar la inversa de la posicion original del hueso, para la referencia inicial de los vertices bone.MatInversePose = TGCMatrix.Invert(bone.MatFinal); } }
public override void Update() { // 1) Crear una matriz de transformacion (de 4x4 para 3D) con la identidad var m = TGCMatrix.Identity; // 2) Crear una matriz de transformacion para traslacion var translate = TGCMatrix.Translation(new TGCVector3(100, -5, 0)); // 3) Crear una matriz de escalado para traslacion var scale = TGCMatrix.Scaling(new TGCVector3(2, 4, 2)); // 4) Crear una matriz de rotacion para traslacion var angleY = FastMath.PI_HALF; //En radianes var angleX = FastMath.ToRad(60); //De grados a radianes var angleZ = FastMath.PI / 14; var rotation = TGCMatrix.RotationYawPitchRoll(angleY, angleX, angleZ); //Ojo con el orden de los angulos // 5) Combinar varias matrices en una sola. El orden depende del movimiento que se quiera lograr var movimientoFinal = scale * rotation * translate; // 6) Transformar un punto en base al movimiento de una matriz de transformacion var p = new TGCVector3(10, 5, 10); var transformedVec4 = TGCVector3.Transform(p, movimientoFinal); //Devuelve un TGCVector4 poque estan las coordenadas homogeneas var transformedVec3 = new TGCVector3(transformedVec4.X, transformedVec4.Y, transformedVec4.Z); //Ignoramos la componente W // 7) Setear la matriz de World de DirectX D3DDevice.Instance.Device.Transform.World = movimientoFinal.ToMatrix(); // 8) Crear una matriz de View mirando hacia un determinado punto y aplicarla a DirectX var posicionCamara = new TGCVector3(20, 10, 0); var haciaDondeMiro = TGCVector3.Empty; var upVector = TGCVector3.Up; //Indica donde es arriba y donde abajo var viewMatrix = TGCMatrix.LookAtLH(posicionCamara, haciaDondeMiro, upVector); D3DDevice.Instance.Device.Transform.View = viewMatrix.ToMatrix(); // 9) Crear una matriz de proyeccion y aplicarla en DirectX var fieldOfViewY = FastMath.ToRad(45.0f); var aspectRatio = D3DDevice.Instance.AspectRatio; var zNearPlaneDistance = 1f; var zFarPlaneDistance = 10000f; var projection = TGCMatrix.PerspectiveFovLH(fieldOfViewY, aspectRatio, zNearPlaneDistance, zFarPlaneDistance); D3DDevice.Instance.Device.Transform.Projection = projection.ToMatrix(); // 10) Proyectar manualmente un punto 3D a la pantalla (lo que normalmente se hace dentro del vertex shader) var q = new TGCVector3(100, -15, 2); var worldViewProj = D3DDevice.Instance.Device.Transform.World * D3DDevice.Instance.Device.Transform.View * D3DDevice.Instance.Device.Transform.Projection; //Obtener la matriz final var projectedPoint = TGCVector3.Transform(q, TGCMatrix.FromMatrix(worldViewProj)); //Proyectar //Dividir por w projectedPoint.X /= projectedPoint.W; projectedPoint.Y /= projectedPoint.W; projectedPoint.Z /= projectedPoint.W; //La z solo es necesaria si queremos hacer Depth-testing //Pasarlo a screen-space var screenPoint = new Point( (int)(0.5f + (p.X + 1) * 0.5f * D3DDevice.Instance.Device.Viewport.Width), (int)(0.5f + (1 - p.Y) * 0.5f * D3DDevice.Instance.Device.Viewport.Height)); // 11) Con vertir de un punto 2D a uno 3D, al revez de lo que se hizo antes (normalmente para hacer picking con el mouse) var screenPoint2 = new Point(15, 100); //punto 2D de la pantalla var vAux = TGCVector3.Empty; vAux.X = (2.0f * screenPoint2.X / D3DDevice.Instance.Device.Viewport.Width - 1) / D3DDevice.Instance.Device.Transform.Projection.M11; vAux.Y = -(2.0f * screenPoint2.Y / D3DDevice.Instance.Device.Viewport.Height - 1) / D3DDevice.Instance.Device.Transform.Projection.M22; vAux.Z = 1.0f; var inverseView = TGCMatrix.Invert(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View)); //Invertir ViewMatrix var origin = new TGCVector3(inverseView.M41, inverseView.M42, inverseView.M43); var direction = new TGCVector3( vAux.X * inverseView.M11 + vAux.Y * inverseView.M21 + vAux.Z * inverseView.M31, vAux.X * inverseView.M12 + vAux.Y * inverseView.M22 + vAux.Z * inverseView.M32, vAux.X * inverseView.M13 + vAux.Y * inverseView.M23 + vAux.Z * inverseView.M33); //Con origin y direction formamos una recta que hay que buscar interseccion contra todos los objetos del escenario y quedarnos con la mas cercana a la camara }