public float4x4 Invert() { float fDet = Determinant(); if ( (float) System.Math.Abs(fDet) < float.Epsilon ) throw new MatrixException( "Matrix is not invertible!" ); // The matrix is not invertible! Singular case! float fIDet = 1.0f / fDet; float4x4 Temp = new float4x4(); Temp.m[0, 0] = CoFactor( 0, 0 ) * fIDet; Temp.m[1, 0] = CoFactor( 0, 1 ) * fIDet; Temp.m[2, 0] = CoFactor( 0, 2 ) * fIDet; Temp.m[3, 0] = CoFactor( 0, 3 ) * fIDet; Temp.m[0, 1] = CoFactor( 1, 0 ) * fIDet; Temp.m[1, 1] = CoFactor( 1, 1 ) * fIDet; Temp.m[2, 1] = CoFactor( 1, 2 ) * fIDet; Temp.m[3, 1] = CoFactor( 1, 3 ) * fIDet; Temp.m[0, 2] = CoFactor( 2, 0 ) * fIDet; Temp.m[1, 2] = CoFactor( 2, 1 ) * fIDet; Temp.m[2, 2] = CoFactor( 2, 2 ) * fIDet; Temp.m[3, 2] = CoFactor( 2, 3 ) * fIDet; Temp.m[0, 3] = CoFactor( 3, 0 ) * fIDet; Temp.m[1, 3] = CoFactor( 3, 1 ) * fIDet; Temp.m[2, 3] = CoFactor( 3, 2 ) * fIDet; Temp.m[3, 3] = CoFactor( 3, 3 ) * fIDet; Set( Temp ); return this; }
public void Set( float4x4 _Source ) { if ( _Source == null ) return; m[0, 0] = _Source.m[0, 0]; m[0, 1] = _Source.m[0, 1]; m[0, 2] = _Source.m[0, 2]; m[0, 3] = _Source.m[0, 3]; m[1, 0] = _Source.m[1, 0]; m[1, 1] = _Source.m[1, 1]; m[1, 2] = _Source.m[1, 2]; m[1, 3] = _Source.m[1, 3]; m[2, 0] = _Source.m[2, 0]; m[2, 1] = _Source.m[2, 1]; m[2, 2] = _Source.m[2, 2]; m[2, 3] = _Source.m[2, 3]; m[3, 0] = _Source.m[3, 0]; m[3, 1] = _Source.m[3, 1]; m[3, 2] = _Source.m[3, 2]; m[3, 3] = _Source.m[3, 3]; }
public static float4x4 Parse( string _Source ) { string[] Terms = _Source.Split( new char[] { ';' } ); if ( Terms.Length != 16 ) throw new Exception( "Source string must have 16 terms!" ); float4x4 Result = new float4x4(); Result.m[0,0] = float.Parse( Terms[4 * 0 + 0] ); Result.m[0,1] = float.Parse( Terms[4 * 0 + 1] ); Result.m[0,2] = float.Parse( Terms[4 * 0 + 2] ); Result.m[0,3] = float.Parse( Terms[4 * 0 + 3] ); Result.m[1,0] = float.Parse( Terms[4 * 1 + 0] ); Result.m[1,1] = float.Parse( Terms[4 * 1 + 1] ); Result.m[1,2] = float.Parse( Terms[4 * 1 + 2] ); Result.m[1,3] = float.Parse( Terms[4 * 1 + 3] ); Result.m[2,0] = float.Parse( Terms[4 * 2 + 0] ); Result.m[2,1] = float.Parse( Terms[4 * 2 + 1] ); Result.m[2,2] = float.Parse( Terms[4 * 2 + 2] ); Result.m[2,3] = float.Parse( Terms[4 * 2 + 3] ); Result.m[3,0] = float.Parse( Terms[4 * 3 + 0] ); Result.m[3,1] = float.Parse( Terms[4 * 3 + 1] ); Result.m[3,2] = float.Parse( Terms[4 * 3 + 2] ); Result.m[3,3] = float.Parse( Terms[4 * 3 + 3] ); return Result; }
// ToString/Parse methods for 4x3 matrices public static float4x4 Parse4x3( string _Source ) { string[] Terms = _Source.Split( ';' ); if ( Terms.Length != 12 ) throw new Exception( "Source string must have 12 terms!" ); float4x4 Result = new float4x4(); Result.m[0,0] = float.Parse( Terms[3 * 0 + 0] ); Result.m[0,1] = float.Parse( Terms[3 * 0 + 1] ); Result.m[0,2] = float.Parse( Terms[3 * 0 + 2] ); Result.m[0,3] = 0.0f; Result.m[1,0] = float.Parse( Terms[3 * 1 + 0] ); Result.m[1,1] = float.Parse( Terms[3 * 1 + 1] ); Result.m[1,2] = float.Parse( Terms[3 * 1 + 2] ); Result.m[1,3] = 0.0f; Result.m[2,0] = float.Parse( Terms[3 * 2 + 0] ); Result.m[2,1] = float.Parse( Terms[3 * 2 + 1] ); Result.m[2,2] = float.Parse( Terms[3 * 2 + 2] ); Result.m[2,3] = 0.0f; Result.m[3,0] = float.Parse( Terms[3 * 3 + 0] ); Result.m[3,1] = float.Parse( Terms[3 * 3 + 1] ); Result.m[3,2] = float.Parse( Terms[3 * 3 + 2] ); Result.m[3,3] = 1.0f; return Result; }
float4x4 ComputeCameraProjection() { float t = (float) (DateTime.Now - m_startTime).TotalSeconds; // Make a camera orbiting around the cube float T = t; float3 cameraPosition = 3.0f * new float3( (float) Math.Cos( T ), (float) Math.Cos( 3 * T ), (float) Math.Sin( T ) ); float3 cameraTarget = new float3( 0, 0, 0 ); float4x4 camera2World = new float4x4(); camera2World.BuildRotLeftHanded( cameraPosition, cameraTarget, float3.UnitY ); // Build the perspective projection matrix float4x4 camera2Proj = new float4x4(); camera2Proj.BuildProjectionPerspective( 80.0f * (float) Math.PI / 180.0f, (float) Width / Height, 0.01f, 100.0f ); // Compose the 2 matrices together to obtain the final matrix that transforms world coordinates into projected 2D coordinates return camera2World.Inverse * camera2Proj; }
/// <summary> /// Makes the camera look at the specified target from the specified eye position /// </summary> /// <param name="_Eye"></param> /// <param name="_Target"></param> /// <param name="_Up"></param> public void LookAt( float3 _Eye, float3 _Target, float3 _Up ) { float4x4 Temp = new float4x4(); Temp.BuildRotLeftHanded( _Eye, _Target, _Up ); this.Camera2World = Temp; }
public static float4x4 operator -( float4x4 _Op0, float4x4 _Op1 ) { float4x4 Ret = new float4x4(); Ret.m[0, 0] = _Op0.m[0, 0] - _Op1.m[0, 0]; Ret.m[0, 1] = _Op0.m[0, 1] - _Op1.m[0, 1]; Ret.m[0, 2] = _Op0.m[0, 2] - _Op1.m[0, 2]; Ret.m[0, 3] = _Op0.m[0, 3] - _Op1.m[0, 3]; Ret.m[1, 0] = _Op0.m[1, 0] - _Op1.m[1, 0]; Ret.m[1, 1] = _Op0.m[1, 1] - _Op1.m[1, 1]; Ret.m[1, 2] = _Op0.m[1, 2] - _Op1.m[1, 2]; Ret.m[1, 3] = _Op0.m[1, 3] - _Op1.m[1, 3]; Ret.m[2, 0] = _Op0.m[2, 0] - _Op1.m[2, 0]; Ret.m[2, 1] = _Op0.m[2, 1] - _Op1.m[2, 1]; Ret.m[2, 2] = _Op0.m[2, 2] - _Op1.m[2, 2]; Ret.m[2, 3] = _Op0.m[2, 3] - _Op1.m[2, 3]; Ret.m[3, 0] = _Op0.m[3, 0] - _Op1.m[3, 0]; Ret.m[3, 1] = _Op0.m[3, 1] - _Op1.m[3, 1]; Ret.m[3, 2] = _Op0.m[3, 2] - _Op1.m[3, 2]; Ret.m[3, 3] = _Op0.m[3, 3] - _Op1.m[3, 3]; return Ret; }
void Control_MouseMove( object sender, MouseEventArgs e ) { if ( EnableMouseAction != null && !EnableMouseAction( e ) ) return; // Don't do anything float4x4 CameraMatrixBeforeBaseCall = CameraTransform; // base.OnMouseMove( e ); m_Control.Focus(); float2 MousePos = ComputeNormalizedScreenPosition( e.X, e.Y, (float) m_Control.Width / m_Control.Height ); // Check for FIRST PERSON switch if ( m_bLastManipulationWasFirstPerson ^ FirstPersonKeyDown ) { // There was a switch so we need to copy the current matrix and make it look like the button was just pressed... Control_MouseDown( sender, e ); } m_bLastManipulationWasFirstPerson = FirstPersonKeyDown; if ( !FirstPersonKeyDown ) { ////////////////////////////////////////////////////////////////////////// // MAYA MANIPULATION MODE ////////////////////////////////////////////////////////////////////////// // switch ( m_ButtonsDown ) { // ROTATE case MouseButtons.Left: { if ( !m_bRotationEnabled ) break; // Rotation is disabled! float fAngleX = (MousePos.y - m_ButtonDownMousePosition.y) * 2.0f * (float) Math.PI * m_ManipulationRotationSpeed; float fAngleY = (MousePos.x - m_ButtonDownMousePosition.x) * 2.0f * (float) Math.PI * m_ManipulationRotationSpeed; float4 AxisX = m_ButtonDownTransform[0]; // float4x4 Rot = AngleAxis2Matrix( fAngleX, -new float3( AxisX.x, AxisX.y, AxisX.z ) ) // * AngleAxis2Matrix( fAngleY, new float3( 0f, -1.0f, 0.0f ) ); float4x4 Rot = new float4x4().BuildFromAngleAxis( fAngleX, -new float3( AxisX.x, AxisX.y, AxisX.z ) ) * new float4x4().BuildFromAngleAxis( fAngleY, new float3( 0f, -1.0f, 0.0f ) ); float4x4 Rotated = m_ButtonDownTransform * m_InvButtonDownTargetObjectMatrix * Rot * TargetObjectMatrix; CameraTransform = Rotated; break; } // DOLLY => Simply translate along the AT axis case MouseButtons.Right: case MouseButtons.Left | MouseButtons.Middle: { float fTrans = m_ButtonDownMousePosition.x - m_ButtonDownMousePosition.y - MousePos.x + MousePos.y; m_NormalizedTargetDistance = m_ButtonDownNormalizedTargetDistance + 4.0f * m_ManipulationZoomSpeed * fTrans; float fTargetDistance = Math.Sign( m_NormalizedTargetDistance ) * DeNormalizeTargetDistance( m_NormalizedTargetDistance ); if ( fTargetDistance > MIN_TARGET_DISTANCE ) { // Okay! We're far enough so we can reduce the distance anyway CameraTargetDistance = fTargetDistance; m_bPushingTarget = false; } else { // Too close! Let's move the camera forward and clamp the target distance... That will push the target along. m_CameraTargetDistance = MIN_TARGET_DISTANCE; m_NormalizedTargetDistance = NormalizeTargetDistance( m_CameraTargetDistance ); if ( !m_bPushingTarget ) { m_ButtonDownNormalizedTargetDistance = m_NormalizedTargetDistance; fTrans = 0.0f; m_bPushingTarget = true; } m_ButtonDownMousePosition = MousePos; float4x4 DollyCam = CameraTransform; DollyCam[3] = DollyCam[3] - 2.0f * m_ManipulationZoomSpeed * fTrans * DollyCam[2]; CameraTransform = DollyCam; } break; } // PAN case MouseButtons.Middle: { float2 Trans = new float2( -(MousePos.x - m_ButtonDownMousePosition.x), MousePos.y - m_ButtonDownMousePosition.y ); float fTransFactor = m_ManipulationPanSpeed * Math.Max( 2.0f, m_CameraTargetDistance ); // Make the camera pan float4x4 PanCam = m_ButtonDownTransform; PanCam[3] = m_ButtonDownTransform[3] - fTransFactor * Trans.x * m_ButtonDownTransform[0] - fTransFactor * Trans.y * m_ButtonDownTransform[1]; CameraTransform = PanCam; break; } } } else { ////////////////////////////////////////////////////////////////////////// // UNREAL MANIPULATION MODE ////////////////////////////////////////////////////////////////////////// // switch ( m_ButtonsDown ) { // TRANSLATE IN THE ZX PLANE (WORLD SPACE) case MouseButtons.Left : { float fTransFactor = m_ManipulationPanSpeed * System.Math.Max( 4.0f, CameraTargetDistance ); // Compute translation in the view direction float4 Trans = CameraMatrixBeforeBaseCall[2]; Trans.y = 0.0f; if ( Trans.LengthSquared < 1e-4f ) { // Better use Y instead... Trans = CameraMatrixBeforeBaseCall[1]; Trans.y = 0.0f; } Trans = Trans.Normalized; float4 NewPosition = CameraMatrixBeforeBaseCall[3] + Trans * fTransFactor * (MousePos.y - m_ButtonDownMousePosition.y); m_ButtonDownMousePosition.y = MousePos.y; // The translation is a cumulative operation... // Compute rotation about the the Y WORLD axis float fAngleY = (m_ButtonDownMousePosition.x - MousePos.x) * 2.0f * (float) Math.PI * m_ManipulationRotationSpeed * 0.2f; // [PATAPATCH] Multiplied by 0.2 as it's REALLY too sensitive otherwise! if ( m_ButtonDownTransform[1].y < 0.0f ) fAngleY = -fAngleY; // Special "head down" case... float4x4 RotY = new float4x4().BuildRotationY( fAngleY ); float4x4 FinalMatrix = m_ButtonDownTransform; FinalMatrix[3] = float4.Zero; // Clear translation... FinalMatrix = FinalMatrix * RotY; FinalMatrix[3] = NewPosition; CameraTransform = FinalMatrix; break; } // ROTATE ABOUT CAMERA case MouseButtons.Right : { float fAngleY = (m_ButtonDownMousePosition.x - MousePos.x) * 2.0f * (float) Math.PI * m_ManipulationRotationSpeed; float fAngleX = (m_ButtonDownMousePosition.y - MousePos.y) * 2.0f * (float) Math.PI * m_ManipulationRotationSpeed; float3 Euler = GetEuler( m_ButtonDownTransform ); float4x4 CamRotYMatrix = new float4x4().BuildRotationY( fAngleY + Euler.y ); float4x4 CamRotXMatrix = new float4x4().BuildRotationX( fAngleX + Euler.x ); float4x4 CamRotZMatrix = new float4x4().BuildRotationZ( Euler.z ); float4x4 RotateMatrix = CamRotXMatrix * CamRotYMatrix * CamRotZMatrix; RotateMatrix[3] = CameraTransform[3]; CameraTransform = RotateMatrix; break; } // Translate in the ( Z-world Y-camera ) plane case MouseButtons.Middle : case MouseButtons.Left | MouseButtons.Right: { float fTransFactor = m_ManipulationPanSpeed * System.Math.Max( 4.0f, CameraTargetDistance ); float4 NewPosition = m_ButtonDownTransform[3] + fTransFactor * ( (MousePos.y - m_ButtonDownMousePosition.y) * float4.UnitY + (m_ButtonDownMousePosition.x - MousePos.x) * m_ButtonDownTransform[0] ); float4x4 NewMatrix = m_ButtonDownTransform; NewMatrix[3] = NewPosition ; CameraTransform = NewMatrix; break; } } } }
// Transforms the box by the given matrix and returns 8 points corresponding to the eight transformed corners public float3[] Transform( float4x4 _Transform ) { float3[] Corners = new float3[8] { new float3( 0, 0, 0 ), new float3( 1, 0, 0 ), new float3( 1, 1, 0 ), new float3( 0, 1, 0 ), new float3( 0, 0, 1 ), new float3( 1, 0, 1 ), new float3( 1, 1, 1 ), new float3( 0, 1, 1 ), }; float3 D = Dim; float3[] Result = new float3[8]; for ( int CornerIndex=0; CornerIndex < 8; CornerIndex++ ) Result[CornerIndex] = (float3) (new float4( m_Min + Corners[CornerIndex] * D, 1.0f ) * _Transform); return Result; }
public static float4x4 operator *( float _s, float4x4 _Op0 ) { float4x4 Ret = new float4x4(); Ret.m[0, 0] = _Op0.m[0, 0] * _s; Ret.m[0, 1] = _Op0.m[0, 1] * _s; Ret.m[0, 2] = _Op0.m[0, 2] * _s; Ret.m[0, 3] = _Op0.m[0, 3] * _s; Ret.m[1, 0] = _Op0.m[1, 0] * _s; Ret.m[1, 1] = _Op0.m[1, 1] * _s; Ret.m[1, 2] = _Op0.m[1, 2] * _s; Ret.m[1, 3] = _Op0.m[1, 3] * _s; Ret.m[2, 0] = _Op0.m[2, 0] * _s; Ret.m[2, 1] = _Op0.m[2, 1] * _s; Ret.m[2, 2] = _Op0.m[2, 2] * _s; Ret.m[2, 3] = _Op0.m[2, 3] * _s; Ret.m[3, 0] = _Op0.m[3, 0] * _s; Ret.m[3, 1] = _Op0.m[3, 1] * _s; Ret.m[3, 2] = _Op0.m[3, 2] * _s; Ret.m[3, 3] = _Op0.m[3, 3] * _s; return Ret; }
// Grows the current bbox using another transformed bbox public void Grow( BoundingBox _BBox, float4x4 _Transform ) { float3[] Corners = _BBox.Transform( _Transform ); for ( int CornerIndex=0; CornerIndex < 8; CornerIndex++ ) Grow( Corners[CornerIndex] ); }
void Application_Idle( object sender, EventArgs e ) { if ( m_Device == null ) return; // Setup global data m_CB_Main.m.iResolution = new float3( panelOutput.Width, panelOutput.Height, 0 ); if ( checkBoxAnimate.Checked ) m_CB_Main.m.iGlobalTime = GetGameTime() - m_StartTime; m_CB_Main.UpdateData(); // Setup area light buffer float LighOffsetX = 1.2f; float SizeX = floatTrackbarControlLightScaleX.Value; float SizeY = 1.0f; float RollAngle = (float) (Math.PI * floatTrackbarControlLightRoll.Value / 180.0); float3 LightPosition = new float3( LighOffsetX + floatTrackbarControlLightPosX.Value, 1.0f + floatTrackbarControlLightPosY.Value, -1.0f + floatTrackbarControlLightPosZ.Value ); float3 LightTarget = new float3( LightPosition.x + floatTrackbarControlLightTargetX.Value, LightPosition.y + floatTrackbarControlLightTargetY.Value, LightPosition.z + 2.0f + floatTrackbarControlLightTargetZ.Value ); float3 LightUp = new float3( (float) Math.Sin( -RollAngle ), (float) Math.Cos( RollAngle ), 0.0f ); float4x4 AreaLight2World = new float4x4(); AreaLight2World.BuildRotRightHanded( LightPosition, LightTarget, LightUp ); float4x4 World2AreaLight = AreaLight2World.Inverse; double Phi = Math.PI * floatTrackbarControlProjectionPhi.Value / 180.0; double Theta = Math.PI * floatTrackbarControlProjectionTheta.Value / 180.0; float3 Direction = new float3( (float) (Math.Sin(Theta) * Math.Sin(Phi)), (float) (Math.Sin(Theta) * Math.Cos(Phi)), (float) Math.Cos( Theta ) ); const float DiffusionMin = 1e-2f; const float DiffusionMax = 1000.0f; // float Diffusion_Diffuse = DiffusionMin / (DiffusionMin / DiffusionMax + floatTrackbarControlProjectionDiffusion.Value); float Diffusion_Diffuse = DiffusionMax + (DiffusionMin - DiffusionMax) * (float) Math.Pow( floatTrackbarControlProjectionDiffusion.Value, 0.01f ); // float3 LocalDirection_Diffuse = (float3) (new float4( Diffusion_Diffuse * Direction, 0 ) * World2AreaLight); float3 LocalDirection_Diffuse = Diffusion_Diffuse * Direction; m_CB_Light.m._AreaLightX = (float3) AreaLight2World[0]; m_CB_Light.m._AreaLightY = (float3) AreaLight2World[1]; m_CB_Light.m._AreaLightZ = (float3) AreaLight2World[2]; m_CB_Light.m._AreaLightT = (float3) AreaLight2World[3]; m_CB_Light.m._AreaLightScaleX = SizeX; m_CB_Light.m._AreaLightScaleY = SizeY; m_CB_Light.m._AreaLightDiffusion = floatTrackbarControlProjectionDiffusion.Value; m_CB_Light.m._AreaLightIntensity = floatTrackbarControlLightIntensity.Value; m_CB_Light.m._AreaLightTexDimensions = new float4( m_Tex_AreaLightSAT.Width, m_Tex_AreaLightSAT.Height, 1.0f / m_Tex_AreaLightSAT.Width, 1.0f / m_Tex_AreaLightSAT.Height ); m_CB_Light.m._ProjectionDirectionDiff = LocalDirection_Diffuse; m_CB_Light.UpdateData(); // =========== Render shadow map =========== // float KernelSize = 16.0f * floatTrackbarControlProjectionDiffusion.Value; float KernelSize = floatTrackbarControlKernelSize.Value; // float ShadowZFar = (float) Math.Sqrt( 2.0 ) * m_Camera.Far; float ShadowZFar = 10.0f; m_CB_ShadowMap.m._ShadowOffsetXY = (float2) Direction; m_CB_ShadowMap.m._ShadowZFar = new float2( ShadowZFar, 1.0f / ShadowZFar ); m_CB_ShadowMap.m._KernelSize = KernelSize; m_CB_ShadowMap.m._InvShadowMapSize = 1.0f / m_Tex_ShadowMap.Width; m_CB_ShadowMap.m._HardeningFactor = new float2( floatTrackbarControlHardeningFactor.Value, floatTrackbarControlHardeningFactor2.Value ); m_CB_ShadowMap.UpdateData(); if ( m_Shader_RenderShadowMap != null && m_Shader_RenderShadowMap.Use() ) { m_Tex_ShadowMap.RemoveFromLastAssignedSlots(); m_Device.SetRenderTargets( m_Tex_ShadowMap.Width, m_Tex_ShadowMap.Height, new View2D[0], m_Tex_ShadowMap ); #if FILTER_EXP_SHADOW_MAP // m_Device.ClearDepthStencil( m_Tex_ShadowMap, 0.0f, 0, true, false ); // m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_GREATER, BLEND_STATE.DISABLED ); // For exp shadow map, the Z order is reversed m_Device.ClearDepthStencil( m_Tex_ShadowMap, 1.0f, 0, true, false ); m_Device.SetRenderStates( checkBoxCullFront.Checked ? RASTERIZER_STATE.CULL_BACK : RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_LESS, BLEND_STATE.DISABLED ); // For exp shadow map, the Z order is reversed #else m_Device.ClearDepthStencil( m_Tex_ShadowMap, 1.0f, 0, true, false ); m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_LESS, BLEND_STATE.DISABLED ); #endif RenderScene( m_Shader_RenderShadowMap ); m_Device.RemoveRenderTargets(); m_Tex_ShadowMap.SetPS( 2 ); } #if FILTER_EXP_SHADOW_MAP if ( m_Shader_FilterShadowMapH != null ) { // m_Tex_ShadowMapFiltered[1].RemoveFromLastAssignedSlots(); m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.DISABLED, BLEND_STATE.DISABLED ); // Filter horizontally m_Device.SetRenderTarget( m_Tex_ShadowMapFiltered[0], null ); m_Shader_FilterShadowMapH.Use(); m_Prim_Quad.Render( m_Shader_FilterShadowMapH ); // Filter vertically m_Device.SetRenderTarget( m_Tex_ShadowMapFiltered[1], null ); m_Tex_ShadowMapFiltered[0].SetPS( 2 ); m_Shader_FilterShadowMapV.Use(); m_Prim_Quad.Render( m_Shader_FilterShadowMapV ); m_Device.RemoveRenderTargets(); m_Tex_ShadowMapFiltered[1].SetPS( 2 ); } #else if ( m_Shader_BuildSmoothie != null && m_Shader_BuildSmoothie.Use() ) { m_Tex_ShadowSmoothie.RemoveFromLastAssignedSlots(); m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.DISABLED, BLEND_STATE.DISABLED ); // Render the (silhouette + Z) RG16 buffer m_Device.SetRenderTarget( m_Tex_ShadowSmoothie, null ); m_Prim_Quad.Render( m_Shader_BuildSmoothie ); m_Device.RemoveRenderTargets(); m_Tex_ShadowSmoothie.SetPS( 3 ); // Build distance field m_Device.SetRenderTarget( m_Tex_ShadowSmoothiePou[0], null ); m_Shader_BuildSmoothieDistanceFieldH.Use(); m_Prim_Quad.Render( m_Shader_BuildSmoothieDistanceFieldH ); // m_Device.RemoveRenderTargets(); // m_Tex_ShadowSmoothiePou[0].SetPS( 3 ); m_Device.SetRenderTarget( m_Tex_ShadowSmoothiePou[1], null ); m_Tex_ShadowSmoothiePou[0].SetPS( 0 ); m_Shader_BuildSmoothieDistanceFieldV.Use(); m_Prim_Quad.Render( m_Shader_BuildSmoothieDistanceFieldV ); m_Device.RemoveRenderTargets(); m_Tex_ShadowSmoothiePou[1].SetPS( 3 ); } #endif // =========== Render scene =========== m_Device.SetRenderTarget( m_Device.DefaultTarget, m_Device.DefaultDepthStencil ); m_Device.Clear( m_Device.DefaultTarget, float4.Zero ); m_Device.ClearDepthStencil( m_Device.DefaultDepthStencil, 1.0f, 0, true, false ); m_Tex_AreaLightSAT.SetPS( 0 ); // m_Tex_AreaLight3D.SetPS( 0 ); m_Tex_AreaLightSATFade.SetPS( 1 ); m_Tex_AreaLight.SetPS( 4 ); m_Tex_FalseColors.SetPS( 6 ); // m_Tex_GlossMap.SetPS( 7 ); // m_Tex_Normal.SetPS( 8 ); // Render the area light itself m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_LESS, BLEND_STATE.DISABLED ); if ( m_Shader_RenderAreaLight != null && m_Shader_RenderAreaLight.Use() ) { m_CB_Object.m._Local2World = AreaLight2World; m_CB_Object.m._Local2World.Scale( new float3( SizeX, SizeY, 1.0f ) ); m_CB_Object.m._World2Local = m_CB_Object.m._Local2World.Inverse; m_CB_Object.m._UseTexture = checkBoxUseTexture.Checked ? 1U : 0U; m_CB_Object.m._FalseColors = checkBoxFalseColors.Checked ? 1U : 0U; m_CB_Object.m._FalseColorsMaxRange = floatTrackbarControlFalseColorsRange.Value; m_CB_Object.UpdateData(); m_Prim_Rectangle.Render( m_Shader_RenderAreaLight ); } else { m_Device.Clear( new float4( 1, 0, 0, 0 ) ); } // Render the scene m_Device.SetRenderStates( RASTERIZER_STATE.CULL_BACK, DEPTHSTENCIL_STATE.NOCHANGE, BLEND_STATE.NOCHANGE ); if ( m_Shader_RenderScene != null && m_Shader_RenderScene.Use() ) { RenderScene( m_Shader_RenderScene ); } else { m_Device.Clear( new float4( 1, 1, 0, 0 ) ); } // Show! m_Device.Present( false ); // Update window text // Text = "Zombizous Prototype - " + m_Game.m_CurrentGameTime.ToString( "G5" ) + "s"; }
public float3x3(float4x4 _Source) { Set(_Source); }
// /// <summary> // /// Converts an angle+axis into a plain rotation matrix // /// </summary> // /// <param name="_Angle"></param> // /// <param name="_Axis"></param> // /// <returns></returns> // protected float4x4 AngleAxis2Matrix( float _Angle, float3 _Axis ) { // // Convert into a quaternion // float3 qv = (float) System.Math.Sin( .5f * _Angle ) * _Axis; // float qs = (float) System.Math.Cos( .5f * _Angle ); // // // Then into a matrix // float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; // // // Quat q = new Quat( _Source ); // // q.Normalize(); // A cast to a matrix only works with normalized quaternions! // // xs = 2.0f * qv.x; ys = 2.0f * qv.y; zs = 2.0f * qv.z; // // wx = qs * xs; wy = qs * ys; wz = qs * zs; // xx = qv.x * xs; xy = qv.x * ys; xz = qv.x * zs; // yy = qv.y * ys; yz = qv.y * zs; zz = qv.z * zs; // // float4x4 Ret = float4x4.Identity; // // Ret.r[0].x = 1.0f - yy - zz; // Ret.r[0].y = xy + wz; // Ret.r[0].z = xz - wy; // // Ret.r[1].x = xy - wz; // Ret.r[1].y = 1.0f - xx - zz; // Ret.r[1].z = yz + wx; // // Ret.r[2].x = xz + wy; // Ret.r[2].y = yz - wx; // Ret.r[2].z = 1.0f - xx - yy; // // return Ret; // } /// <summary> /// Extracts Euler angles from a rotation matrix /// </summary> /// <param name="_Matrix"></param> /// <returns></returns> protected float3 GetEuler( float4x4 _Matrix ) { float3 Ret = new float3(); float fSinY = Math.Min( +1.0f, Math.Max( -1.0f, _Matrix[0].z ) ), fCosY = (float) Math.Sqrt( 1.0f - fSinY*fSinY ); if ( _Matrix[0].x < 0.0 && _Matrix[2].z < 0.0 ) fCosY = -fCosY; if ( (float) Math.Abs( fCosY ) > float.Epsilon ) { Ret.x = (float) Math.Atan2( _Matrix[1].z / fCosY, _Matrix[2].z / fCosY ); Ret.y = (float) -Math.Atan2( fSinY, fCosY ); Ret.z = (float) Math.Atan2( _Matrix[0].y / fCosY, _Matrix[0].x / fCosY ); } else { Ret.x = (float) Math.Atan2( -_Matrix[2].y, _Matrix[1].y ); Ret.y = (float) -Math.Asin( fSinY ); Ret.z = 0.0f; } return Ret; }
public static float4x4 operator /( float4x4 _Op0, float _s ) { float Is = 1.0f / _s; float4x4 Ret = new float4x4(); Ret.m[0, 0] = _Op0.m[0, 0] * Is; Ret.m[0, 1] = _Op0.m[0, 1] * Is; Ret.m[0, 2] = _Op0.m[0, 2] * Is; Ret.m[0, 3] = _Op0.m[0, 3] * Is; Ret.m[1, 0] = _Op0.m[1, 0] * Is; Ret.m[1, 1] = _Op0.m[1, 1] * Is; Ret.m[1, 2] = _Op0.m[1, 2] * Is; Ret.m[1, 3] = _Op0.m[1, 3] * Is; Ret.m[2, 0] = _Op0.m[2, 0] * Is; Ret.m[2, 1] = _Op0.m[2, 1] * Is; Ret.m[2, 2] = _Op0.m[2, 2] * Is; Ret.m[2, 3] = _Op0.m[2, 3] * Is; Ret.m[3, 0] = _Op0.m[3, 0] * Is; Ret.m[3, 1] = _Op0.m[3, 1] * Is; Ret.m[3, 2] = _Op0.m[3, 2] * Is; Ret.m[3, 3] = _Op0.m[3, 3] * Is; return Ret; }
void Control_MouseDown( object sender, MouseEventArgs e ) { if ( EnableMouseAction != null && !EnableMouseAction( e ) ) return; // Don't do anything m_ButtonsDown |= e.Button; // Add this button // Keep a track of the mouse and camera states when button was pressed m_ButtonDownTransform = CameraTransform; m_ButtonDownTargetObjectMatrix = TargetObjectMatrix; m_InvButtonDownTargetObjectMatrix = m_ButtonDownTargetObjectMatrix.Inverse; m_ButtonDownMousePosition = ComputeNormalizedScreenPosition( e.X, e.Y, (float) m_Control.Width / m_Control.Height ); m_ButtonDownCameraTargetDistance = CameraTargetDistance; m_ButtonDownNormalizedTargetDistance = NormalizeTargetDistance( m_ButtonDownCameraTargetDistance ); }
/// <summary> /// Computes the rotation matrix to transform a source vector into a target vector /// (routine from Thomas Moller) /// </summary> /// <param name="_Source">The source vector</param> /// <param name="_Target">The target vector</param> /// <returns>The rotation matrix to apply that will transform</returns> public static float4x4 ComputeRotationMatrix( float3 _Source, float3 _Target ) { SharpMath.float4x4 Result = new float4x4(); Result.MakeIdentity(); float e = _Source | _Target; bool bReverse = e < 0.0f; if ( bReverse ) { // Revert target _Target = -_Target; e = -e; } if ( e > 1.0f - 0.000001f ) { if ( bReverse ) { // Reverse final matrix Result.SetRow0( -Result.GetRow0() ); Result.SetRow1( -Result.GetRow1() ); Result.SetRow2( -Result.GetRow2() ); } return Result; // No rotation needed... } float3 Ortho = _Source ^ _Target; float h = 1.0f / (1.0f + e); // Optimization by Gottfried Chen Result.SetRow0( new float3( e + h * Ortho.x * Ortho.x, h * Ortho.x * Ortho.y + Ortho.z, h * Ortho.x * Ortho.z - Ortho.y ) ); Result.SetRow1( new float3( h * Ortho.x * Ortho.y - Ortho.z, e + h * Ortho.y * Ortho.y, h * Ortho.y * Ortho.z + Ortho.x ) ); Result.SetRow2( new float3( h * Ortho.x * Ortho.z + Ortho.y, h * Ortho.y * Ortho.z - Ortho.x, e + h * Ortho.z * Ortho.z ) ); if ( bReverse ) { // Reverse final matrix Result.SetRow0( -Result.GetRow0() ); Result.SetRow1( -Result.GetRow1() ); Result.SetRow2( -Result.GetRow2() ); } return Result; }
void Control_MouseUp( object sender, MouseEventArgs e ) { m_ButtonsDown = MouseButtons.None; // Remove all buttons // Update the mouse and camera states when button is released m_ButtonDownTransform = CameraTransform; m_ButtonDownTargetObjectMatrix = TargetObjectMatrix; m_ButtonDownMousePosition = ComputeNormalizedScreenPosition( e.X, e.Y, (float) m_Control.Width / m_Control.Height ); m_ButtonDownCameraTargetDistance = CameraTargetDistance; m_ButtonDownNormalizedTargetDistance = NormalizeTargetDistance( m_ButtonDownCameraTargetDistance ); }
public float4x4( float4x4 _Source ) { Set( _Source ); }
static void TestFloat4x4() { if ( System.Runtime.InteropServices.Marshal.SizeOf(typeof(float4x4)) != 64 ) throw new Exception( "Not the appropriate size!" ); float4x4 test1 = new float4x4( new float[16] { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 } ); float4x4 test2 = new float4x4( new float4( 1, 0, 0, 0 ), new float4( 0, 1, 0, 0 ), new float4( 0, 0, 1, 0 ), new float4( 0, 0, 0, 1 ) ); float4x4 test3 = new float4x4( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ); float4x4 test0; test0 = test3; test2.Scale( new float3( 2, 2, 2 ) ); float3x3 cast = (float3x3) test3; float4x4 mul0 = test1 * test2; float4x4 mul1 = 3.0f * test2; float4 mul2 = new float4( 1, 1, 1, 1 ) * test3; float4 access0 = test3[2]; test3[1] = new float4( 12, 13, 14, 15 ); float access1 = test3[1,2]; test3[1,2] = 18; float coFactor = test3.CoFactor( 0, 2 ); float det = test3.Determinant; float4x4 inv = test2.Inverse; float4x4 id = float4x4.Identity; test3.BuildRotLeftHanded( float3.UnitZ, float3.Zero, float3.UnitY ); test3.BuildRotRightHanded( float3.UnitZ, float3.Zero, float3.UnitY ); test3.BuildProjectionPerspective( 1.2f, 2.0f, 0.01f, 10.0f ); test3.BuildRotationX( 0.5f ); test3.BuildRotationY( 0.5f ); test3.BuildRotationZ( 0.5f ); test3.BuildFromAngleAxis( 0.5f, float3.UnitY ); }
/// <summary> /// Creates a perspective projection float4x4 for the camera /// </summary> /// <param name="_FOV"></param> /// <param name="_AspectRatio"></param> /// <param name="_Near"></param> /// <param name="_Far"></param> public void CreatePerspectiveCamera( float _FOV, float _AspectRatio, float _Near, float _Far ) { m_Near = _Near; m_Far = _Far; m_AspectRatio = _AspectRatio; m_PerspFOV = _FOV; float4x4 Temp = new float4x4(); Temp.BuildProjectionPerspective( _FOV, _AspectRatio, _Near, _Far ); this.Camera2Proj = Temp; m_bIsPerspective = true; // Build camera data m_CachedCameraData.x = (float) Math.Tan( 0.5 * m_PerspFOV ); m_CachedCameraData.y = m_AspectRatio; m_CachedCameraData.z = m_Near; m_CachedCameraData.w = m_Far; }