private void LoadNif(string path) { nifPath = path; try { NifFile f = BSAArchive.LoadMesh(path); if (f == null) { throw new ApplicationException("Failed to load nif: " + path); } nif = f; } catch (ApplicationException ex) { MessageBox.Show("An error occured while loading the nif: " + ex.Message, "Error"); return; } //Change camera radius lightControl.Radius = nif.Radius; camera.SetRadius(nif.Radius * 3.0f, 0, nif.Radius * 4.9f); float aspect = (float)sampleFramework.BackBufferSurfaceDescription.Width / (float)sampleFramework.BackBufferSurfaceDescription.Height; camera.SetProjectionParameters((float)Math.PI / 4, aspect, nif.Radius / 80, nif.Radius * 5); //Change the subset control box ComboBox cb = sampleUi.GetComboBox(SubsetControl); cb.Clear(); cb.AddItem("Whole mesh", (int)-1); for (int i = 0; i < nif.Subsets; i++) { cb.AddItem("Subset " + i, i); } }
private unsafe void BasicSetup(byte[] data, string tex0) { LoadReturn lr = Load(data, data.Length); if (lr.Subsets <= 0) { throw new ApplicationException("Failed to load nif"); } subsets = new Subset[lr.Subsets]; radius = lr.maxsize; loadLog = new string(lr.log); if (lr.FailedSubsets > 0) { System.Windows.Forms.MessageBox.Show("" + lr.FailedSubsets + " could not be rendered", "Warning"); } string texFileName; for (uint i = 0; i < subsets.Length; i++) { //Get basic info GetInfo(i, out subsets[i].info); GetMaterial(i, out subsets[i].mat); GetTransform(i, out subsets[i].transform); if (i == 0 && tex0 != null) { texFileName = tex0; } else if (subsets[i].info.containsTexture) { sbyte *charPtr; GetTex(i, out charPtr); texFileName = new string(charPtr); } else { texFileName = null; } //sanity check //if(!subsets[i].info.containsTexCoords) throw new ApplicationException("Vertex texture coords are missing from subset "+i); //if(!subsets[i].info.containsNormals) throw new ApplicationException("Vertex normals are missing from subset "+i); //if(texFileName==null) throw new ApplicationException("No texture name was specified in subset "+i); //Load textures if (texFileName != null) { System.IO.Stream stream = BSAArchive.GetTexture(texFileName); if (stream != null) { subsets[i].colorMap = TextureLoader.FromStream(device, stream); SurfaceDescription desc = subsets[i].colorMap.GetLevelDescription(0); subsets[i].data.cWidth = desc.Width; subsets[i].data.cHeight = desc.Height; subsets[i].data.cformat = desc.Format; subsets[i].data.path = texFileName; } else { throw new ApplicationException("Could not load texture for subset " + i); } stream = BSAArchive.GetGlowTexture(texFileName); if (stream != null) { subsets[i].glowMap = TextureLoader.FromStream(device, stream); SurfaceDescription desc = subsets[i].glowMap.GetLevelDescription(0); subsets[i].data.gWidth = desc.Width; subsets[i].data.gHeight = desc.Height; subsets[i].data.gformat = desc.Format; } else { subsets[i].data.gWidth = -1; } stream = BSAArchive.GetNormalTexture(texFileName); if (stream != null) { subsets[i].normalMap = TextureLoader.FromStream(device, stream); SurfaceDescription desc = subsets[i].normalMap.GetLevelDescription(0); subsets[i].data.nWidth = desc.Width; subsets[i].data.nHeight = desc.Height; subsets[i].data.nformat = desc.Format; } else { subsets[i].data.nWidth = -1; } } else { subsets[i].colorMap = null; subsets[i].data.cWidth = -1; subsets[i].data.gWidth = -1; subsets[i].data.nWidth = -1; } //Get vertex information VertexElement[] decl = new VertexElement[7]; decl[0] = new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0); decl[1] = new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Tangent, 0); decl[2] = new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.BiNormal, 0); decl[3] = new VertexElement(0, 36, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0); decl[4] = new VertexElement(0, 48, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0); decl[5] = new VertexElement(0, 56, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.Color, 0); decl[6] = VertexElement.VertexDeclarationEnd; subsets[i].vDecl = new VertexDeclaration(device, decl); if (subsets[i].info.containsTangentBinormal) { Mesh m = new Mesh(subsets[i].info.iCount / 3, subsets[i].info.vCount, MeshFlags.SystemMemory, decl, device); subsets[i].vBuffer = new VertexBuffer(typeof(ConvertedVertex), subsets[i].info.vCount, device, Usage.WriteOnly, VertexFormats.None, Pool.Managed); //ConvertedVertex[] cv=(ConvertedVertex[])subsets[i].vBuffer.Lock(0, LockFlags.None); ConvertedVertex[] cv = (ConvertedVertex[])m.LockVertexBuffer(typeof(ConvertedVertex), LockFlags.None, subsets[i].info.vCount); fixed(ConvertedVertex *cvPtr = cv) { GetVerticies(i, cvPtr); } m.UnlockVertexBuffer(); //subsets[i].vBuffer.Unlock(); //Indicies subsets[i].iBuffer = new IndexBuffer(typeof(ushort), subsets[i].info.iCount, device, Usage.WriteOnly, Pool.Managed); //ushort[] indicies=(ushort[])subsets[i].iBuffer.Lock(0, LockFlags.None); ushort[] indicies = (ushort[])m.LockIndexBuffer(typeof(ushort), LockFlags.None, subsets[i].info.iCount); fixed(ushort *iPtr = indicies) { GetIndicies(i, iPtr); } //subsets[i].iBuffer.Unlock(); m.UnlockIndexBuffer(); subsets[i].numTris = subsets[i].info.iCount / 3; int[] adj = new int[subsets[i].info.iCount]; m.GenerateAdjacency(0.01f, adj); m.ComputeTangent(0, 0, 0, 1, adj); //m.ComputeTangentFrame(TangentOptions.CalculateNormals|TangentOptions.GenerateInPlace); cv = (ConvertedVertex[])m.LockVertexBuffer(typeof(ConvertedVertex), LockFlags.ReadOnly, subsets[i].info.vCount); ConvertedVertex[] cv2 = (ConvertedVertex[])subsets[i].vBuffer.Lock(0, LockFlags.None); for (int j = 0; j < cv.Length; j++) { cv2[j] = cv[j]; } m.UnlockVertexBuffer(); subsets[i].vBuffer.Unlock(); indicies = (ushort[])m.LockIndexBuffer(typeof(ushort), LockFlags.None, subsets[i].info.iCount); ushort[] indicies2 = (ushort[])subsets[i].iBuffer.Lock(0, LockFlags.None); for (int j = 0; j < indicies.Length; j++) { indicies2[j] = indicies[j]; } m.UnlockIndexBuffer(); subsets[i].iBuffer.Unlock(); m.Dispose(); } else { subsets[i].vBuffer = new VertexBuffer(typeof(ConvertedVertex), subsets[i].info.vCount, device, Usage.WriteOnly, VertexFormats.None, Pool.Managed); ConvertedVertex[] cv = (ConvertedVertex[])subsets[i].vBuffer.Lock(0, LockFlags.None); fixed(ConvertedVertex *cvPtr = cv) { GetVerticies(i, cvPtr); } subsets[i].vBuffer.Unlock(); //Indicies subsets[i].iBuffer = new IndexBuffer(typeof(ushort), subsets[i].info.iCount, device, Usage.WriteOnly, Pool.Managed); ushort[] indicies = (ushort[])subsets[i].iBuffer.Lock(0, LockFlags.None); fixed(ushort *iPtr = indicies) { GetIndicies(i, iPtr); } subsets[i].iBuffer.Unlock(); subsets[i].numTris = subsets[i].info.iCount / 3; } } int alphaCount = 0; for (int i = 0; i < Subsets; i++) { if (subsets[i].info.hasalpha) { alphaCount++; } } AlphaIndicies = new int[alphaCount]; alphaCount = 0; for (int i = 0; i < Subsets; i++) { if (subsets[i].info.hasalpha) { AlphaIndicies[alphaCount++] = i; } } }