public void Render(QbModel model) { ssao_geometryDepth.UseShader(); geometryBuffer.BindFBOWritting(); ssao_geometryDepth.WriteUniform("gWVP", camera.modelviewprojection); ssao_geometryDepth.WriteUniform("gWV", camera.view); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); model.Render(); ssao.UseShader(); geometryBuffer.BindFBOReading(TextureUnit.Texture1); SSAOBuffer.BindFBOWritting(); GL.Clear(ClearBufferMask.ColorBufferBit); GL.BindBuffer(BufferTarget.ArrayBuffer, quadBuffer); GL.EnableVertexAttribArray(0); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 3, 0); GL.DrawArrays(PrimitiveType.Quads, 0, 4); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); ssao_voxel.UseShader(); SSAOBuffer.BindFBOReading(TextureUnit.Texture2); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); ssao_voxel.WriteUniform("modelview", camera.modelviewprojection); model.Render(ssao_voxel); }
public void Select(int index) { if (index < offsetindex + linecount && index >= offsetindex) { int nindex = index - offsetindex; background.Enable = true; background.SetBoundsNoScaling(Absolute_X, labels[nindex].Absolute_Y, size.X, labels[nindex].size.Y - (4f).ScaleVerticlSize()); UpdateWidgets(); } else { QbModel model = Singleton <QbManager> .INSTANCE.ActiveModel; int max = model.matrices.Count - linecount; int nindex = Math.Min(max, index); offsetindex = nindex; int bindex = 0; if (index > offsetindex) { bindex = index - offsetindex; } background.Enable = true; background.SetBoundsNoScaling(Absolute_X, labels[bindex].Absolute_Y, size.X, labels[bindex].size.Y - (4f).ScaleVerticlSize()); UpdateWidgets(); } scrollbar.SetValue(offsetindex); Singleton <GUI> .INSTANCE.Dirty = true; }
public static bool Export(string extension, string name, string path, QbModel model) { if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(name)) { return(false); } try { foreach (var exporter in exporters) { if (extension.Contains(exporter.extension)) { exporter.write(path, name, model); return(true); } } } catch (Exception ex) { MessageBox.Show("StoneVox had trouble trying to save. This could be because the folder you are saving to is protected. Try saving somewhere else, then re-running SV as Admin.", "StoneVox - Saving Error"); return(false); } return(false); }
public void write(QbModel model) { outgoingmessage.Write(model.name); outgoingmessage.Write(model.numMatrices); foreach (var m in model.matrices) { outgoingmessage.Write(m.name); outgoingmessage.Write(m.position.X); outgoingmessage.Write(m.position.Y); outgoingmessage.Write(m.position.Z); outgoingmessage.Write(m.size.X); outgoingmessage.Write(m.size.Y); outgoingmessage.Write(m.size.Z); outgoingmessage.Write(m.colors.Length); foreach (var color in m.colors) { outgoingmessage.Write(color.R); outgoingmessage.Write(color.G); outgoingmessage.Write(color.B); } outgoingmessage.Write(m.voxels.Count); foreach (var voxel in m.voxels.Values) { outgoingmessage.Write(voxel.colorindex); outgoingmessage.Write(voxel.alphamask); outgoingmessage.Write(voxel.x); outgoingmessage.Write(voxel.y); outgoingmessage.Write(voxel.z); } } }
public QbModel AddEmpty() { QbModel model = QbModel.EmptyModel(); AddModel(model); return(model); }
public static bool Export(string extension, string name, string path, QbModel model) { if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(name)) { return false; } try { foreach (var exporter in exporters) { if (extension.Contains(exporter.extension)) { exporter.write(path, name, model); return true; } } } catch (Exception ex) { MessageBox.Show("StoneVox had trouble trying to save. This could be because the folder you are saving to is protected. Try saving somewhere else, then re-running SV as Admin.", "StoneVox - Saving Error"); return false; } return false; }
public void Refresh() { offsetindex = 0; QbModel model = Singleton <QbManager> .INSTANCE.ActiveModel; scrollbar.UpdateScrollbar(model.matrices.Count); UpdateWidgets(); background.Enable = true; background.SetBoundsNoScaling(Absolute_X, labels[0].Absolute_Y, size.X, labels[0].size.Y - (4f).ScaleVerticlSize()); Singleton <GUI> .INSTANCE.Dirty = true; }
public void AddModel(QbModel model, bool setActive = true) { models.Add(model); if (setActive) { ActiveModel = model; ActiveMatrix.MatchFloorToSize(); } broadcaster.Broadcast(Message.ModelImported, model, model.name); }
public QbModel read(string path) { StopwatchUtil.startclient("regularqbread", "Begin SVP read"); QbModel model = _read(path); model.GenerateVertexBuffers(); model.FillVertexBuffers(); StopwatchUtil.stopclient("regularqbread", "End SVP read"); return(model); }
public override void onclientrecieve(NetIncomingMessage message) { Client.print("info", "Recieve qb packet"); StopwatchUtil.startclient("qbpacket", "Building qb model"); int junk = message.ReadInt32(); QbModel model = new QbModel(message.ReadString()); int matrixcount = message.ReadInt32(); model.setmatrixcount((uint)matrixcount); foreach (var m in model.matrices) { m.name = message.ReadString(); m.position = new OpenTK.Vector3(message.ReadFloat(), message.ReadFloat(), message.ReadFloat()); m.setsize((int)message.ReadFloat(), (int)message.ReadFloat(), (int)message.ReadFloat()); int colorcount = message.ReadInt32(); for (int i = 0; i < colorcount; i++) { m.GetColorIndex(message.ReadFloat(), message.ReadFloat(), message.ReadFloat()); } int voxelcount = message.ReadInt32(); for (int i = 0; i < voxelcount; i++) { int colorindex = message.ReadInt32(); byte alphamask = message.ReadByte(); int x = message.ReadInt32(); int y = message.ReadInt32(); int z = message.ReadInt32(); m.voxels.GetOrAdd(m.GetHash(x, y, z), new Voxel((short)x, (short)y, (short)z, alphamask, (short)colorindex)); } } Client.OpenGLContextThread.Add(() => { model.GenerateVertexBuffers(); model.FillVertexBuffers(); Singleton <QbManager> .INSTANCE.AddModel(model); StopwatchUtil.stopclient("qbpacket", "End building qb model"); }); base.onclientrecieve(message); }
public QbModelTab(QbModel model) : base() { this.model = model; height = Client.window.Qfont.fontData.maxGlyphHeight; height = height.ScaleVerticlSize(); vBorderOffset = -(3f).ScaleVerticlSize(); hBorderOffset = (3f).ScaleHorizontalSize(); label = new Label(GetNextAvailableID(), model.name, System.Drawing.Color.White, true); closeButton = new Label(GetNextAvailableID(), "x", System.Drawing.Color.DarkRed, true); var size = label.MeasureText(label.text + " "); closeButton.Parent = this; label.Parent = this; closeButton.handler = new WidgetEventHandler() { mouseenter = (e) => { closeButton.color = Color.Red; }, mouseleave = (e) => { closeButton.color = Color.DarkRed; }, mousedownhandler = (e, mouse) => { if (mouse.IsPressed && mouse.Button == OpenTK.Input.MouseButton.Left) { var result = MessageBox.Show("There might be unsaved changes to this model. Are you sure you want to close it?", "StoneVox : Closing Model", MessageBoxButtons.OKCancel); if (result == DialogResult.Cancel || result == DialogResult.Abort) { return; } Singleton <QbManager> .INSTANCE.RemoveModel(this.model); } } }; SetBounds(null, null, size.Width, height.UnScaleVerticlSize() * borderscale * 1.5f); closeButton.SetBoundsNoScaling(Absolute_X + this.size.X - closeButton.size.X * 1.5f, Absolute_Y + closeButton.size.Y * .9f); background = appearence.AddAppearence("background", new PlainBackground(new Color4(100 - 10, 87 - 10, 61 - 10, 255))); border = appearence.AddAppearence("border", new PlainBorder(4, new Color4(122 - 10, 106 - 10, 70 - 10, 255))); }
public override void onclientrecieve(NetIncomingMessage message) { Client.print("info", "Recieve qb packet"); StopwatchUtil.startclient("qbpacket", "Building qb model"); int junk = message.ReadInt32(); QbModel model = new QbModel(message.ReadString()); int matrixcount = message.ReadInt32(); model.setmatrixcount((uint)matrixcount); foreach (var m in model.matrices) { m.name = message.ReadString(); m.position = new OpenTK.Vector3(message.ReadFloat(), message.ReadFloat(), message.ReadFloat()); m.setsize((int)message.ReadFloat(), (int)message.ReadFloat(), (int)message.ReadFloat()); int colorcount = message.ReadInt32(); for (int i = 0; i < colorcount; i++) { m.GetColorIndex(message.ReadFloat(), message.ReadFloat(), message.ReadFloat()); } int voxelcount = message.ReadInt32(); for (int i = 0; i < voxelcount; i++) { int colorindex = message.ReadInt32(); byte alphamask = message.ReadByte(); int x = message.ReadInt32(); int y = message.ReadInt32(); int z = message.ReadInt32(); m.voxels.GetOrAdd(m.GetHash(x, y, z), new Voxel((short)x, (short)y, (short)z, alphamask, (short)colorindex)); } } Client.OpenGLContextThread.Add(() => { model.GenerateVertexBuffers(); model.FillVertexBuffers(); Singleton<QbManager>.INSTANCE.AddModel(model); StopwatchUtil.stopclient("qbpacket", "End building qb model"); }); base.onclientrecieve(message); }
public QbModelTab(QbModel model) : base() { this.model = model; height = Client.window.Qfont.fontData.maxGlyphHeight; height = height.ScaleVerticlSize(); vBorderOffset = -(3f).ScaleVerticlSize(); hBorderOffset = (3f).ScaleHorizontalSize(); label = new Label(GetNextAvailableID(), model.name, System.Drawing.Color.White, true); closeButton = new Label(GetNextAvailableID(), "x", System.Drawing.Color.DarkRed, true); var size = label.MeasureText(label.text + " "); closeButton.Parent = this; label.Parent = this; closeButton.handler = new WidgetEventHandler() { mouseenter = (e) => { closeButton.color = Color.Red; }, mouseleave= (e) => { closeButton.color = Color.DarkRed; }, mousedownhandler = (e, mouse) => { if (mouse.IsPressed && mouse.Button == OpenTK.Input.MouseButton.Left) { var result = MessageBox.Show("There might be unsaved changes to this model. Are you sure you want to close it?", "StoneVox : Closing Model", MessageBoxButtons.OKCancel); if (result == DialogResult.Cancel || result == DialogResult.Abort) return; Singleton<QbManager>.INSTANCE.RemoveModel(this.model); } } }; SetBounds(null, null, size.Width, height.UnScaleVerticlSize() * borderscale * 1.5f); closeButton.SetBoundsNoScaling(Absolute_X + this.size.X - closeButton.size.X * 1.5f, Absolute_Y + closeButton.size.Y * .9f); background = appearence.AddAppearence("background", new PlainBackground(new Color4(100 - 10, 87 - 10, 61 - 10, 255))); border = appearence.AddAppearence("border", new PlainBorder(4, new Color4(122 - 10, 106 - 10, 70 - 10, 255))); }
public static QbModel EmptyModel() { QbModel model = new QbModel(); model.version = 257; model.zAxisOrientation = 1; model.visibilityMaskEncoded = 1; model.setmatrixcount(1); model.name = "default"; model.matrices[0].name = "default"; model.matrices[0].setsize(15, 15, 15, true); model.GenerateVertexBuffers(); return model; }
public static QbModel EmptyModel() { QbModel model = new QbModel(); model.version = 257; model.zAxisOrientation = 1; model.visibilityMaskEncoded = 1; model.setmatrixcount(1); model.name = "default"; model.matrices[0].name = "default"; model.matrices[0].setsize(15, 15, 15, true); model.GenerateVertexBuffers(); return(model); }
public static void loadqbnetworking(string path) { if (Client.net != null && Client.net.ConnectionsCount == 0) { Client.print("error", "Error : loadqbnetworking - is meant for network loading of files. Connect your client to a server before running this command, or try using \"loadqb\""); return; } Client.OpenGLContextThread.Add(() => { StopwatchUtil.startclient("internalqbread", "Begin Qb Read"); ImporterQb importer = new ImporterQb(); QbModel model = importer._read(path); StopwatchUtil.stopclient("internalqbread", "End Qb Read"); StopwatchUtil.startclient("clientwriteqbpacket", "Begin Qb Packet Write"); var packet = PacketWriter.write <Packet_QbImported>(NetEndpoint.CLIENT); packet.write(model); packet.send(); StopwatchUtil.stopclient("clientwriteqbpacket", "End qb Packet Write"); }); }
public void UpdateWidgets() { QbModel model = Singleton <QbManager> .INSTANCE.ActiveModel; for (int i = 0; i < labels.Count; i++) { Label label = labels[i]; ToggleButton button = buttons[i]; string labeltext = i + offsetindex < model.matrices.Count ? model.matrices[i + offsetindex].name : ""; if (labeltext == "") { label.Enable = false; button.MaintainEnabled = false; button.Enable = false; button.MaintainEnabled = true; continue; } else { label.Enable = true; label.text = labeltext; button.MaintainEnabled = false; button.Enable = true; button.MaintainEnabled = true; if (model.matrices[i + offsetindex].Visible) { button.Toggle(0); } else { button.Toggle(1); } } } }
public void RemoveModel(QbModel model) { // stonevox as of now, must have a qbmodel reference... // this will be cleanup sometime // it's a dirty fix for now :( if (ActiveModelIndex == 0 && models.Count == 1) { if (models.Remove(model)) { AddEmpty(); broadcaster.Broadcast(Message.ModelRemoved, model, model.name); model = null; } FixActiveMatrix(); return; } if (models.Remove(model)) { FixActiveMatrix(); broadcaster.Broadcast(Message.ModelRemoved, model, model.name); model = null; } }
public void Render(QbModel model) { switch (wireFrameType) { case WireframeType.WireframeBlack: if (drawWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(1); wireframeShader.UseShader(); wireframeShader.WriteUniform("vHSV", new Vector3(1, 0f, 0)); wireframeShader.WriteUniform("modelview", camera.modelviewprojection); model.getactivematrix.RenderAll(wireframeShader); } GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(2); voxelShader.UseShader(); voxelShader.WriteUniform("modelview", camera.modelviewprojection); selection.render(voxelShader); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); model.RenderAll(voxelShader); break; case WireframeType.WireframeColorMatch: if (drawWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(1); wireframeShader.UseShader(); wireframeShader.WriteUniform("vHSV", new Vector3(1, 1.1f, 1.1f)); wireframeShader.WriteUniform("modelview", camera.modelviewprojection); model.getactivematrix.RenderAll(wireframeShader); } GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(2); voxelShader.UseShader(); voxelShader.WriteUniform("modelview", camera.modelviewprojection); selection.render(voxelShader); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); model.RenderAll(voxelShader); break; case WireframeType.SmartOutline: if (drawWireframe) { GL.CullFace(CullFaceMode.Front); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(2); wireframeShader.UseShader(); wireframeShader.WriteUniform("vHSV", new Vector3(1, 1.5f, 1.0f)); wireframeShader.WriteUniform("modelview", camera.modelviewprojection); model.getactivematrix.RenderAll(wireframeShader); } GL.CullFace(CullFaceMode.Back); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(2); voxelShader.UseShader(); voxelShader.WriteUniform("modelview", camera.modelviewprojection); selection.render(voxelShader); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); model.RenderAll(voxelShader); break; } }
protected override void OnKeyDown(KeyboardKeyEventArgs e) { base.OnKeyDown(e); input.handleKeydown(e); if (e.Control && e.Key == Key.O) { var open = new OpenFileDialog(); open.Multiselect = false; open.Title = "StoneVox - Open File"; open.DefaultExt = ".qb"; open.FileOk += (s, o) => { Client.OpenGLContextThread.Add(() => { ImportExportUtil.Import(open.FileName); }); }; Thread thread = new Thread(() => { open.ShowDialog(); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } if (e.Control && e.Key == Key.S) { var save = new SaveFileDialog(); save.Title = "StoneVox - Save File"; save.Filter = "StoneVox Project (.svp)|*.svp|Qubicle Binary (.qb)|*.qb|Wavefront OBJ (.obj)|*.obj|All files (*.*)|*.*"; save.DefaultExt = ".svp"; save.FileOk += (s, t) => { QbModel model = manager.ActiveModel; model.name = save.FileName.Split('\\').Last(); if (model.name.Contains('.')) { model.name = model.name.Split('.').First(); } broadcaster.Broadcast(Message.ModelRenamed, model, model.name); ImportExportUtil.Export(save.FileName.Split('\\').Last().Replace(model.name, ""), model.name, Path.GetDirectoryName(save.FileName), model); }; Thread thread = new Thread(() => { save.ShowDialog(); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } else if (e.Control && e.Key == Key.F12) { GUIEditor editor = new GUIEditor(); editor.Show(); } //else if (e.Key == Key.T) //{ // Stopwatch w = Stopwatch.StartNew(); // var model = Singleton<QbManager>.INSTANCE.ActiveMatrix; // Colort color = new Colort(1f, 0f, 0f); // var volume = new VoxelVolume() // { // minx = 0, // maxx = 100, // miny = 0, // maxy = 100, // minz = 0, // maxz = 100 // }; // model.Add(volume, ref color); // w.Stop(); // Console.WriteLine("add " + w.ElapsedMilliseconds.ToString()); //} //else if (e.Key == Key.T) //{ // Stopwatch w = Stopwatch.StartNew(); // var model = Singleton<QbManager>.INSTANCE.ActiveMatrix; // Colort color = new Colort(1f, 0f, 0f); // for (int x = 0; x < 100; x++) // for (int z = 0; z < 100; z++) // for (int y = 0; y< 100; y++) // model.Add(x, y, z, color); // w.Stop(); // Console.WriteLine("add " +w.ElapsedMilliseconds.ToString()); //} //else if (e.Key == Key.Y) //{ // Stopwatch w = Stopwatch.StartNew(); // var model = Singleton<QbManager>.INSTANCE.ActiveMatrix; // Colort color = new Colort(1f, 0f, 0f); // for (int x = 0; x < 100; x++) // for (int z = 0; z < 100; z++) // for (int y = 0; y < 100; y++) // model.Remove(x, y, z); // w.Stop(); // Console.WriteLine("earse " + w.ElapsedMilliseconds.ToString()); //} }
public void write(string path, string name, QbModel model) { string fullpath = Path.Combine(path, name + extension); using (FileStream f = new FileStream(fullpath, FileMode.OpenOrCreate)) { using (BinaryWriter w = new BinaryWriter(f)) { w.Write(model.version); w.Write(model.colorFormat); w.Write(model.zAxisOrientation); w.Write(model.compressed); w.Write(model.visibilityMaskEncoded); w.Write((uint)model.matrices.Count); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; if (!m.Visible) continue; int startx = Math.Min(0 , m.minx ); int starty = Math.Min(0, m.miny); int startz = Math.Min(0 , m.minz ); int width = (int)(Math.Abs(Math.Min(0, m.minx)) + m.maxx + 1); int height = (int)(Math.Abs(Math.Min(0, m.miny)) + m.maxy + 1); int length = (int)(Math.Abs(Math.Min(0, m.minz)) + m.maxz + 1); if (width < m.size.X) width = (int)m.size.X; if (height < m.size.Y) height = (int)m.size.Y; if (length < m.size.Z) length = (int)m.size.Z; w.Write(m.name); w.Write((uint)width); w.Write((uint)height); w.Write((uint)length); w.Write((int)m.position.X); w.Write((int)m.position.Y); w.Write((int)m.position.Z); if (model.compressed == 0) { Voxel voxel; for (int z = startz; z < startz + length; z++) for (int y = starty; y < starty + height; y++) for (int x = startx; x < startx + width; x++) { int zz = model.zAxisOrientation == (int)0 ? z : (int)(length - z - 1); if (m.voxels.TryGetValue(m.GetHash(x, y, zz), out voxel)) { Colort c = m.colors[voxel.colorindex]; int r = (int)(c.R * 255f); int g = (int)(c.G * 255f); int b = (int)(c.B * 255f); w.Write((byte)r); w.Write((byte)g); w.Write((byte)b); w.Write(voxel.alphamask); } else { w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); } } } } } } }
public void write(string path, string name, QbModel model) { Client.OpenGLContextThread.Add(() => { int Wwidth = Client.window.Width; int Wheight = Client.window.Height; int framebuffer = GL.GenBuffer(); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer); int color = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, color); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, Wwidth, Wheight, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, color, 0); int depth = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, depth); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent24, Wwidth, Wheight, 0, PixelFormat.DepthComponent, PixelType.UnsignedByte, IntPtr.Zero); GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, TextureTarget.Texture2D, depth, 0); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer); GL.DrawBuffers(1, new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0 }); GL.ClearColor(0, 0, 0, 0); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); int minx = 10000; int miny = 10000; int minz = 10000; int maxx = 0; int maxy = 0; int maxz = 0; int sizex = 0; int sizey = 0; int sizez = 0; foreach (var matrix in model.matrices) { if (!matrix.Visible) continue; if (matrix.minx < minx) minx = matrix.minx; if (matrix.maxx > maxx) maxx = matrix.maxx; if (matrix.miny < miny) miny = matrix.miny; if (matrix.maxy > maxy) maxy = matrix.maxy; if (matrix.minz < minz) minz = matrix.minz; if (matrix.maxz > maxz) maxz = matrix.maxz; } sizex = maxx - minx; sizey = maxy - miny; sizez = maxz - minz; float backup = 0; if (sizey * 1.5f > 20) backup = sizey * 1.5f; else if (sizex * 1.5f > 20) backup = sizex * 1.5f; else backup = 20; var centerpos = new Vector3((minx + ((maxx - minx) / 2)), (miny + ((maxy - miny) / 2)), (minz + ((maxz - minz) / 2))); var position = centerpos + new Vector3(.5f, sizey * .65f, backup); Vector3 direction; Vector3.Subtract(ref centerpos, ref position, out direction); direction.Normalize(); var cameraright = Vector3.Cross(direction, VectorUtils.UP); var cameraup = Vector3.Cross(cameraright, direction); var view = Matrix4.LookAt(position, position + direction, cameraup); var modelviewprojection = view * Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), (float)Wwidth / (float)Wheight, 1, 300); Shader voxelShader = ShaderUtil.GetShader("qb"); voxelShader.UseShader(); voxelShader.WriteUniform("modelview", modelviewprojection); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); model.RenderAll(voxelShader); string fullpath = Path.Combine(path, name + extension); using (FileStream f = new FileStream(fullpath, FileMode.OpenOrCreate)) { var bit = Screenshot.ScreenShot(ReadBufferMode.ColorAttachment0); bit = cropImage(bit, new Rectangle(Wwidth /4, 0, Wwidth - ((Wwidth/4)*2), Wheight)); bit = bit.ResizeImage(ResizeKeepAspect(bit.Size, 400, 400)); byte[] buffer = new byte[0]; using (MemoryStream m = new MemoryStream()) { bit.Save(m, System.Drawing.Imaging.ImageFormat.Png); buffer = m.ToArray(); } using (BinaryWriter w = new BinaryWriter(f)) { w.Write(version); w.Write((int)buffer.Length); w.Write(buffer); // note - just in case i allow extending the color pattet // which i probably will w.Write(colorpalletflag); for (int i = 0; i < 10; i++) { var c = Singleton<GUI>.INSTANCE.Get<EmptyWidget>(GUIID.START_COLOR_SELECTORS+ i).appearence.Get<PlainBackground>("background").color; w.Write(c.R); w.Write(c.G); w.Write(c.B); } w.Write(model.version); w.Write(model.colorFormat); w.Write(model.zAxisOrientation); w.Write(model.compressed); w.Write(model.visibilityMaskEncoded); w.Write((uint)model.matrices.Count); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; if (!m.Visible) continue; int startx = Math.Min(0, m.minx); int starty = Math.Min(0, m.miny); int startz = Math.Min(0, m.minz); int width = (int)(Math.Abs(Math.Min(0, m.minx)) + m.maxx + 1); int height = (int)(Math.Abs(Math.Min(0, m.miny)) + m.maxy + 1); int length = (int)(Math.Abs(Math.Min(0, m.minz)) + m.maxz + 1); if (width < m.size.X) width = (int)m.size.X; if (height < m.size.Y) height = (int)m.size.Y; if (length < m.size.Z) length = (int)m.size.Z; w.Write(m.name); w.Write((uint)width); w.Write((uint)height); w.Write((uint)length); w.Write((int)m.position.X); w.Write((int)m.position.Y); w.Write((int)m.position.Z); if (model.compressed == 0) { Voxel voxel; for (int z = startz; z < startz + length; z++) for (int y = starty; y < starty + height; y++) for (int x = startx; x < startx + width; x++) { int zz = model.zAxisOrientation == (int)0 ? z : (int)(length - z - 1); if (m.voxels.TryGetValue(m.GetHash(x, y, zz), out voxel)) { Colort c = m.colors[voxel.colorindex]; w.Write((byte)(c.R * 255)); w.Write((byte)(c.G * 255)); w.Write((byte)(c.B * 255)); w.Write(voxel.alphamask); } else { w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); } } } } } GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); GL.DeleteTexture(color); GL.DeleteTexture(depth); GL.DeleteFramebuffer(framebuffer); } }); }
void SetActiveModel(QbModel model) { SetActiveModel(models.IndexOf(model)); }
public QbModelMatrixListbox(float width, float height) : base(-1) { //input = Singleton<ClientInput>.INSTANCE; ID = GetNextAvailableID(); appearence.AddAppearence("border", new PlainBorder(6, new Color4(122f / 256f, 106f / 256f, 70f / 256f, 1f))); appearence.AddAppearence("background", new PlainBackground(new Color4(66, 63, 63, 255))); float realheight = Client.window.Qfont.fontData.maxGlyphHeight; float fontheight = (float)realheight * 2f; linecount = (int)((height.UnScaleVerticlSize()) / fontheight); //float labelspacing = 25f; textbox = new TextBox(100000000, "", Color4.Wheat.ToSystemDrawingColor(), 1000); textbox.focused = true; fontheight = fontheight.ScaleVerticlSize(); labels = new List <Label>(); buttons = new List <ToggleButton>(); size.X = width; size.Y = linecount * fontheight;// + linecount * (labelspacing).ScaleVerticlSize(); QbModel model = null; bool hasmodel = Singleton <QbManager> .INSTANCE.HasModel; if (hasmodel) { model = Singleton <QbManager> .INSTANCE.ActiveModel; } float previouseY = Absolute_Y + size.Y - realheight.ScaleVerticlSize() * 2f; background = new EmptyWidget(); background.Parent = this; PlainBackground bg = new PlainBackground(Color4.Black); background.appearence.AddAppearence("background", bg); for (int i = 0; i < linecount; i++) { string labeltext = ""; if (hasmodel) { labeltext = i < model.matrices.Count ? model.matrices[i].name : ""; } Label label = new Label(GetNextAvailableID(), labeltext, System.Drawing.Color.White, true); label.Parent = this; label.SetBoundsNoScaling(Absolute_X + size.X * .08f, previouseY); Boolean editing = false; label.customData.Add("edit", editing); label.handler = new WidgetEventHandler() { mousedownhandler = (e, mouse) => { if (!mouse.IsPressed || mouse.Button != OpenTK.Input.MouseButton.Left) { return; } background.Enable = true; bg.color = Color4.Black; background.SetBoundsNoScaling(Absolute_X, label.Absolute_Y, size.X, label.size.Y - (4f).ScaleVerticlSize()); QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; int index = labels.IndexOf(label); int offset = index + offsetindex; Singleton <QbManager> .INSTANCE.ActiveMatrixIndex = offset; lastActiveIndex = labels.ToList().IndexOf(label); }, mousedoubleclick = (e, mouse) => { if (!mouse.IsPressed || mouse.Button != OpenTK.Input.MouseButton.Left) { return; } QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; int index = labels.IndexOf(label); int offset = index + offsetindex; Singleton <QbManager> .INSTANCE.ActiveMatrixIndex = offset; Singleton <Camera> .INSTANCE.TransitionToMatrix(); }, mouseenter = (e) => { //lastover = label; int index = labels.IndexOf(label); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].highlight = new Colort(1.5f, 1.5f, 1.5f); }, mouseleave = (e) => { int index = labels.IndexOf(label); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].highlight = new Colort(1f, 1f, 1f); }, Keydownhandler = (e, k) => { if (!edit && k.Key == Key.F2) { previousText = label.text; editinglable = label; textbox.Text = label.text; textbox.HandleFocusedGained(); label.text += "|"; editing = true; edit = true; Singleton <GUI> .INSTANCE.Dirty = true; } else if (edit && k.Key == Key.Enter || k.Key == Key.KeypadEnter) { editing = false; edit = false; label.text = textbox.Text; if (string.IsNullOrEmpty(label.text)) { label.text = previousText; MessageBox.Show("Matrix names MUST contain at least one character", "Matrix Name Limits"); } Singleton <GUI> .INSTANCE.Dirty = true; int index = labels.IndexOf(label); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].name = label.text; Singleton <GUI> .INSTANCE.Get <TextBox>(GUIID.ACTIVE_MATRIX_NAME).Text = label.text; } else if (edit && k.Key == Key.Escape) { label.text = previousText.Replace("|", ""); edit = false; editing = false; Singleton <GUI> .INSTANCE.Get <TextBox>(GUIID.ACTIVE_MATRIX_NAME).Text = label.text; Singleton <GUI> .INSTANCE.Dirty = true; } else if (editing) { textbox.HandleKeyDown(k); label.text = textbox.Text; } }, Keypresshandler = (e, k) => { if (editing) { textbox.HandleKeyPress(k); label.text = textbox.Text; } }, focuslost = (e) => { if (editing) { editing = false; edit = false; label.text = textbox.Text; if (string.IsNullOrEmpty(label.text)) { label.text = previousText; MessageBox.Show("Matrix names MUST contain at least one character", "Matrix Name Limits"); } label.color = System.Drawing.Color.White; Singleton <GUI> .INSTANCE.Dirty = true; int index = labels.IndexOf(label); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].name = label.text; Singleton <GUI> .INSTANCE.Get <TextBox>(GUIID.ACTIVE_MATRIX_NAME).Text = label.text; } } }; if (i == 0) { background.Enable = true; bg.color = Color4.Black; background.SetBoundsNoScaling(Absolute_X, label.Absolute_Y, size.X, label.size.Y - (4f).ScaleVerticlSize()); } label.StatusText = stonevox.StatusText.label_matrixlistbox; labels.Add(label); ToggleButton button = new ToggleButton("./data/images/qb_matrix_visibility_on.png", "./data/images/qb_matrix_visibility_off.png"); button.Parent = this; button.SetBoundsNoScaling(Absolute_X + size.X * .01f, previouseY + fontheight * .02f, size.X * .05f, fontheight); button.handler = new WidgetEventHandler() { mousedownhandler = (e, mouse) => { if (mouse.IsPressed && mouse.Button == MouseButton.Left) { int index = buttons.IndexOf(button); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].Visible = !m.matrices[offset].Visible; } }, mouseenter = (e) => { int index = labels.IndexOf(label); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].highlight = new Colort(1.5f, 1.5f, 1.5f); }, mouseleave = (e) => { int index = labels.IndexOf(label); int offset = index + offsetindex; QbModel m = Singleton <QbManager> .INSTANCE.ActiveModel; m.matrices[offset].highlight = new Colort(1f, 1f, 1f); } }; button.StatusText = stonevox.StatusText.button_matrixvisibiliy; buttons.Add(button); previouseY -= fontheight; // + (labelspacing).ScaleVerticlSize(); if (hasmodel) { if (labeltext == "") { label.Enable = false; button.Enable = false; button.MaintainEnabled = true; } else { if (model.matrices[i].Visible) { button.Toggle(0); } else { button.Toggle(1); } } } else { label.Enable = false; button.Enable = false; button.MaintainEnabled = true; } } int matrixcount = 10; if (hasmodel) { matrixcount = model.matrices.Count; } scrollbar = new VerticalScrollbar((size.X * .055f).UnScaleHorizontalSize(), size.Y.UnScaleVerticlSize(), matrixcount); scrollbar.fontHeight = size.Y / linecount; scrollbar.UpdateScrollbar(); scrollbar.Parent = this; scrollbar.SetBoundsNoScaling(Absolute_X + size.X - scrollbar.size.X, Absolute_Y); scrollbar.handler = new WidgetEventHandler() { scrollbarchanged = (e, value, delta) => { offsetindex = (int)value; UpdateWidgets(); if (delta > 0) { background.location.Y += (fontheight /*+ (labelspacing).ScaleVerticlSize()*/) * (int)delta; } else { background.location.Y -= (fontheight /* + (labelspacing).ScaleVerticlSize()*/) * -(int)delta; } bool backgroundOutofBounds = true; if (background.Absolute_Y > Absolute_Y + size.Y - fontheight * .5f) { backgroundOutofBounds = false; } else if (background.Absolute_Y < Absolute_Y) { backgroundOutofBounds = false; } background.Enable = backgroundOutofBounds; } }; }
public void write(string path, string name, QbModel model) { string fullpath = Path.Combine(path, name + extension); using (FileStream f = new FileStream(fullpath, FileMode.OpenOrCreate)) { using (BinaryWriter w = new BinaryWriter(f)) { w.Write(model.version); w.Write(model.colorFormat); w.Write(model.zAxisOrientation); w.Write(model.compressed); w.Write(model.visibilityMaskEncoded); w.Write((uint)model.matrices.Count); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; if (!m.Visible) { continue; } int startx = Math.Min(0, m.minx); int starty = Math.Min(0, m.miny); int startz = Math.Min(0, m.minz); int width = (int)(Math.Abs(Math.Min(0, m.minx)) + m.maxx + 1); int height = (int)(Math.Abs(Math.Min(0, m.miny)) + m.maxy + 1); int length = (int)(Math.Abs(Math.Min(0, m.minz)) + m.maxz + 1); if (width < m.size.X) { width = (int)m.size.X; } if (height < m.size.Y) { height = (int)m.size.Y; } if (length < m.size.Z) { length = (int)m.size.Z; } w.Write(m.name); w.Write((uint)width); w.Write((uint)height); w.Write((uint)length); w.Write((int)m.position.X); w.Write((int)m.position.Y); w.Write((int)m.position.Z); if (model.compressed == 0) { Voxel voxel; for (int z = startz; z < startz + length; z++) { for (int y = starty; y < starty + height; y++) { for (int x = startx; x < startx + width; x++) { int zz = model.zAxisOrientation == (int)0 ? z : (int)(length - z - 1); if (m.voxels.TryGetValue(m.GetHash(x, y, zz), out voxel)) { Colort c = m.colors[voxel.colorindex]; int r = (int)(c.R * 255f); int g = (int)(c.G * 255f); int b = (int)(c.B * 255f); w.Write((byte)r); w.Write((byte)g); w.Write((byte)b); w.Write(voxel.alphamask); } else { w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); } } } } } } } } }
public QbModel _read(string path) { QbModel model = new QbModel(path.Split('\\').Last().Split('.').First()); using (FileStream f = new FileStream(path, FileMode.Open)) using (BinaryReader reader = new BinaryReader(f)) { int version = reader.ReadInt32(); int len = reader.ReadInt32(); reader.ReadBytes(len); int colorpalleteflag = reader.ReadInt32(); for (int i = 0; i < 10; i++) { var colorpal = Singleton <GUI> .INSTANCE.Get <EmptyWidget>(GUIID.START_COLOR_SELECTORS + i); var c = colorpal.appearence.Get <PlainBackground>("background"); c.color.R = reader.ReadSingle(); c.color.G = reader.ReadSingle(); c.color.B = reader.ReadSingle(); bool e = (bool)colorpal.customData["active"]; if (e) { Singleton <Broadcaster> .INSTANCE.Broadcast(Message.ColorSelectionChanged, colorpal, c.color); } } model.version = reader.ReadUInt32(); model.colorFormat = reader.ReadUInt32(); model.zAxisOrientation = reader.ReadUInt32(); model.compressed = reader.ReadUInt32(); model.visibilityMaskEncoded = reader.ReadUInt32(); model.setmatrixcount(reader.ReadUInt32()); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; byte l = reader.ReadByte(); m.name = System.Text.Encoding.Default.GetString(reader.ReadBytes(l)); m.setsize((int)reader.ReadUInt32(), (int)reader.ReadUInt32(), (int)reader.ReadUInt32()); m.position = new OpenTK.Vector3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); byte r; byte g; byte b; byte a; int zz; if (model.compressed == 0) { for (int z = 0; z < m.size.Z; z++) { for (int y = 0; y < m.size.Y; y++) { for (int x = 0; x < m.size.X; x++) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); zz = model.zAxisOrientation == (int)0 ? z : (int)(m.size.Z - z - 1); if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } } } else { for (int z = 0; z < m.size.Z; z++) { zz = model.zAxisOrientation == 0 ? z : (int)m.size.Z - z - 1; int index = 0; while (true) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (r == 6 && g == 0 && b == 0 && a == 0) // NEXTSLICEFLAG { break; } else { if (r == 2 && g == 0 && b == 0 && a == 0) //CODEFLAG { uint count = reader.ReadUInt32(); r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (a != 0) { for (int j = 0; j < count; j++) { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } else { index += (int)count; } } else { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } } } } } } return(model); }
public QbModel _read(string path) { QbModel model = new QbModel(path.Split('\\').Last().Split('.').First()); using (FileStream f = new FileStream(path, FileMode.Open)) using (BinaryReader reader = new BinaryReader(f)) { int version = reader.ReadInt32(); int len = reader.ReadInt32(); reader.ReadBytes(len); int colorpalleteflag = reader.ReadInt32(); for (int i = 0; i < 10; i++) { var colorpal = Singleton< GUI >.INSTANCE.Get<EmptyWidget>(GUIID.START_COLOR_SELECTORS + i); var c = colorpal.appearence.Get<PlainBackground>("background"); c.color.R = reader.ReadSingle(); c.color.G = reader.ReadSingle(); c.color.B = reader.ReadSingle(); bool e =(bool)colorpal.customData["active"]; if (e) Singleton<Broadcaster>.INSTANCE.Broadcast(Message.ColorSelectionChanged, colorpal, c.color); } model.version = reader.ReadUInt32(); model.colorFormat = reader.ReadUInt32(); model.zAxisOrientation = reader.ReadUInt32(); model.compressed = reader.ReadUInt32(); model.visibilityMaskEncoded = reader.ReadUInt32(); model.setmatrixcount(reader.ReadUInt32()); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; byte l = reader.ReadByte(); m.name = System.Text.Encoding.Default.GetString(reader.ReadBytes(l)); m.setsize((int)reader.ReadUInt32(), (int)reader.ReadUInt32(), (int)reader.ReadUInt32()); m.position = new OpenTK.Vector3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); byte r; byte g; byte b; byte a; int zz; if (model.compressed == 0) { for (int z = 0; z < m.size.Z; z++) for (int y = 0; y < m.size.Y; y++) for (int x = 0; x < m.size.X; x++) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); zz = model.zAxisOrientation == (int)0 ? z : (int)(m.size.Z - z - 1); if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } else { for (int z = 0; z < m.size.Z; z++) { zz = model.zAxisOrientation == 0 ? z : (int)m.size.Z - z - 1; int index = 0; while (true) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (r == 6 && g == 0 && b == 0 && a == 0) // NEXTSLICEFLAG { break; } else { if (r == 2 && g == 0 && b == 0 && a == 0) //CODEFLAG { uint count = reader.ReadUInt32(); r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (a != 0) { for (int j = 0; j < count; j++) { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } else { index += (int)count; } } else { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } } } } } } return model; }
public void write(string path, string name, QbModel dataType) { Dictionary <int, string> colorlookup = new Dictionary <int, string>(); int colorindex = 0; using (FileStream material = new FileStream(path + "\\" + name + ".mtl", FileMode.OpenOrCreate)) { using (StreamWriter _out = new StreamWriter(material)) { for (int t = 0; t < dataType.matrices.Count; t++) { //color index, to string for usemlt value QbMatrix m = dataType.matrices[t]; if (!m.Visible) { continue; } foreach (var color in m.colors) { float r = color.R; float g = color.G; float b = color.B; if (r < 0.0F) { r = 0.0F; } if (r > 1.0F) { r = 1.0F; } if (r <= 0.03928F) { r /= 12.92F; } else { r = (float)Math.Exp(2.4D * Math.Log((r + 0.055D) / 1.055D)); } if (g < 0.0F) { g = 0.0F; } if (g > 1.0F) { g = 1.0F; } if (g <= 0.03928F) { g /= 12.92F; } else { g = (float)Math.Exp(2.4D * Math.Log((g + 0.055D) / 1.055D)); } if (b < 0.0F) { b = 0.0F; } if (b > 1.0F) { b = 1.0F; } if (b <= 0.03928F) { b /= 12.92F; } else { b = (float)Math.Exp(2.4D * Math.Log((b + 0.055D) / 1.055D)); } if (colorlookup.Values.Contains($"{color.R}_{color.G}_{color.B}")) { continue; } _out.WriteLine("newmtl " + color.R + "_" + color.G + "_" + color.B); _out.WriteLine("illum 0"); _out.WriteLine("Kd " + color.R + " " + color.G + " " + color.B); _out.WriteLine(""); colorlookup.Add(colorindex, $"{color.R}_{color.G}_{color.B}"); colorindex++; } } } } using (FileStream obj = new FileStream(path + "\\" + name + ".obj", FileMode.OpenOrCreate)) { using (StreamWriter _out = new StreamWriter(obj)) { _out.WriteLine($"mtllib {name}.mtl"); Dictionary <int, string> vertexcolors = new Dictionary <int, string>(); int indexcount = 0; int index = 0; for (int t = 0; t < dataType.matrices.Count; t++) { QbMatrix m = dataType.matrices[t]; if (!m.Visible) { continue; } foreach (var c in m.voxels.Values) { if (c.alphamask <= 1) { continue; } float cubesize = .5f; float x = c.x; float y = c.y; float z = c.z; //front if ((c.alphamask & 32) == 32) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //back if ((c.alphamask & 64) == 64) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //top if ((c.alphamask & 8) == 8) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //bottom if ((c.alphamask & 16) == 16) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //left if ((c.alphamask & 2) == 2) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //right if ((c.alphamask & 4) == 4) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } } } index = 0; for (int i = 1; i < indexcount * 4; i += 4) { _out.WriteLine($"usemtl {vertexcolors[index]}"); _out.WriteLine(string.Format("f {0} {1} {2}", i, i + 1, i + 2)); _out.WriteLine(string.Format("f {0} {1} {2}", i, i + 2, i + 3)); index++; } } } }
public void write(string path, string name, QbModel model) { Client.OpenGLContextThread.Add(() => { int Wwidth = Client.window.Width; int Wheight = Client.window.Height; int framebuffer = GL.GenBuffer(); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer); int color = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, color); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, Wwidth, Wheight, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, color, 0); int depth = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, depth); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent24, Wwidth, Wheight, 0, PixelFormat.DepthComponent, PixelType.UnsignedByte, IntPtr.Zero); GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, TextureTarget.Texture2D, depth, 0); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer); GL.DrawBuffers(1, new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0 }); GL.ClearColor(0, 0, 0, 0); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); int minx = 10000; int miny = 10000; int minz = 10000; int maxx = 0; int maxy = 0; int maxz = 0; int sizex = 0; int sizey = 0; int sizez = 0; foreach (var matrix in model.matrices) { if (!matrix.Visible) { continue; } if (matrix.minx < minx) { minx = matrix.minx; } if (matrix.maxx > maxx) { maxx = matrix.maxx; } if (matrix.miny < miny) { miny = matrix.miny; } if (matrix.maxy > maxy) { maxy = matrix.maxy; } if (matrix.minz < minz) { minz = matrix.minz; } if (matrix.maxz > maxz) { maxz = matrix.maxz; } } sizex = maxx - minx; sizey = maxy - miny; sizez = maxz - minz; float backup = 0; if (sizey * 1.5f > 20) { backup = sizey * 1.5f; } else if (sizex * 1.5f > 20) { backup = sizex * 1.5f; } else { backup = 20; } var centerpos = new Vector3((minx + ((maxx - minx) / 2)), (miny + ((maxy - miny) / 2)), (minz + ((maxz - minz) / 2))); var position = centerpos + new Vector3(.5f, sizey * .65f, backup); Vector3 direction; Vector3.Subtract(ref centerpos, ref position, out direction); direction.Normalize(); var cameraright = Vector3.Cross(direction, VectorUtils.UP); var cameraup = Vector3.Cross(cameraright, direction); var view = Matrix4.LookAt(position, position + direction, cameraup); var modelviewprojection = view * Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45), (float)Wwidth / (float)Wheight, 1, 300); Shader voxelShader = ShaderUtil.GetShader("qb"); voxelShader.UseShader(); voxelShader.WriteUniform("modelview", modelviewprojection); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); model.RenderAll(voxelShader); string fullpath = Path.Combine(path, name + extension); using (FileStream f = new FileStream(fullpath, FileMode.OpenOrCreate)) { var bit = Screenshot.ScreenShot(ReadBufferMode.ColorAttachment0); bit = cropImage(bit, new Rectangle(Wwidth / 4, 0, Wwidth - ((Wwidth / 4) * 2), Wheight)); bit = bit.ResizeImage(ResizeKeepAspect(bit.Size, 400, 400)); byte[] buffer = new byte[0]; using (MemoryStream m = new MemoryStream()) { bit.Save(m, System.Drawing.Imaging.ImageFormat.Png); buffer = m.ToArray(); } using (BinaryWriter w = new BinaryWriter(f)) { w.Write(version); w.Write((int)buffer.Length); w.Write(buffer); // note - just in case i allow extending the color pattet // which i probably will w.Write(colorpalletflag); for (int i = 0; i < 10; i++) { var c = Singleton <GUI> .INSTANCE.Get <EmptyWidget>(GUIID.START_COLOR_SELECTORS + i).appearence.Get <PlainBackground>("background").color; w.Write(c.R); w.Write(c.G); w.Write(c.B); } w.Write(model.version); w.Write(model.colorFormat); w.Write(model.zAxisOrientation); w.Write(model.compressed); w.Write(model.visibilityMaskEncoded); w.Write((uint)model.matrices.Count); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; if (!m.Visible) { continue; } int startx = Math.Min(0, m.minx); int starty = Math.Min(0, m.miny); int startz = Math.Min(0, m.minz); int width = (int)(Math.Abs(Math.Min(0, m.minx)) + m.maxx + 1); int height = (int)(Math.Abs(Math.Min(0, m.miny)) + m.maxy + 1); int length = (int)(Math.Abs(Math.Min(0, m.minz)) + m.maxz + 1); if (width < m.size.X) { width = (int)m.size.X; } if (height < m.size.Y) { height = (int)m.size.Y; } if (length < m.size.Z) { length = (int)m.size.Z; } w.Write(m.name); w.Write((uint)width); w.Write((uint)height); w.Write((uint)length); w.Write((int)m.position.X); w.Write((int)m.position.Y); w.Write((int)m.position.Z); if (model.compressed == 0) { Voxel voxel; for (int z = startz; z < startz + length; z++) { for (int y = starty; y < starty + height; y++) { for (int x = startx; x < startx + width; x++) { int zz = model.zAxisOrientation == (int)0 ? z : (int)(length - z - 1); if (m.voxels.TryGetValue(m.GetHash(x, y, zz), out voxel)) { Colort c = m.colors[voxel.colorindex]; w.Write((byte)(c.R * 255)); w.Write((byte)(c.G * 255)); w.Write((byte)(c.B * 255)); w.Write(voxel.alphamask); } else { w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); } } } } } } } GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); GL.DeleteTexture(color); GL.DeleteTexture(depth); GL.DeleteFramebuffer(framebuffer); } }); }
public void write(string path, string name, QbModel dataType) { Dictionary<int, string> colorlookup = new Dictionary<int, string>(); int colorindex = 0; using (FileStream material = new FileStream(path + "\\" + name + ".mtl", FileMode.OpenOrCreate)) { using (StreamWriter _out = new StreamWriter(material)) { for (int t = 0; t < dataType.matrices.Count; t++) { //color index, to string for usemlt value QbMatrix m = dataType.matrices[t]; if (!m.Visible) continue; foreach (var color in m.colors) { float r = color.R; float g = color.G; float b = color.B; if (r < 0.0F) { r = 0.0F; } if (r > 1.0F) { r = 1.0F; } if (r <= 0.03928F) { r /= 12.92F; } else { r = (float)Math.Exp(2.4D * Math.Log((r + 0.055D) / 1.055D)); } if (g < 0.0F) { g = 0.0F; } if (g > 1.0F) { g = 1.0F; } if (g <= 0.03928F) { g /= 12.92F; } else { g = (float)Math.Exp(2.4D * Math.Log((g + 0.055D) / 1.055D)); } if (b < 0.0F) { b = 0.0F; } if (b > 1.0F) { b = 1.0F; } if (b <= 0.03928F) { b /= 12.92F; } else { b = (float)Math.Exp(2.4D * Math.Log((b + 0.055D) / 1.055D)); } if (colorlookup.Values.Contains($"{color.R}_{color.G}_{color.B}")) continue; _out.WriteLine("newmtl " + color.R + "_" + color.G + "_" + color.B); _out.WriteLine("illum 0"); _out.WriteLine("Kd " +color.R + " " +color.G + " " + color.B); _out.WriteLine(""); colorlookup.Add(colorindex, $"{color.R}_{color.G}_{color.B}"); colorindex++; } } } } using (FileStream obj = new FileStream(path + "\\" + name + ".obj", FileMode.OpenOrCreate)) { using (StreamWriter _out = new StreamWriter(obj)) { _out.WriteLine($"mtllib {name}.mtl"); Dictionary<int, string> vertexcolors = new Dictionary<int, string>(); int indexcount = 0; int index = 0; for (int t = 0; t < dataType.matrices.Count; t++) { QbMatrix m = dataType.matrices[t]; if (!m.Visible) continue; foreach (var c in m.voxels.Values) { if (c.alphamask <= 1) continue; float cubesize = .5f; float x = c.x; float y = c.y; float z = c.z; //front if ((c.alphamask & 32) == 32) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //back if ((c.alphamask & 64) == 64) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //top if ((c.alphamask & 8) == 8) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //bottom if ((c.alphamask & 16) == 16) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //left if ((c.alphamask & 2) == 2) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", cubesize + x, -cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } //right if ((c.alphamask & 4) == 4) { indexcount++; _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, -cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, -cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, cubesize + z)); _out.WriteLine(string.Format("v {0} {1} {2}", -cubesize + x, cubesize + y, -cubesize + z)); Colort color = m.colors[c.colorindex]; vertexcolors.Add(index, $"{color.R}_{color.G}_{color.B}"); index++; } } } index = 0; for (int i = 1; i < indexcount * 4; i += 4) { _out.WriteLine($"usemtl {vertexcolors[index]}"); _out.WriteLine(string.Format("f {0} {1} {2}", i, i + 1, i + 2)); _out.WriteLine(string.Format("f {0} {1} {2}", i, i + 2, i + 3)); index++; } } } }
public QbModel _read(string path) { QbModel model = new QbModel(path.Split('\\').Last().Split('.').First()); using (FileStream f = new FileStream(path, FileMode.Open)) using (BinaryReader reader = new BinaryReader(f)) { model.version = reader.ReadUInt32(); model.colorFormat = reader.ReadUInt32(); model.zAxisOrientation = reader.ReadUInt32(); model.compressed = reader.ReadUInt32(); model.visibilityMaskEncoded = reader.ReadUInt32(); model.setmatrixcount(reader.ReadUInt32()); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; byte l = reader.ReadByte(); m.name = System.Text.Encoding.Default.GetString(reader.ReadBytes(l)); m.setsize((int)reader.ReadUInt32(), (int)reader.ReadUInt32(), (int)reader.ReadUInt32()); m.position = new OpenTK.Vector3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); byte r; byte g; byte b; byte a; int zz; if (model.compressed == 0) { for (int z = 0; z < m.size.Z; z++) for (int y = 0; y < m.size.Y; y++) for (int x = 0; x < m.size.X; x++) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); zz = model.zAxisOrientation == (int)0 ? z : (int)(m.size.Z - z - 1); if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } else { for (int z = 0; z < m.size.Z; z++) { zz = model.zAxisOrientation == 0 ? z : (int)m.size.Z - z - 1; int index = 0; while (true) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (r == 6 && g == 0 && b == 0 && a == 0) // NEXTSLICEFLAG { break; } else { if (r == 2 && g == 0 && b == 0 && a == 0) //CODEFLAG { uint count = reader.ReadUInt32(); r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (a != 0) { for (int j = 0; j < count; j++) { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } else { index += (int)count; } } else { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } } } } } } return model; }
public QbModel _read(string path) { QbModel model = new QbModel(path.Split('\\').Last().Split('.').First()); using (FileStream f = new FileStream(path, FileMode.Open)) using (BinaryReader reader = new BinaryReader(f)) { model.version = reader.ReadUInt32(); model.colorFormat = reader.ReadUInt32(); model.zAxisOrientation = reader.ReadUInt32(); model.compressed = reader.ReadUInt32(); model.visibilityMaskEncoded = reader.ReadUInt32(); model.setmatrixcount(reader.ReadUInt32()); for (int i = 0; i < model.numMatrices; i++) { QbMatrix m = model.matrices[i]; byte l = reader.ReadByte(); m.name = System.Text.Encoding.Default.GetString(reader.ReadBytes(l)); m.setsize((int)reader.ReadUInt32(), (int)reader.ReadUInt32(), (int)reader.ReadUInt32()); m.position = new OpenTK.Vector3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); byte r; byte g; byte b; byte a; int zz; if (model.compressed == 0) { for (int z = 0; z < m.size.Z; z++) { for (int y = 0; y < m.size.Y; y++) { for (int x = 0; x < m.size.X; x++) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); zz = model.zAxisOrientation == (int)0 ? z : (int)(m.size.Z - z - 1); if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } } } else { for (int z = 0; z < m.size.Z; z++) { zz = model.zAxisOrientation == 0 ? z : (int)m.size.Z - z - 1; int index = 0; while (true) { r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (r == 6 && g == 0 && b == 0 && a == 0) // NEXTSLICEFLAG { break; } else { if (r == 2 && g == 0 && b == 0 && a == 0) //CODEFLAG { uint count = reader.ReadUInt32(); r = reader.ReadByte(); g = reader.ReadByte(); b = reader.ReadByte(); a = reader.ReadByte(); if (a != 0) { for (int j = 0; j < count; j++) { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } else { index += (int)count; } } else { int x = index % (int)m.size.X; int y = index / (int)m.size.X; index++; if (a != 0) { m.voxels.GetOrAdd(m.GetHash(x, y, zz), new Voxel(x, y, zz, a, m.getcolorindex(r, g, b, model.colorFormat))); } } } } } } } } return(model); }