public void TestMat() { var mat1 = Mat.RotationX<Mat4> (30); var mat2 = Mat.RotationY<Mat4> (40); var mat3 = Mat.RotationZ<Mat4> (50); var mat4 = Mat.Scaling<Mat4> (100, 100, 100); var mat5 = Mat.Translation<Mat4> (1000, 1000, 1000); Mat4 res = new Mat4 (); for (int i = 0; i < 1000000; i++) { res = mat1 * mat2 * mat3 * mat4 * mat5; } Console.WriteLine (res); }
public MainCamera() { Near = 1f; Far = 500f; Model = Mat4.Translate(0,0,0); Target = Vect3.Zero; Up = Vect3.UnitY; Eye = new Vect3(0,0,20); _view =Mat4.LookAt(Eye, Target, Up); // _view = Mat4.RotateX(Angle.FromRadians(Math.Atan(Math.Sin(Angle.FromDegrees(-45))))) * (Mat4.LookAt(Eye, Target, Up) * Mat4.RotateZ(Angle.FromDegrees(45))); //_view = Mat4.Identity; }
void workAreaControl_Render( MultiViewRenderTargetControl sender, int viewIndex, Camera camera ) { //update camera if( Map.Instance != null ) { Vec3 position; Vec3 forward; Vec3 up; Degree fov; if( !freeCameraEnabled ) { //usual camera mode //add here your special camera management code and set "freeCameraEnabled = false;" position = Vec3.Zero; forward = new Vec3( 1, 0, 0 ); up = Vec3.ZAxis; fov = Map.Instance.Fov; //MapCamera mapCamera = Entities.Instance.GetByName( "MapCamera_0" ) as MapCamera; //if( mapCamera != null ) //{ // position = mapCamera.Position; // forward = mapCamera.Rotation * new Vec3( 1, 0, 0 ); // fov = mapCamera.Fov; //} } else { //free camera mode position = freeCameraPosition; forward = freeCameraDirection.GetVector(); up = Vec3.ZAxis; fov = Map.Instance.Fov; } //update control RenderTargetUserControl control = workAreaControl.Views[ viewIndex ].Control; if( viewIndex == 0 ) { //first view control.CameraNearFarClipDistance = Map.Instance.NearFarClipDistance; control.CameraFixedUp = up; control.CameraFov = fov; control.CameraPosition = position; control.CameraDirection = forward; } else { //all views except first view. set orthographic camera projection. control.CameraNearFarClipDistance = Map.Instance.NearFarClipDistance; control.CameraProjectionType = ProjectionTypes.Orthographic; control.CameraOrthoWindowHeight = 30; Vec3 lookAt = position; switch( viewIndex ) { case 1: control.CameraFixedUp = Vec3.ZAxis; control.CameraDirection = -Vec3.XAxis; control.CameraPosition = lookAt - control.CameraDirection * 100; break; case 2: control.CameraFixedUp = Vec3.ZAxis; control.CameraDirection = -Vec3.YAxis; control.CameraPosition = lookAt - control.CameraDirection * 100; break; case 3: control.CameraFixedUp = Vec3.YAxis; control.CameraDirection = -Vec3.ZAxis; control.CameraPosition = lookAt - control.CameraDirection * 100; break; } } } //update sound listener if( viewIndex == 0 && SoundWorld.Instance != null ) SoundWorld.Instance.SetListener( camera.Position, Vec3.Zero, camera.Direction, camera.Up ); //draw 2D graphics as 3D by means DebugGeometry if( workAreaViewsConfiguration == ViewsConfigurations.FourViews && viewIndex == 3 ) { const float cameraOffset = 10; Vec3 center = camera.Position + camera.Direction * cameraOffset; //draw box Vec3[] positions; int[] indices; GeometryGenerator.GenerateBox( new Vec3( 10, 4, 1 ), out positions, out indices ); Mat4 transform = new Mat4( Mat3.Identity, center ); camera.DebugGeometry.Color = new ColorValue( .5f, 0, 0 ); camera.DebugGeometry.AddVertexIndexBuffer( positions, indices, transform, false, true ); camera.DebugGeometry.Color = new ColorValue( 1, 1, 0 ); camera.DebugGeometry.AddVertexIndexBuffer( positions, indices, transform, true, true ); //draw axes camera.DebugGeometry.Color = new ColorValue( 1, 0, 0 ); camera.DebugGeometry.AddArrow( center, center + new Vec3( 5, 0, 0 ) ); camera.DebugGeometry.Color = new ColorValue( 0, 1, 0 ); camera.DebugGeometry.AddArrow( center, center + new Vec3( 0, 5, 0 ) ); camera.DebugGeometry.Color = new ColorValue( 0, 0, 1 ); camera.DebugGeometry.AddArrow( center, center + new Vec3( 0, 0, 5 ) ); } }
private void UpdateTransform() { var attachedToRoot = Graph.Root == Root; if (attachedToRoot) foreach (var node in Traverse ()) node.RemoveFromIndex (); _transform = Mat.Translation<Mat4> (Offset.X, Offset.Y, Offset.Z) * Mat.Scaling<Mat4> (Scale.X, Scale.Y, Scale.Z) * Mat.RotationZ<Mat4> (Orientation.Z) * Mat.RotationY<Mat4> (Orientation.Y) * Mat.RotationX<Mat4> (Orientation.X); if (attachedToRoot) foreach (var node in Traverse ()) node.AddToIndex (); }
public void DebugDrawNavMesh( Camera camera ) { if( recastWorld == IntPtr.Zero ) return; if( debugNavigationMeshVertices == null ) { if( !GetDebugNavigationMeshGeometry( out debugNavigationMeshVertices ) ) return; debugNavigationMeshIndices = new int[ debugNavigationMeshVertices.Length ]; for( int n = 0; n < debugNavigationMeshIndices.Length; n++ ) debugNavigationMeshIndices[ n ] = n; } //Render NavMesh { Mat4 transform = new Mat4( Mat3.Identity, new Vec3( 0, 0, .1f ) ); //draw without depth test { camera.DebugGeometry.SetSpecialDepthSettings( false, false ); camera.DebugGeometry.Color = new ColorValue( 0, 1, 0, .1f ); camera.DebugGeometry.AddVertexIndexBuffer( debugNavigationMeshVertices, debugNavigationMeshIndices, transform, false, true ); camera.DebugGeometry.Color = new ColorValue( 1, 1, 0, .1f ); camera.DebugGeometry.AddVertexIndexBuffer( debugNavigationMeshVertices, debugNavigationMeshIndices, transform, true, true ); camera.DebugGeometry.RestoreDefaultDepthSettings(); } //draw with depth test { camera.DebugGeometry.Color = new ColorValue( 0, 1, 0, .3f ); camera.DebugGeometry.AddVertexIndexBuffer( debugNavigationMeshVertices, debugNavigationMeshIndices, transform, false, true ); camera.DebugGeometry.Color = new ColorValue( 1, 1, 0, .3f ); camera.DebugGeometry.AddVertexIndexBuffer( debugNavigationMeshVertices, debugNavigationMeshIndices, transform, true, true ); } } }
//IndexVertexBufferCollector GetGeometriesForNavigationMesh( Bounds bounds ) //{ // IndexVertexBufferCollector collector = new IndexVertexBufferCollector(); // странный способ // Map.Instance.GetObjects( new Box( bounds ), delegate( MapObject obj ) // { // if( geometries.Contains( obj ) ) // AddEntityToCollector( collector, obj ); // } ); // //heightmapterrain is not added in volume selections, this is actually good thing because now we can only add the required part // { // //raycast does not hit terrain?!? // /* // Vec3 top = bounds.GetCenter(); // top.Z = boundsMax.Z; // Vec3 bottom = bounds.GetCenter(); // bottom.Z = boundsMin.Z; // RayCastResult[] results = PhysicsWorld.Instance.RayCastPiercing(new Ray(top, bottom), (int)ContactGroup.CastOnlyCollision); // foreach (RayCastResult result in results) // { // HeightmapTerrain terrain = HeightmapTerrain.GetTerrainByBody( result.Shape.Body ); // if( terrain != null) // if( geometries.Contains(terrain) ) // AddHeightmapTerrainPartToCollector(collector, terrain, bounds); // } // */ // //SodanKerjuu: Lo-Tek style, better hope you don't have more than one terrain // foreach( HeightmapTerrain terrain in HeightmapTerrain.Instances ) // if( geometries.Contains( terrain ) ) // AddHeightmapTerrainPartToCollector( collector, terrain, bounds ); // } // return collector; //} //void AddHeightmapTerrainPartToCollector( IndexVertexBufferCollector collector, HeightmapTerrain terrain, Bounds bounds ) //{ // int size = terrain.GetHeightmapSizeAsInteger(); // Vec3[] vertices = new Vec3[ ( size + 1 ) * ( size + 1 ) ]; // int[] indices = new int[ size * size * 6 ]; // int vertexPosition = 0; // int indexPosition = 0; // for( int y = 0; y < size + 1; y++ ) // { // for( int x = 0; x < size + 1; x++ ) // { // если очень большое число дыр, то будет излишне? // //SodanKerjuu: no need, you will have unused vertices, but they won't matter for Recast if they are not indexed // //if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) // //{ // Vec2 pos2 = terrain.GetPositionXY( new Vec2i( x, y ) ); // Vec3 pos = new Vec3( pos2.X, pos2.Y, terrain.GetHeight( new Vec2i( x, y ) ) ); // vertices[ vertexPosition ] = pos; // vertexPosition++; // //} // } // } // for( int y = 0; y < size; y++ ) // { // for( int x = 0; x < size; x++ ) // { // if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) // { // indices[ indexPosition + 0 ] = ( size + 1 ) * y + x; // indices[ indexPosition + 1 ] = ( size + 1 ) * y + x + 1; // indices[ indexPosition + 2 ] = ( size + 1 ) * ( y + 1 ) + x + 1; // indices[ indexPosition + 3 ] = ( size + 1 ) * ( y + 1 ) + x + 1; // indices[ indexPosition + 4 ] = ( size + 1 ) * ( y + 1 ) + x; // indices[ indexPosition + 5 ] = ( size + 1 ) * y + x; // indexPosition += 6; // } // } // } // collector.Add( vertices, vertexPosition, indices, indexPosition ); //} bool AddEntityToCollector( IndexVertexBufferCollector collector, Entity entity ) { //Static meshes StaticMesh staticMesh = entity as StaticMesh; if( staticMesh != null ) { if( staticMesh.Collision == false ) return false; Mesh mesh; if( !string.IsNullOrEmpty( staticMesh.CollisionSpecialMeshName ) ) mesh = MeshManager.Instance.Load( staticMesh.CollisionSpecialMeshName ); else mesh = MeshManager.Instance.Load( staticMesh.MeshName ); if( mesh == null ) return false; Mat4 transform = staticMesh.GetTransform(); foreach( SubMesh subMesh in mesh.SubMeshes ) { if( subMesh.AllowCollision ) { Vec3[] vertices; int[] indices; subMesh.GetSomeGeometry( out vertices, out indices ); if( vertices != null ) { for( int n = 0; n < vertices.Length; n++ ) vertices[ n ] = transform * vertices[ n ]; collector.Add( vertices, vertices.Length, indices, indices.Length ); } } } return true; } //MapObjectAttachedMesh MapObject mapObject = entity as MapObject; if( mapObject != null && !( entity is StaticMesh ) ) //SodanKerjuu: static meshes qualify as both { bool added = false; foreach( MapObjectAttachedObject attachedObject in mapObject.AttachedObjects ) { MapObjectAttachedMesh attachedMesh = attachedObject as MapObjectAttachedMesh; if( attachedMesh != null && attachedMesh.Collision ) { Mesh mesh; if( !string.IsNullOrEmpty( attachedMesh.CollisionSpecialMeshName ) ) mesh = MeshManager.Instance.Load( attachedMesh.CollisionSpecialMeshName ); else mesh = MeshManager.Instance.Load( attachedMesh.MeshName ); if( mesh != null ) { Vec3 pos; Quat rot; Vec3 scl; attachedMesh.GetGlobalTransform( out pos, out rot, out scl ); Mat4 transform = new Mat4( rot.ToMat3() * Mat3.FromScale( scl ), pos ); foreach( SubMesh subMesh in mesh.SubMeshes ) { if( subMesh.AllowCollision ) { Vec3[] vertices; int[] indices; subMesh.GetSomeGeometry( out vertices, out indices ); if( vertices != null ) { for( int n = 0; n < vertices.Length; n++ ) vertices[ n ] = transform * vertices[ n ]; collector.Add( vertices, vertices.Length, indices, indices.Length ); added = true; } } } } } } return added; } //HeightmapTerrain HeightmapTerrain terrain = entity as HeightmapTerrain; if( terrain != null ) { int size = terrain.GetHeightmapSizeAsInteger(); Vec3[] vertices = new Vec3[ ( size + 1 ) * ( size + 1 ) ]; int[] indices = new int[ size * size * 6 ]; int vertexPosition = 0; int indexPosition = 0; for( int y = 0; y < size + 1; y++ ) { for( int x = 0; x < size + 1; x++ ) { //SodanKerjuu: no need, you will have unused vertices, but they won't matter for Recast if they are not indexed //if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) //{ Vec2 pos2 = terrain.GetPositionXY( new Vec2I( x, y ) ); Vec3 pos = new Vec3( pos2.X, pos2.Y, terrain.GetHeight( new Vec2I( x, y ) ) ); vertices[ vertexPosition ] = pos; vertexPosition++; //} } } for( int y = 0; y < size; y++ ) { for( int x = 0; x < size; x++ ) { if( !terrain.GetHoleFlag( new Vec2I( x, y ) ) ) { indices[ indexPosition + 0 ] = ( size + 1 ) * y + x; indices[ indexPosition + 1 ] = ( size + 1 ) * y + x + 1; indices[ indexPosition + 2 ] = ( size + 1 ) * ( y + 1 ) + x + 1; indices[ indexPosition + 3 ] = ( size + 1 ) * ( y + 1 ) + x + 1; indices[ indexPosition + 4 ] = ( size + 1 ) * ( y + 1 ) + x; indices[ indexPosition + 5 ] = ( size + 1 ) * y + x; indexPosition += 6; } } } collector.Add( vertices, vertexPosition, indices, indexPosition ); return true; } return false; }
private static IEnumerable<Mat4> TubeTransforms() { var res = new Mat4 (1f); for (int i = 0; i < 10; i++) { res = Mat.RotationX<Mat4> (10f.Radians ()) * Mat.Translation<Mat4> (0f, 0f, -10f) * res; yield return res; } }
static void AddCone( Camera camera, Vec3 from, Vec3 to, float radius ) { Vec3 direction = to - from; float length = direction.Normalize(); Vec3[] positions; int[] indices; GeometryGenerator.GenerateCone( radius, length, 32, true, true, out positions, out indices ); Quat rotation = Quat.FromDirectionZAxisUp( direction ); Mat4 transform = new Mat4( rotation.ToMat3(), from ); camera.DebugGeometry.AddVertexIndexBuffer( positions, indices, transform, false, true ); }
static void AddSphere( Camera camera, Sphere sphere ) { Vec3[] positions; int[] indices; GeometryGenerator.GenerateSphere( sphere.Radius, 4, 4, false, out positions, out indices ); Mat4 transform = new Mat4( Mat3.Identity, sphere.Origin ); camera.DebugGeometry.AddVertexIndexBuffer( positions, indices, transform, false, true ); }
static void AddThicknessLine( Camera camera, Vec3 start, Vec3 end, float thickness ) { Vec3 diff = end - start; Vec3 direction = diff.GetNormalize(); Quat rotation = Quat.FromDirectionZAxisUp( direction ); float length = diff.Length(); float thickness2 = thickness; Mat4 t = new Mat4( rotation.ToMat3() * Mat3.FromScale( new Vec3( length, thickness2, thickness2 ) ), ( start + end ) * .5f ); if( addThicknessLinePositions == null ) GeometryGenerator.GenerateBox( new Vec3( 1, 1, 1 ), out addThicknessLinePositions, out addThicknessLineIndices ); camera.DebugGeometry.AddVertexIndexBuffer( addThicknessLinePositions, addThicknessLineIndices, t, false, true ); }
static void AddSphere( Camera camera, Sphere sphere ) { if( addSpherePositions == null ) GeometryGenerator.GenerateSphere( sphere.Radius, 8, 8, false, out addSpherePositions, out addSphereIndices ); Mat4 transform = new Mat4( Mat3.Identity, sphere.Origin ); camera.DebugGeometry.AddVertexIndexBuffer( addSpherePositions, addSphereIndices, transform, false, true ); }
void Pass_RenderObjectPass( Pass pass, Vec3 objectWorldPosition ) { //update cubemap reflection textures if( cubemapEventUnitStates != null ) { for( int n = 0; n < cubemapEventUnitStates.Count; n++ ) { Pair<Pass, TextureUnitState> item = cubemapEventUnitStates[ n ]; if( item.First == pass ) UpdateReflectionCubemap( item.Second, objectWorldPosition ); } } //update maps transform with animations if( mapsWithAnimations != null ) { for( int n = 0; n < mapsWithAnimations.Count; n++ ) UpdateMapTransformGpuParameters( mapsWithAnimations[ n ] ); } //set the matrix for projective texturing if( projectiveTexturing ) { Mat4 clipSpaceToImageSpaceMatrix = new Mat4( 0.5f, 0, 0, 0, 0, -0.5f, 0, 0, 0, 0, 1, 0, 0.5f, 0.5f, 0, 1 ); Mat4 matrix = clipSpaceToImageSpaceMatrix * projectiveTexturingFrustum.GetProjectionMatrix() * projectiveTexturingFrustum.GetViewMatrix(); matrix.Transpose(); SetCustomGpuParameter( GpuParameters.texViewProjImageMatrix0, matrix.Item0, true, false, false ); SetCustomGpuParameter( GpuParameters.texViewProjImageMatrix1, matrix.Item1, true, false, false ); SetCustomGpuParameter( GpuParameters.texViewProjImageMatrix2, matrix.Item2, true, false, false ); SetCustomGpuParameter( GpuParameters.texViewProjImageMatrix3, matrix.Item3, true, false, false ); } }
ColorValue RenderPixel( Vec2I pixelIndex ) { int triangleIndex = lightmapTriangleMap[ pixelIndex.Y ][ pixelIndex.X ]; if( triangleIndex == -1 ) return new ColorValue( -1, -1, -1, -1 ); Mesh mesh = lightmapMeshObject.Mesh; Mat4 transform = new Mat4( lightmapMeshObject.Rotation.ToMat3() * Mat3.FromScale( lightmapMeshObject.Scale ), lightmapMeshObject.Position ); Vec3 position; Vec3 normal; { Vec2 texCoord = GetTexCoordByPixelIndex( pixelIndex ); int index0 = mesh.Indices[ triangleIndex * 3 + 0 ]; int index1 = mesh.Indices[ triangleIndex * 3 + 1 ]; int index2 = mesh.Indices[ triangleIndex * 3 + 2 ]; Vec3 position0 = transform * mesh.Positions[ index0 ]; Vec3 position1 = transform * mesh.Positions[ index1 ]; Vec3 position2 = transform * mesh.Positions[ index2 ]; Vec3 normal0 = lightmapMeshObject.Rotation * mesh.Normals[ index0 ]; Vec3 normal1 = lightmapMeshObject.Rotation * mesh.Normals[ index1 ]; Vec3 normal2 = lightmapMeshObject.Rotation * mesh.Normals[ index2 ]; Vec2 texCoord0 = mesh.LightmapTexCoords[ index0 ]; Vec2 texCoord1 = mesh.LightmapTexCoords[ index1 ]; Vec2 texCoord2 = mesh.LightmapTexCoords[ index2 ]; float coef0; float coef1; GetTriangePositionCoefficients( ref texCoord0, ref texCoord1, ref texCoord2, ref texCoord, out coef0, out coef1 ); //calculate position { Vec3 p01 = Vec3.Lerp( position0, position1, coef0 ); Vec3 p02 = Vec3.Lerp( position0, position2, coef0 ); position = Vec3.Lerp( p01, p02, coef1 ); } //calculate normal { Vec3 p01 = Vec3.Lerp( normal0, normal1, coef0 ); Vec3 p02 = Vec3.Lerp( normal0, normal2, coef0 ); normal = Vec3.Lerp( p01, p02, coef1 ); normal.Normalize(); } } //calculate pixel color ColorValue resultColor = new ColorValue( 0, 0, 0 ); foreach( MyLight light in lights ) { //simple culling method. need use grid if( !light.Bounds.IsContainsPoint( position ) ) continue; //calculate illumination float illumination = light.GetIllumination( position, normal ); if( illumination <= .00001f ) continue; //check for direct visibility bool shadowed = false; if( calculateShadows ) { Ray ray = light.GetCheckVisibilityRay( position ); RayCastResult result = physicsScene.RayCast( ray, contactGroup ); if( result.Shape != null ) shadowed = true; } ColorValue color = light.DiffuseColor * illumination; if( shadowed ) color *= new ColorValue( 1, 1, 1 ) - shadowColor; resultColor += color; } resultColor.Alpha = 1; return resultColor; }
public CoordinateSystem(string name, Mat4 transform) { Name = name; Transform = transform; }
public Plane[] CullingPlanes(Mat4 cameraToWorld) { var corners = Corners.Map (p => cameraToWorld.Transform (p)); return new Plane[6] { new Plane (corners[1], corners[0], corners[4]), // left new Plane (corners[3], corners[2], corners[6]), // right new Plane (corners[0], corners[3], corners[7]), // bottom new Plane (corners[2], corners[1], corners[5]), // top new Plane (corners[0], corners[1], corners[2]), // near new Plane (corners[6], corners[5], corners[4]) // far }; }
protected override void OnDebugRender( DebugGeometry debugGeometry, ref Mat4 bodyTransform, bool simpleGeometry ) { Bounds localBounds = new Bounds( -halfDimensions, halfDimensions ); Mat4 t = bodyTransform; if( !IsIdentityTransform ) t *= GetTransform(); Box box = new Box( localBounds ) * t; debugGeometry.AddBox( box ); }