Jump to content
Xtreme .Net Talk

Reidar Lange

Members
  • Posts

    16
  • Joined

  • Last visited

Personal Information

  • Visual Studio .NET Version
    Visual Studio .NET Professional
  • .NET Preferred Language
    C#

Reidar Lange's Achievements

Newbie

Newbie (1/14)

0

Reputation

  1. Calculating intersection points // Assuming that you have the intersectInformation object ready: float u = intersectInformation.intersectInformation.U; float v = intersectInformation.intersectInformation.V; // The intersection point in model space Vector3 IntersectionPoint = (1-u-v)*intersectInformation.triangle[0]+ u*intersectInformation.triangle[1]+ v*intersectInformation.triangle[2]; // The intersection point in real world Vector3 IntersectionPointRealWorld = IntersectionPoint; IntersectionPointRealWorld.TransformCoordinate(device.Transform.World);
  2. You might find a solution if you used hash tables. I guess you have full control over all your text boxes. In that case you could loop trough them (only once) and put them in a hashtable with the controls name as the key. Below is a full example of what I mean: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace HTControls { /// <summary> /// Summary description for Form1. /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.TextBox textBox3; System.Collections.Hashtable ht = new Hashtable(); private System.Windows.Forms.Button button1; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // ht[textBox1.Name]=textBox1; ht[textBox2.Name]=textBox2; ht[textBox3.Name]=textBox3; } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.textBox3 = new System.Windows.Forms.TextBox(); this.button1 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(48, 24); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(168, 20); this.textBox1.TabIndex = 0; this.textBox1.Text = "textBox1"; // // textBox2 // this.textBox2.Location = new System.Drawing.Point(48, 48); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(168, 20); this.textBox2.TabIndex = 1; this.textBox2.Text = "textBox2"; // // textBox3 // this.textBox3.Location = new System.Drawing.Point(48, 72); this.textBox3.Name = "textBox3"; this.textBox3.Size = new System.Drawing.Size(168, 20); this.textBox3.TabIndex = 2; this.textBox3.Text = "textBox3"; // // button1 // this.button1.Location = new System.Drawing.Point(96, 112); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(64, 32); this.button1.TabIndex = 3; this.button1.Text = "Action"; this.button1.Click += new System.EventHandler(this.button1_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.button1); this.Controls.Add(this.textBox3); this.Controls.Add(this.textBox2); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion /// <summary> /// The main entry point for the application. /// </summary> [sTAThread] static void Main() { Application.Run(new Form1()); } private void button1_Click(object sender, System.EventArgs e) { TextBox tb = (TextBox)ht[textBox1.Text]; tb.Text = "Text added by indirection"; } } } textboxbyindirection.bmp
  3. To add relations in a dataset you have twoo options: 1. You can use a typed dataset and add both tables ans relations in the dataset designer that comes with visual studio. (There is even a faste way to update typed datasets - that is if you have defined the adapters in the designer instead of by hand. Then you can right click on the adapter and select create dataset.... 2. You can add realtions programatically. use the dataset.Relations.Add method and look up System.Data.DataRelation in the help docs. Having set up the dataset, you can call DataRow.GetChildRows Example from vs helpdocs: private void GetChildRowsFromDataRelation(DataTable myTable ) { DataRow[] arrRows; foreach(DataRelation myRelation in myTable.ChildRelations){ foreach(DataRow myRow in myTable.Rows){ arrRows = myRow.GetChildRows(myRelation, DataRowVersion.Proposed); // Print values of rows. for(int i = 0; i < arrRows.Length; i++){ foreach(DataColumn myColumn in myTable.Columns){ Console.WriteLine(arrRows[i][myColumn]); } } } } } The coding is even easier if you have a typed dataset. You realy should check that out. It's very neat. Hope this helps. If you are stuck still. Pleas let me know and I'll dig up some example code for you.
  4. The simplest soulution is often the best. Very good point :) You are quite right, but what if I want the mesh to be even more transparent than what you see on the snapshot, but not completely gone ? I have tried to fiddle with different alpha settings, but this is the best I could come up with.
  5. In the render method I use this: device.RenderState.Lighting = true; device.RenderState.Ambient = Color.FromArgb(100,100,100); device.RenderState.ZBufferEnable = true; device.RenderState.CullMode = Cull.CounterClockwise; device.RenderState.ShadeMode = ShadeMode.Gouraud; device.RenderState.FillMode = FillMode.Solid; device.RenderState.AlphaBlendEnable = true; device.RenderState.AlphaSourceBlend = Blend.SourceAlpha; device.RenderState.DestinationBlend = Blend.InvSourceAlpha; device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse; device.TextureState[0].AlphaArgument1 = TextureArgument.Diffuse; device.TextureState[0].AlphaArgument2 = TextureArgument.TextureColor; device.TextureState[0].AlphaOperation = TextureOperation.BlendFactorAlpha; device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = Color.FromArgb(0,200,200,200); device.Lights[0].Specular = Color.White; device.Lights[0].Direction = new Vector3((float)Math.Cos((float) device.Lights[0].Commit();//let d3d know about the light device.Lights[0].Enabled = true; Then I set the material color to argb(0,255,255,255) for one of the rendered meshes. I trun off alpha blending for all except one. The question is: When I set the alpha channel to 0, I would expect the transparent mesh to dissapear completely. Why does it not ? transparent.bmp
  6. Here is an example of how to create a textured sphere: (Se the attached bitmap). /// <summary> /// Creates a PositionNormalTextured sphere /// </summary> /// <param name="device">The current direct3D drawing device.</param> /// <param name="radius">The sphere's radius</param> /// <param name="slices">Number of slices (Horizontal resolution).</param> /// <param name="stacks">Number of stacs. (Vertical resolution)</param> /// <returns></returns> /// <remarks> /// Number of vertices in the sphere will be (slices+1)*(stacks+1)<br/> /// Number of faces :slices*stacks*2 /// Number of Indexes : Number of faces * 3; /// </remarks> public static Direct3D.Mesh TexturedSphere(Device device, float radius, int slices, int stacks) { int numVertices = (slices+1)*(stacks+1); int numFaces = slices*stacks*2; int indexCount = numFaces * 3;// numVertices + (slices-1)*(stacks); Mesh mesh = new Mesh(numFaces,numVertices,MeshFlags.Managed,CustomVertex.PositionNormalTextured.Format,device); // Get the original sphere's vertex buffer. int [] ranks = new int[1]; ranks[0] = mesh.NumberVertices; System.Array arr = mesh.VertexBuffer.Lock(0,typeof(CustomVertex.PositionNormalTextured),LockFlags.None,ranks); // Set the vertex buffer int vertIndex=0; for(int slice=0;slice<=slices;slice++) { float alphaY = (float)slice/slices*(float)Math.PI*2.0f; // Angel around Y-axis for(int stack=-(stacks+1)/2;stack<=(stacks+1)/2;stack++) { Direct3D.CustomVertex.PositionNormalTextured pnt = new CustomVertex.PositionNormalTextured(); float alphaZ = (float)stack/stacks*(float)Math.PI*1.0f; // Angel around Z-axis. pnt.X = (float)(Math.Cos(alphaY)*radius/2.0f)*(float)Math.Cos(alphaZ); pnt.Z = (float)(Math.Sin(alphaY)*radius/2.0f)*(float)Math.Cos(alphaZ); pnt.Y = (float)(Math.Sin(alphaZ)*radius/2.0f); pnt.Tu = pnt.X/radius; pnt.Tv = 0.5f - pnt.Y/radius; arr.SetValue(pnt,vertIndex++); } } mesh.VertexBuffer.Unlock(); ranks[0]=indexCount; arr = mesh.LockIndexBuffer(typeof(short),LockFlags.None,ranks); int i=0; short leftVertex = 0; short rightVertex = 0; for(short x=0;x<slices;x++) { leftVertex = (short)((stacks+1)*x); rightVertex = (short)(leftVertex + stacks + 1); for(int y=0;y<stacks;y++) { arr.SetValue(rightVertex,i++); arr.SetValue(leftVertex,i++); arr.SetValue((short)(leftVertex+1),i++); arr.SetValue(rightVertex,i++); arr.SetValue((short)(leftVertex+1),i++); arr.SetValue((short)(rightVertex+1),i++); leftVertex++; rightVertex++; } } mesh.IndexBuffer.SetData(arr,0,LockFlags.None); mesh.ComputeNormals(); return mesh; } TexturedSphere.bmp
  7. Example of converting the Mesh.Box to a textured mesh. This function shows an example: /// <summary> /// Creates a textured box from the Mesh.Box method. Texture coordinates = x, and y values shifted by halve length and height. /// texture y-coordinate is inverted. /// </summary> /// <param name="device">The device used for rendering.</param> /// <param name="width">Width of the box.</param> /// <param name="height">Height of the box.</param> /// <param name="depth">Depth of the box.</param> /// <returns>A box mesh with textured coordinates.</returns> public static Direct3D.Mesh TexturedBox(Direct3D.Device device, float width, float height, float depth) { GraphicsStream adjacency; Mesh box = Mesh.Box(device,width,height,depth,out adjacency); Mesh texturedBox = new Mesh(box.NumberFaces,box.NumberVertices,MeshFlags.Managed,CustomVertex.PositionNormalTextured.Format,device); // Get the original box's vertex buffer. int [] ranks = new int[1]; ranks[0] = box.NumberVertices; System.Array arr = box.VertexBuffer.Lock(0,typeof(CustomVertex.PositionNormal),LockFlags.None,ranks); // Set the vertex buffer using(VertexBuffer vb = texturedBox.VertexBuffer) { System.Array data = vb.Lock(0,typeof(CustomVertex.PositionNormalTextured),LockFlags.None,ranks); for(int i=0;i<arr.Length;i++) { Direct3D.CustomVertex.PositionNormal pn = (CustomVertex.PositionNormal)arr.GetValue(i); Direct3D.CustomVertex.PositionNormalTextured pnt = (CustomVertex.PositionNormalTextured)data.GetValue(i); pnt.X = pn.X; pnt.Y = pn.Y; pnt.Z = pn.Z; pnt.Nx = pn.Nx; pnt.Ny = pn.Ny; pnt.Nz = pn.Nz; pnt.Tu = pnt.X+width/2; pnt.Tv = 1.0f-pnt.Y+height/2; data.SetValue(pnt,i); } vb.Unlock(); box.VertexBuffer.Unlock(); } // Set the index buffer. ranks[0] = box.NumberFaces * 3; arr = box.LockIndexBuffer(typeof(short),LockFlags.None,ranks); texturedBox.IndexBuffer.SetData(arr,0,LockFlags.None); return texturedBox; } I quess you could do similar things with the other basic Mesh figures. The clue here is how to calculate the texture coordinates. For a cylinder you could let the Tv be a function of the Z coordinates, while the Tu describes where the point is on the circle sorounding the cylinder. Speres could also be delt vith in terms of cos and sin functions.
  8. Found a solution! The following code creates a 0-digit mesh and scales all vertixes down by 50% Mesh m = Mesh.TextFromFont(device,font,"0",1f,0.1f,ref glyph); int [] ranks = new int[1]; ranks[0] = m.NumberVertices; System.Array arr = m.VertexBuffer.Lock(0,typeof(CustomVertex.PositionNormal),LockFlags.None,ranks); for(int i=0;i<arr.Length;i++) { Direct3D.CustomVertex.PositionNormal pn = (CustomVertex.PositionNormal)arr.GetValue(i); pn.X *= 0.5f; pn.Y *= 0.5f; pn.Z *= 0.5f; arr.SetValue(pn,i); } m.VertexBuffer.Unlock();
  9. Does anyone know how to control the size of the resulting mesh when you use Mesh.TextFromFont(). System.Drawing.Font font = new System.Drawing.Font("Arial",1.0f,GraphicsUnit.Millimeter); GlyphMetricsFloat [] glyph = new GlyphMetricsFloat[1]; Mesh m = Mesh.TextFromFont(device,font,"8",1f,0.1f,ref glyph); Setting the font size does not change anything. One solution would be to aply scaling to the world transform before rendering, but that has a tendency to do strange things with 3d lighting.
  10. OK, but thanks anyway. By the way; I have found out that the code example can be simplified: Surface renderTarget = device.GetRenderTarget(0); SurfaceLoader.Save(@"c:\temp\test.bmp",ImageFileFormat.Bmp,renderTarget); I said earlier that the code could be executed before device.Present(). Infact it should be.... You do not know how many hours I have spent in search for this solution. Just look at the beauty. It realy is quite different than the c++ sniplet I started out with.
  11. Sub routines vs functions. In most procedural languages you can think of a sub routine as a function with no parameters that does not return any values. Infact, in some languages like c c++ c# and so on the term sub routine does not exist at all. It's all about functions. Sub-routines does not return any values. Functions does. Both may have parameters. A "sub routine" like function in c# would be declared as: void my_function() { // Do some stuff here. } A function (that returns data) could be some thing like this: int my_function() { // Do some stuff here. return 5; } In vb you use sub if you do not need any return values. Some time ago i did a lot of programming in Microsoft Access VB. I dont know if it was me or a part of the VB standard but I could not make subs with more than one parameter to work. Instead I had to work around by declearing it as a function. Then i worked. Wierd.......... I have been a programmer for more than 20 years and I have seen a lot of different programming languages. My first experience was with ZX Spectrums BASIC. The basic languages from back then is one of the ancestors of modern VB, but you would probably not see any resemblences. In those days the term "function" did not exist. We did not even have subs. The only thing we could use was the GOSUB statement, making sure some global variables was set before the call. Later we got declarations for subs and functions, but my guess is that subs have survived because of old habits. There is no real nead for destinguishing between subs and functions.
  12. Normally an xml-fil will start with <?xml version="1.0" encoding="UTF-8"?>, but it does not have to. To comply with rules of "wellformedness" an xml-file must have one root node, probably the EXPORT tag in your case and some child nodes, typically with their own child nodes. You can think of it as something like a directory structure. (Wellformedness requiers some other properties as well). xslt is short for xml style sheets. An xslt is in it self xml data but describes how som other xml-code should be transformed (maybe to another xml). To make the xml transformation work you must have an xml tranformation processor, lik the one found in .NET XmlTranformation class. If you have some programming capabilities, it should be easy to write some code to parse and extract the information you need from the xml-file. After all, this is one of the key ideas behind xml - It should be easy to write xml parsers. In the .NET environment there is plenty of logic handling reading, modifying and writing xml files.
  13. Pick a mesh. I have resently done som work on this subject and here is a synopsis of what i have come up with so far. But first a cuppleo warnings: 1. The code here is not tested as is. I have cut it out from various places in my source code, so you may have to play with it to actual make it work. 2. The code relays strongly on what others have writen, so if you recognize this as your own work, you may be right. 3. After rereading your question I see that there is a missing part here. How to do something with the selected face (hide it or something) can be seen in the sdk's pick sample. It is written in C++ but you should be able to work out the missing pieces. Picking meshes can be acomplished in the folowing steps: Let's say the mouse is located in point 100,200 on screen: 1. Transform this coordinate in the range -1 , +1 for x and -1 , +1 for y, y - axis are inverted. In adition the projection matrix must be takent into acount: --------------------------------------------------------------------------------------------- Matrix matProj = device.GetTransform(TransformType.Projection); Vector3 screenVector = new Vector3(( ( ( 2.0f * screenX ) / this.ClientRectangle.Width ) - 1) / matProj.M11,-( ( ( 2.0f * screenY ) / this.ClientRectangle.Height ) - 1) / matProj.M22,1.0f); -------------------------------------------------------------------------------------------- This first step has to be done once each time you start intersection testing in the scene. The remaining steps must be done for each mesh. 2. Calculate a ray defined by the camaraposition and a direction vector such that it gos trough the actual point on the screen. The World transform is the same transform that is used to "place" the mesh in the 3D-world, so this, and the remaining steps must be done for each mesh. --------------------------------------------------------------------------------------------- Matrix m = device.Transform.World * device.Transform.View; m.Invert(); // Transform the screen space pick ray into 3D space Vector3 vPickRayDir = new Vector3(0,0,0); Vector3 vPickRayOrig = new Vector3(0,0,0); startPoint = Vector3.Empty; direction = Vector3.Empty; direction.X = screenVector.X*m.M11 + screenVector.Y*m.M21 + screenVector.Z*m.M31; direction.Y = screenVector.X*m.M12 + screenVector.Y*m.M22 + screenVector.Z*m.M32; direction.Z = screenVector.X*m.M13 + screenVector.Y*m.M23 + screenVector.Z*m.M33; startPoint.X = m.M41; startPoint.Y = m.M42; startPoint.Z = m.M43; --------------------------------------------------------------------------------------------- 3. Test intersection for mesh of interest: --------------------------------------------------------------------------------------------- IntersectInformation closestHit = new IntersectInformation(); if(mesh.Intersect(startPoint,direction,ref closestHit)) { // Intersection found. For example closestHit.Dest will tell you how close // the mesh is from camera. } --------------------------------------------------------------------------------------------- If you want to do intersection test on triangles this can be acheaved by Geometry.IntersectTri() The intersectionInformation object have information about whitch face has been selected. This will be 3 Vector3 objects. They will be in model space. Along with the 3 points, the IntersectInformation object also contains a u,v pair that can be used to calculate the exact intersection point: If we say that the tree points are v0, v1 and V3, then the intersection point will be: Vector3 vIntersection = (1-u-v)*v0+u*v1+v*v2; The vIntersection will be in model space. To convert it to real world space you can do the following: Vector3 vIntersectionRealWorld = vIntersection; vIntersectionPointRealWorld.TransformCoordinate(device.GetTransform(TransformType.World)); Thats it for now. Hope this helps.
  14. You are hereby declared as HERO I was not able to make TextureLoader work but you put me on the track that lead me right to the solution! Here is the code that takes a snapshot from the current suface and saves it to the disk (can be executed before Device.Present()): ------------------------------------------------------------------------------------------- Surface renderTarget = device.GetRenderTarget(0); Surface destTarget = device.CreateOffscreenPlainSurface(ClientRectangle.Width,ClientRectangle.Height,graphicsSettings.WindowedDisplayMode.Format,Pool.SystemMemory); device.GetRenderTargetData(renderTarget,destTarget); SurfaceLoader.Save(@"c:\temp\test.bmp",ImageFileFormat.Bmp,destTarget); ------------------------------------------------------------------------------------------- You have saved my day!!!!!!!!!!!!!!!
×
×
  • Create New...