Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Go Back  Xtreme Visual Basic Talk > > > Exploring 3D graphics with VB.Net, but without using DirectX or XNA


Reply
 
Thread Tools Display Modes
  #101  
Old 04-23-2015, 12:46 PM
PlausiblyDamp's Avatar
PlausiblyDampExploring 3D graphics with VB.Net, but without using DirectX or XNA PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,056
Default


The ISerializable interface and the <Serializable> attribute will only be used with XML if you are using the SoapFormatter to serialise the objects.

If you are interested in having more control over the XML then you could always use the XmlSerializer class. This allow you to have more control over the format of the XML by annotating the underlying classes with attributes. That link should have some examples of these.

If you want to be more specific in the objects you want to write out then you may find serialization in any form too blunt a tool, you might need to write code to handle eactly what is written. Depending on the version of .Net you are targeting the XML Linq support might be the easiest option as it allows a lot of control while reading and writing without too much code bloat.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #102  
Old 04-25-2015, 12:14 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Serialization blues and working vb.net 2010 delaunay triangulation demo

Quote:
Originally Posted by PlausiblyDamp
If you are interested in having more control over the XML then you could always use the XmlSerializer class. This allow you to have more control over the format of the XML by annotating the underlying classes with attributes. That link should have some examples of these.
Yes I looked at that, but none of the examples was what I needed.
It would be nice if they had a wizard or something inside the IDE..

Dumping the need to do voronoi generation, attached is a working VB.Net code demo for generating 2D Delaunay Triangulation,
(as well a working attachment of some off form render 3D code I was testing..)



Quote:
Edit1:
I did a search of the forum for "delaunay" and guess which is the only thread in the VB.Net part of the forum?

So I guess I would be re-miss if I didn't really explain their are a number of different algorithms to do such triangulation and, although it's pretty obvious, I should mention it's based on the Bowyer–Watson algorithm.

The algorithm, (quoting the linked to Wikipedia page), "can be used to obtain a Voronoi diagram of the points, which is the dual graph of the Delaunay triangulation."
Ooooooh..yes, I'm coveting Voronoi diagramming!
(also known as "Direchlet tesselation", named after this guy.)

I don't think this would be the most efficient algorithm for 3D, but it could be applied after the 3d-to-2D projection.

The other popular 2D Voronoi algorithm I saw (when researching) was called "Fortune's".

As this phd thesis pdf points out there are mainly voronoi producing algorithms that lend themselves to massive parallelism.



It's so frustrating to me that over the years people have spend so much time asking to have their code fixed
and not enough time posting some working code based on one algorithm and then asking how to do an implementation based on a better algorithm.





On the topic of "data waiting for a good algorithmic approach", I guess I should also mention today is World Malaria Day.

For decades data that could have used to prevent the spread of malaria has been (was) locked away (languished) in government vaults in South Dakota.

Then some Phd-guy named Sturrock (an "MEI Spatial Epidemiologist") worked with Rebecca Moorse and the Google Earth Engine team to develop a malaria map to help point to where there’s a need for insecticide-treated bed nets to keep out mosquitoes (as part of the U.N. Foundation's "Nothing But Nets" initiative).

In this PBS Newshour segment, after explaining:
"Sturrock, with the power of thousands of Google’s computers at his fingertips,
is combining the satellite pictures with on-the-ground information, using algorithms. "
..it felt compelled to add (for the laymen/non-programmers):
"An algorithm is nothing more than a recipe."

Of course I'm sure everyone reading through this thread already knows that!

But the importance of algorithms is not only that they are attractive for coders (because can be used to produce better/faster/leaner code),
but also because they can (quite literally) save lives.
Attached Files
File Type: zip DelaunayTriangulation.zip (602.3 KB, 20 views)
File Type: zip !_off_form_3D_render_test.zip (208.5 KB, 23 views)

Last edited by dotnetwrassler; 04-25-2015 at 07:35 AM.
Reply With Quote
  #103  
Old 05-02-2015, 08:51 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Post-hiatus..

So if I am going to be filling triangles (including 3D triangle faces),
I've got to find some VB.Net code that is designed to work with specifically with triangles.

However if you search the MSDN for Triangle fill routines/examples you are not going to find much.

Because triangle-related code isn't referenced under "triangles".
Eventually (after much googling) you generally come to realize
that triangles are considered (for coding purposes) as a special case of the Polygon class.

Even knowing that will only get you a limited set of examples.

So what did I come up with for this week?
Look below and you'll see I reached my 5 attachment limit this week.

Some misc (semi-related) reference links:
The "Fill Polygon With Image - Stretch to fit" social.msdn thread featuring Paul Ishak and Thorsten Gudera.

The attachment below is a "cleaned-up" version of their code demo.
It's limitations and "features":
1.) It uses a custom canvas control (unnecessary).
2.) The code will generate a divide by zero error if you carefully bring
together
the two red drag handles on the top of the picture-image quad
so they lie exactly atop one another (at/on the same point)
3.) If you look closely at the screenshot attached below
where the line art texture gets pinched at the top
(as the two upper points red drag points are brought together),
you'll notice some discontinuities in the lines of the graphic.

However their interpolation code is somewhat of an alternative to the existing/working pixel lerping code
in the attachment to posts #9 and #18 of this thread.
Code:
Private Function getTransformedBitmap() As Bitmap
  If srcH = 0 OrElse srcW = 0 Then
   Return Nothing
  End If
  Dim destCB As New ImageData()
  destCB.A = New Byte(rect.Width - 1, rect.Height - 1) {}
  destCB.B = New Byte(rect.Width - 1, rect.Height - 1) {}
  destCB.G = New Byte(rect.Width - 1, rect.Height - 1) {}
  destCB.R = New Byte(rect.Width - 1, rect.Height - 1) {}
     Dim ptInPlane As New PointF()
     Dim x1 As Integer, x2 As Integer, y1 As Integer, y2 As Integer
     Dim dab As Double, dbc As Double, dcd As Double, dda As Double
     Dim dx1 As Single, dx2 As Single, dy1 As Single, _
          dy2 As Single, dx1y1 As Single, dx1y2 As Single, _
	  dx2y1 As Single, dx2y2 As Single, nbyte As Single
      For y As Integer = 0 To rect.Height - 1
       For x As Integer = 0 To rect.Width - 1
	 Dim srcPt As New Point(x, y)
	 srcPt.Offset(Me.rect.Location)
	 If isOnPlaneABCD(srcPt) Then
	   dab = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(0), srcPt)).CrossProduct(AB))
	   dbc = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(1), srcPt)).CrossProduct(BC))
	   dcd = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(2), srcPt)).CrossProduct(CD))
	   dda = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(3), srcPt)).CrossProduct(DA))
	   ptInPlane.X = CSng(srcW * (dda / (dda + dbc)))
	   ptInPlane.Y = CSng(srcH * (dab / (dab + dcd)))
	   x1 = CInt(Math.Truncate(ptInPlane.X))
	   y1 = CInt(Math.Truncate(ptInPlane.Y))
	   If x1 >= 0 AndAlso x1 < srcW AndAlso y1 >= 0 AndAlso y1 < srcH Then
	    If isBilinear Then
             x2 = If((x1 = srcW - 1), x1, x1 + 1)
	     y2 = If((y1 = srcH - 1), y1, y1 + 1)
	     dx1 = ptInPlane.X - CSng(x1)
	     If dx1 < 0 Then
              dx1 = 0
	     End If
             dx1 = 1.0F - dx1
	     dx2 = 1.0F - dx1
	     dy1 = ptInPlane.Y - CSng(y1)
	     If dy1 < 0 Then
	       dy1 = 0
             End If
	     dy1 = 1.0F - dy1
	     dy2 = 1.0F - dy1
	     dx1y1 = dx1 * dy1
	     dx1y2 = dx1 * dy2
	     dx2y1 = dx2 * dy1
	     dx2y2 = dx2 * dy2
 	     nbyte = srcCB.A(x1, y1) * dx1y1 + srcCB.A(x2, y1) * dx2y1 + srcCB.A(x1, y2) * dx1y2 + srcCB.A(x2, y2) * dx2y2
             destCB.A(x, y) = CByte(Math.Truncate(nbyte))
	     nbyte = srcCB.B(x1, y1) * dx1y1 + srcCB.B(x2, y1) * dx2y1 + srcCB.B(x1, y2) * dx1y2 + srcCB.B(x2, y2) * dx2y2
	     destCB.B(x, y) = CByte(Math.Truncate(nbyte))
      	     nbyte = srcCB.G(x1, y1) * dx1y1 + srcCB.G(x2, y1) * dx2y1 + srcCB.G(x1, y2) * dx1y2 + srcCB.G(x2, y2) * dx2y2
	     destCB.G(x, y) = CByte(Math.Truncate(nbyte))
	     nbyte = srcCB.R(x1, y1) * dx1y1 + srcCB.R(x2, y1) * dx2y1 + srcCB.R(x1, y2) * dx1y2 + srcCB.R(x2, y2) * dx2y2
	     destCB.R(x, y) = CByte(Math.Truncate(nbyte))
           Else
	     destCB.A(x, y) = srcCB.A(x1, y1)
	     destCB.B(x, y) = srcCB.B(x1, y1)
	     destCB.G(x, y) = srcCB.G(x1, y1)
	     destCB.R(x, y) = srcCB.R(x1, y1)
	   End If
	 End If
       End If
     Next
   Next
  Return destCB.ToBitmap()
End Function
http://www.vb-helper.com/howto_net_l...ent_brush.html

Code Listing 9.7 - "Clipping with the Region Class" is to be found on this page.

There is a "triangle_fill_examples.zip" (that shows custom colorblending fills) attached to this post.

Also of triangulation note:
"Break a polygon into triangles in VB.NET":
http://www.vb-helper.com/howto_net_p...iangulate.html


Code hint: To get the cube faces to show a rainbow gradient (as in the screenshot below)
instead of just seeing the rainbow gradient on the tetrahedron faces in the center of the cube,
you have to disable the "faces with text" rendering by
commenting out (in the Form2_Pain sub) these lines:
Code:
If Cube1.Faces.Contains(face) Then
' RenderCubeFaceWithText(g, face)
'Else
	face.Paint(g)
End If
I noticed boops boops' read only bounds property (in the Face3D class)
was being used for anything so, it came in handy to use for this code:
Code:
Public Overridable Sub Paint(g As Graphics)
	Dim clr As Color
	If Me.FrontPresentation Then
		clr = FillColor
	Else
		clr = FillColorBack
	End If

	Using br As New LinearGradientBrush( _
			bounds, Color.Blue, Color.White, 0.0F)
		' Create a ColorBlend object. 
		Dim ColorBlend As New ColorBlend()
		Dim intAlpha As Integer = 128
		ColorBlend.Colors = New Color() _
		{ _
		  Color.FromArgb(intAlpha, 255, 0, 0), _
		  Color.FromArgb(intAlpha, 255, 165, 0), _
		  Color.FromArgb(intAlpha, 255, 255, 0), _
		  Color.FromArgb(intAlpha, 0, 255, 0), _
		  Color.FromArgb(intAlpha, 0, 0, 255), _
		  Color.FromArgb(intAlpha, 75, 0, 130), _
		  Color.FromArgb(intAlpha, 128, 0, 128) _
		}
		ColorBlend.Positions = New Single() _
		{ _
		   0.0F, 1 / 6.0F, 2 / 6.0F, 3 / 6.0F, 4 / 6.0F, 5 / _
		   6.0F, 1.0F _
		}
		br.InterpolationColors = ColorBlend
		g.FillPolygon(br, Me.Vertices2D)
	End Using
End Sub


Note: I only found one other VB.Net example of using alpha /opacity adjusted colorblend-type linear gradient brushes online..

Code defining triangle points like this wasn't too common either:
Code:
Dim m_trianglePts1() As Point = New Point() {}
Dim m_trianglePts2() As Point = New Point() {}
Dim m_trianglePts3() As Point = New Point() {}

Private Sub Form1_Load(sender As Object, _
                    e As System.EventArgs) Handles Me.Load
  m_trianglePts1 = { _
    	      New Point(210, 10), _
	      New Point(310, 10), _
	      New Point(260, 110), _
	      New Point(210, 10)
  }
  m_trianglePts2 = { _
	       New Point(207.5, 10), _
	       New Point(258, 110), _
	       New Point(167.5, 110), _
	       New Point(207.5, 10)
  }
  m_trianglePts3 = { _
		New Point(313, 10), _
		New Point(353, 110), _
		New Point(262.5, 110), _
		New Point(313, 10)
  }
End Sub
There are some "magic numbers" in the triangle fill example,
so I could get the colorblends to point to the center of the fan in the screenshot (sorry).

I wish there was a way to calculate this at runtime
so the triangle points could be dragged
and still have the colorblend gradients angle correctly toward a certain point.

The rotation transforms mess up, though, without the right corresponding TranslateTransform numbers.

Might have something to do with needing to adjust/set the point of rotation, but the math
was beyond me --just trial and errored to get numbers that were close..
Attached Images
File Type: jpg screenshots_fills-n-texturemapping.JPG (161.9 KB, 10 views)
Attached Files
File Type: zip triangle_fill_example2.zip (42.3 KB, 13 views)
File Type: zip PW5_with_LinearBrush_fills.zip (280.7 KB, 11 views)
File Type: zip ClippingToTrianglePolygonPath2.zip (60.9 KB, 15 views)
File Type: zip Thorsten_Ishak_texturemapping.zip (243.1 KB, 15 views)

Last edited by dotnetwrassler; 05-02-2015 at 09:59 PM.
Reply With Quote
  #104  
Old 05-10-2015, 05:01 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default VB.Net Voronoi, semi-transparent rotate virtual control & texturebrush transforms

Well, hopefully at least a few people got to look at the screenshot last post even if hardly anyone downloaded the code attachments.

Still working on TR (triangle rasterization --filling triangles with textures/pixels).

Some TR related links (in no particular order)
The MSDN related links:
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
https://msdn.microsoft.com/en-us/lib...6wcf.aspx#Y609
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
https://msdn.microsoft.com/en-us/library/729d4sbe.aspx
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
https://msdn.microsoft.com/en-us/lib....aspx#Triangle

Non-MSDN links:
http://ogldev.atspace.co.uk/www/tuto...utorial16.html
http://freespace.virgin.net/hugo.eli...s/x_polysc.htm
http://joshbeam.com/articles/triangle_rasterization/
http://www.xbdev.net/maths_of_3d/ras...ngle/index.php
http://www.xbdev.net/maths_of_3d/index.php
https://lva.cg.tuwien.ac.at/ecg/wiki..._rasterization
http://www.codeproject.com/Tips/8635...le-algorithm-D
http://gamedev.stackexchange.com/que...instead-of-gpu
http://forum.starling-framework.org/...e-texture-fill
http://stackoverflow.com/questions/2...in-a-square-to
http://www-users.mat.uni.torun.pl/~w...i_fillers.html
http://www.hugi.scene.org/online/cod...20cotriang.htm
http://stackoverflow.com/questions/8...-triangle?rq=1
Software Rasterization Algorithms for Filling Triangles (has a java applet on the page - don't access if you are leary of those)

Coloring and texturing polygons (pdf)

After taking 5 minutes to glance thru and familiarize yourself with the content in all those links,
let's move on to the business at hand - the code attachments.

As always - look at the screenshots and decided what working code attachment you want to download.

Both VB.Net coded demos/samples have no direct/exact equivalent (up to this point) anywhere on the internet
(that I know of - please let me know if you find anything of a like nature).

The Voroni demo is a VB.Net translation of this C# Voroni CodeProject.

It also uses VB.Net to produce "contoli" noise (see bottom right on the one screenshot) .
Note: This procedural noise texture generation code was kinda unique so
I made some extra effort to get a VB.Net code version of that working.


The Perlin Noise part of the project, however, "resisted" translation.

Here's the troublesome C# code functions:
Code:
float pseudoRandom(uint x, uint y)
{
    uint u = GetUint(x, y);
    return (u + 1.0f) * 2.328306435454494e-10f;
}
float noise(float x, float y,float w,float h)
{
    return pseudoRandom((uint)(x ), (uint)(y ));
}
Look pretty normal don't they?
They run perfectly fine.

Then, though, you try the VB.Net equivalent coding:
Code:
Private Function pseudoRandom(x As UInteger, y As UInteger) As Single
	Dim u As UInteger = GetUint(x, y)
	Return (u + 1F) * 2.328306E-10F
End Function

Private Function noise(x As Single, y As Single, w As Single, h As Single) As Single
	Return pseudoRandom(CUInt(x), CUInt(y))
End Function
See the issue?
Error (on the line inside the noise Function):
System.OverflowException was unhandled
HResult=-2146233066
Message=Arithmetic operation resulted in an overflow

To those who use UIntegers all the time (maybe to implement a Blowfish algorithm in VB.Net), you already know what's going on.

To those who think:
This is simple to solve - just use the "unchecked" keyword in VB.Net the same as you would in C#.
I'm afraid there is no such thing.

Of course you could turn off Option Strict or use this or this to defeat the error checking.
Probably not good practice overall, however..

Isn't there some kind of xvbt thread that touches on this issue?!

Why certainly --it's right here.

Quote:
Originally Posted by AtmaWeapon
UInteger and the other unsigned types didn't exist until .NET 2.0. So most of the framework uses signed numbers where it should use unsigned numbers because it was written before unsigned numbers existed, and it would be a breaking change to switch. Even more concerning is the unsigned data types are not CLS-compliant, which means a fat lot of nothing to most people but to library developers means you would normally not want to expose them in public interface. .NET languages aren't *required* to support the unsigned integer types, thus a library that exposes them might be unusable to some .NET language.

C and other low-level languages make it easy to convert from signed to unsigned and back because in the end they don't enforce a very strong type system. All C cares about is that the variable has some value with at least as many bits as expected; it's lenient enough that you can mangle structs to be compatible and so forth. Not so in .NET. In .NET, the fact that the data is held as bits is abstracted away. At the outer layers of the framework, an Integer is not 32 bits of data, it's a number that falls within a specific range. So from the .NET perspective, the cast is converting a value, not bytes, and it fails. If you want to peel back the layers of abstraction and work with the bits, you have to do things at a lower level. The type characters and overload available in the Convert class are easy shortcuts to what you'd really have to do: use bit shift operators or BitConverter to get the bits and build the desired value.

.NET does conversion differently than some other languages in this respect. Since the unsigned numbers were introduced late in the game, no one really uses them so it's rare that the warts around them bite you. If you're using a library with UInteger values then you're going to feel some pain; that's why the guidelines for designing libraries recommend avoiding them.
Note: Highlighting is mine - this is definitely a pain!

Post #15 of that thread actually gives a few special VB.Net functions to handle this situation,
but since the noise function is only used for Perlin Noise generation and the forum already has a thread regarding working Perlin Noise VB.Net code,
I just decided not to fix the issue myself --but if anyone else can if they really care..

So what if you are not happy with the my particular VB.Net Voronoi code?

There is the old PSC VB6 Rutton Voronoi code which represents
another possible "translation candidate"
(for someone familiar with VB.Net GDI wrapper equivalents to those old VB6 memDC API calls)

For those asking - why make a special virtual control?
I wanted to be able to adjust the texturemapping/alignment for:
1.) A single 3D triangle face
2.) A selected group of 3D triangle faces
3.) The triangle mesh for an entire model
Something that could appear to "float" semi-transparently over/around the 3D triangle face selection
(in all three cases) seemed to me the best (most intuitive) solution.

For those asking - does this solve the mapping coordinates issue when dealing with unwrap mapping?
No.
This special MSDN tutorial talks about this.
This is the significant image which shows how a single 2D image can be mapped in 3D by a kind of "unwrap correspondence map" (like a sprite sheet cut-out pattern, but a bit more complicated).

To PD..targeting at least 4.0, but (sorry) still haven't find an good XML Linq examples of:
Quote:
Originally Posted by PlausiblyDamp

If you want to be more specific in the objects you want to write out then you may find serialization in any form too blunt a tool, you might need to write code to handle exactly what is written.
Depending on the version of .Net you are targeting the XML Linq support might be the easiest option as it allows a lot of control while reading and writing without too much code bloat.

Last edited by dotnetwrassler; 05-10-2015 at 05:41 PM.
Reply With Quote
  #105  
Old 05-15-2015, 06:30 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Into unknown 3D territory - the land of vector normals

You would think if I found a way to texture map to triangles all would be well and good.
Well it's not.

Textures are useless unless they can be shaded.

In order to shade a texture in a 3D space you have to know
how the 3D face is oriented in relation to the light source.

How do you do that?
You have to be able to calculate something called a vector normal.
If you search the MSDN section for GDI/GDI+ good luck on finding the phrase "vector normal" --you'll find "vector" but no normal.

And here is the really frustrating thing --I not only wanted to mathematically find the vertex normal,
I wanted to show (by rendering/drawing) what a vertex normal looked like.

I have spend the last 5 days searching for a good (but simple) example of this using C# that I could translate to VB.Net.

I found some references to a Mike Rodnick 3D tutorial from the time when WPF was associated with something called "Avalon",
but the actual code seemed to have disappeared.

That was until I started digging around in the Wayback Machine (Internet Archives) and found the page with the C# code.

Unfortunately it used a pre-compiled binary call "3DTools.dll",
so there was no way to even upload it to the forum to get help on the translation.

So I had to not only translate the Rodnick code myself, but also had to find and translate the C# 3DTools dll code
(which was basically a wrapper around "ScreenSpaceLines3D" and some MathUtils).

The C# Codeplex code listing is here.

As someone is sure to point out:, Yes, this is WPF code.

So this became my first ever C# WPF to VB.Net WPF code conversion.

There were all kinds of translation issues - trying to DirectCast a point4D,
issues with Viewport3DVisual and visual.Viewport,
then a really nasty errors with Matrix3DStack() that ended up need patching with some translated parts of the extra Matrix3DStack class
(for which I had to rip out the IEnumerator and ICollection code that was giving me the same old issues
as the Voronoi C# code that wouldn't translate).

Anyway --got everything translated from both sets of C# codebases and no external pre-compiled dll for 3DTools needed. (yeah!)

So is there ever going to be some non-WPF code for calculating vertex normals.
Would like to arrive at that VB.Net code.

I found a few C# snippets that I translated to VB.Net, but I don't know how to use them to draw the blue lines.
Code:
Private Shared Function CalculateNormal(firstPoint As Point3D, secondPoint As Point3D, thirdPoint As Point3D) As Vector3D
	Dim u = New Point3D(firstPoint.X - secondPoint.X, firstPoint.Y - secondPoint.Y, firstPoint.Z - secondPoint.Z)
	Dim v = New Point3D(secondPoint.X - thirdPoint.X, secondPoint.Y - thirdPoint.Y, secondPoint.Z - thirdPoint.Z)
	Return New Vector3D(u.Y * v.Z - u.Z * v.Y, u.Z * v.X - u.X * v.Z, u.X * v.Y - u.Y * v.X)
End Function
Code:
' Calculate a triangle's normal vector.
Public Shared Function FindTriangleNormal(point1 As Point3D, point2 As Point3D, point3 As Point3D) As Vector3D
	' Get two edge vectors.
	Dim v1 As Vector3D = point2 - point1
	Dim v2 As Vector3D = point3 - point2
	' Get the cross product.
	Dim n As Vector3D = Vector3D.CrossProduct(v1, v2)
	' Normalize.
	n.Normalize()
	Return n
End Function
Here is the MSDN link for Vector.CrossProduct (which doesn't appear to be connected with DirectX/XNA/WPF).
Here is the MSDN link for Vector.Normalize

Maybe I should back up a step though to throw up a few links:
Normal (per it's Wikipedia page):
Quote:
In the three-dimensional case a surface normal, or simply normal, to a surface at a point P is a vector that is perpendicular to the tangent plane to that surface at P.

The normal is often used in computer graphics to determine a surface's orientation toward a light source for flat shading, or the orientation of each of the corners (vertices) to mimic a curved surface with Phong shading
There is also this pdf that talks about "face normals":
Quote:
What is the Normal?
Any Face or 3D Surface has a Normal. This Normal determines the faces response to lighting within
a 3D scene. The Normal is a Vector that points directly away from and is perpendicular to the face.
If a light source is in line with
the Normal then the surface will appear at its brightest. If the Normal
points away from a light source then the surface will be rendered at its darkest.
Step 1: Get the Vectors
Step 2: Calculate the Normal from the vectors (using Cross Product math)
Of course after those two steps then the pdf goes into C++ code which helps us not at all.

There are a couple CodeProjects (1, 2) that although they are C#,
might be useful to translate, because there is also something called the "dot product"
that is used with the cross product for "normalization" of vectors.

The only dot product functions in the MSDN (1, 2) are for DirectX/XNA and WPF.


There is some VB6 code (an interlocking sub/function pairing,
which might be translatable) for
computing dotproduct and crossproduct on this page.

The other difficulty in translating over the XAML/WPF code is that we have no ViewPort
and there is no such thing as an in-built GDI+ Create3Dmesh function.

I don't know how much farther I can go into non-WPF code for calculating (and showing via blue lines)
these face normal vectors.

The only thing to add is that boops boops code uses the Edge3D structure to create the vectors that make up a side of a Face3D.
Maybe there is something to work with there.

Or I forgot to answer: "what's a vector?"
A vector is basically just a line with two endpoints, where the position/ location of the endpoints (could be 2D or 3D) determines directionality.

This is the point where I shamelessly ask for links - not for VB.Net code links for this (which I know there is none),
but any non-DirectX/non-XNA/non-OpenGL/non-WPF .Net C# code that draws 3D face normals.

Meanwhile I'll keep playing around and see what I code mischief I can get myself into..

Last edited by dotnetwrassler; 05-15-2015 at 06:41 PM.
Reply With Quote
  #106  
Old 05-21-2015, 10:20 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Grappling w/ephemeral points & possible refactoring revelation from fighting ameobas

Probably anyone following this thread has been wondering what's been going on.

Well, the PS7 attachment to post #99 is (I finally realized) a dead end.

I thought I would be able to get the 3DSImport code and boops boops code to "gel" together post merger,
because I thought that the only difficulty would be converting a few classes, adding the gFill class,
and find a way to use "model space" instead of "world coordinates locked to device coordinates space".

There is another issue though.

The Paint subs of the two code bases are just too far apart to be able to do a suitable morph-merge mashup.

I finally realized this while working on various versions of the gFill class.

It's been a while since passel put in an appearance in this thread (Post #96 on 04/09/2015),
so I've had to rely on some long talks with my own personal passel avatar
in order to have conversations about the way the code refactoring needs
to happen to move the project forward.

Unfortunately this means debugging my own mind.

My mind works in a weird way - whenever it encounters a problem that the conscious mind can't solve
it kind of assigns it to a "background worker thread' in my sub conscious mind.

In the meantime I was researching "vector transforms" in a ..Net context and I came across
some C# book charting code from a guy named Jack Wu.

Most of the later chapters of this book involved a custom 3D chart control (which was useless code to me)
but in one of the early chapters I found some interesting colormapping code.
The thing that jumped out at me was his use of magic number offsets.

Why did he pick those numbers?
What if there was a way to play around with the offsets at runtime?
What kind of graphics rendering would be produced?

So I translated the example to VB.Net code and extended the interface
to have a way to play around with the mapping point offsets.

I called it "BCIM" (BilinearInterpolatedColorMapping) while I was developing it,
but I did a more verbose re-naming for the attachment below
("Bilinear_interpolated_runtime-adjustable_multi-point_color_mapping.zip")

Possibly it could become one of gFill's enumerated FillTypes in the future.


Here's why I posted today:
I "half woke up" early this morning - it's that state where you are
aware you are not asleep but your eyes are closed and your mind is just drifting.

The word "ephemeral" appeared in big bold 3D letters.

Then two ameboid shapes appeared, one red, one blue.
They appear to be attacked each other, and as they fought
labels appear on each - one was labelled "Face3D", another was labelled "gFill".

Then the outer membranes of each burst into one another and the mixed
cytoplasm formed a purple pocket between the two.

As I describe it probably no one gets the symbolism,
but it was a revelation to me because I had been working with
a set of code I called "PW5 with various fill types".

I realized something - Face3D doesn't need to have the Paint sub.

In fact Face3D doesn't even need to have a FaceEdges property or a Vertices2D property.

However if I move all three to the gFill class then how do I get
the points to be labelled at runtime for debugging purposes?

The PS7 uses a twisty triangle dropdown to display the the point information
dynamically as the trianglestrip point are dragged but that's awkward.

It's would be a lot cooler to have the point numbers text strings drawn directly atop the 3D models
(as the Import3DS code does when rendering with certain checkboxes checked).

So I need to make the points less "ephemeral" by transferring that part of the 3DSImport code that does the DrawString calls
into the boops boops code, somehow hooking it into the Vertices2D structure.

Why is this helpful?

Look at the the screenshot below about bad texturebrushing.
Part of the issue there is I am referencing the points incorrectly.

They not only need to be referenced after the post 3D to 2D projection,
but separated parsed for each face.

If Face3D get inherited inside gFill class (instead of the other way around)
then maybe you can use something like:
Scene.Layer.Cuboid.face.gFill.Vertices2D(1).X

This might even allow working with the Thorsten-Ishak texturemapping code
instead of being forced to texturebrush.

It's the angled shearing of the texturemapping (not necessarily the rotational transform) that's the difficulty right now.



The thing that is frustrating is the fact is I know there is a way to properly texturemap a cube because
the working code attachment "QuaternionDrawing23.zip" to post #8 of this thread proves it can be done.


Here is the relevant code snippet from inside the Cuboid.vb class file of that attachment:
Code:
If m_drawingImage AndAlso bmp(i) IsNot Nothing Then
	filters(i).FourCorners = face(i)
	g.DrawImage(filters(i).Bitmap, filters(i).ImageLocation)
End If
DrawImage in this case is not being used to re-shape the bitmap texture to fit the
cube face points.
It's basically just moving un-transformed pixels around like a bitblt call.

The bitmap transform is being done by the getTransformedBitmap() function
inside the FreeTransform.vb class which has code lines like:
Code:
If isOnPlaneABCD(srcPt) Then
	dab = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(0), srcPt)).CrossProduct(AB))
	dbc = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(1), srcPt)).CrossProduct(BC))
	dcd = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(2), srcPt)).CrossProduct(CD))
	dda = Math.Abs((New YLScsDrawing.Geometry.Vector(vertex(3), srcPt)).CrossProduct(DA))
	ptInPlane.X = CSng(srcW * (dda / (dda + dbc)))
	ptInPlane.Y = CSng(srcH * (dab / (dab + dcd)))
	x1 = CInt(Math.Truncate(ptInPlane.X))
	y1 = CInt(Math.Truncate(ptInPlane.Y))
	If x1 >= 0 AndAlso x1 < srcW AndAlso y1 >= 0 AndAlso y1 < srcH Then
		If isBilinear Then
			x2 = If((x1 = srcW - 1), x1, x1 + 1)
			y2 = If((y1 = srcH - 1), y1, y1 + 1)
I don't understand exactly what that code is doing,
but I know enough about researching the use of crossproduct in connection with vector normals
that this code "smells" like vector processing code - possibly finding/using the 2D angles necessary to reshape the bitmap
to fit the vector angles of the 3D cube face..

Would it be possible, though, to transplant code connected with quaternion rotation to
inside of the boops boops' world-coordinate-locked-to-device-coordinates-space that uses matrix rotation?
Don't know until I play around a little more..

But anyway..the important thing is that after today I'm seeing things in a slightly different way
that may allow some paths forward instead of frustrated by the "wall" of trying to apply texturebrushing
to 3D objects and not being able to make achieve good/proper texturemapping angled alignment.

However gFill_test7g is a failure.
Another dead end.
Still, I will post it anyway, so if anyone finds this thread and is traveling the same path
they will know not to go down that path-branch.

I will continue refactoring and maybe fail better next time.
Reply With Quote
  #107  
Old 05-29-2015, 09:12 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Deeper into 3D texturemapping and colliding with vector transforms

I said last time:
Quote:
Would it be possible, though, to transplant code connected with quaternion rotation to
inside of the boops boops' world-coordinate-locked-to-device-coordinates-space that uses matrix rotation?
Don't know until I play around a little more..
After doing a code extraction of the getTransformedBitmap() function
and isolating it to texture a Quad Plane (instead of a multiple cube faces)
I think it may be adaptable to the boops boops Face3D class.

Here's the "snag" (or difficulty or "wrinkle"):
When you map a texture to a set of angled vectors
comprising either a triangle mesh or
a quad mesh (say a mesh with rows of trapezoidal shaped quadrilaterals)
you have a number of method options as to how the texture is applied:

method a:
You can designate one side as the "top" and then fill the triangle or quad
with the texture applied perfectly perpendicular to this "top" edge/line,
then use texturebrush clipping to isolate the texture inside the face/shape.

The issue: I looks strange!
Not like the typical 3D texturemapping at all but just some weirdly clipped pixel fill

method b:
You adjust the texture to fill the triangle or quad face using some form of
pixel interpolation (like bilinear interpolation).

You have two sub-choices for this:
1.) Do a "squish" distortion/warp so that the texture, slightly over-sized beyond the edge lines of the face/shape,
is compressed until it exactly fills (and fits) within the lines/edges.

2.) Do a stretch/expand "taffy pull" (distort/warp the pixels) so that the texture, slightly under-sized
inside the edge lines of the face/shape, is expanded until it exactly fills (and fits) within the lines/edges.

Method "b" definitely produces better results (that look closer to what classic 3D texturemapping is supposed to look like),
but with both interpolation sub choice types have the same two issues:
A.) No way to "correct" for "bad" distortion effects
B.) No optimal way to select which edge(s) to align with -- especially if
the 3D model is undergoing rotation

The normal way to solve issue "A' is to have the UV unwrapped texture be "reverse distorted"
to compensate for the post texturemap wrapping distortion.

This may be possible using the Mona Lisa grid distortion code in this thread, so I'm going to purposely ignore that for now.

There are tools in Blender, 3D Studio Max and Maya to do this even if no
VB.Net code is developed to do this perfectly:
http://www.cs.washington.edu/researc.../uvtexture.htm
http://www.republicofcode.com/tutori...p_uvw_mapping/
https://kakes3d.wordpress.com/2010/0...xturing-azusa/

Issue B though might prove more intractable.
I keep feeling that is a vector normalization issue and I'll keep focusing on that until
someone informs me that neither cross product or dot product math can provide the desired solution.

Thus I keep searching for code that might be helpful.
This CodeProject vector code is one I keep coming back to --it looks tantalizingly like what I need
but the C# project has no form, nothing to paint/render to.

It's just raw math turned into a dis-embodied code library.

This CodeProject code actually draws something to screen and has,
inside it's vector code file, has both Normalize code and a DotProduct function code.

Even though its 2D, not 3D, this vector file was enough of an incentive to work through a C# to VB.Net translation.

The working VB.Net example of moveable polygons with collision displacement transforms using normalized vectors is attached below.

From the attached screenshot you can see I "fancied it up" a little using color fills, but the behavior is what's interesting.

Most of the time if you have a collision of objects (with the necessary hit test) the objects either:
1.) Stop moving after colliding (if the coder is lazy) or
2.) Bounce off in some kind of transfer-of-forces angular momentum.

This code does neither.
If allow you to try and keep pressing the arrow key in the same direction that caused the collision and
if it hits the colliding polygon on an angled edge it will slide across or down that angled side.

The math behind how this "sliding" transform is accomplished is the interesting part.

Anyway, it was a busy week at my day job so nothing else to post this week..

Oh..one annoying thing about the translation.
If you copy and past the Form_KeyDown routine there is one line that inaccurately translates in all the online translators.

The C# code line is:
Code:
if (polygon == player) continue;
..which the Telerik and most of the other translators convert to VB.Net as:
Code:
If polygon = player Then
  Continue For
End If
This keep coming up as an error because the equals sign can't be used to compare these types.

I tried writing a custom IComparable code set.
I tried a whole bunch of ways of coercing the "player" Polygon/vector type.

But in the end (after much struggle) the answer was so simple:
Code:
If polygon Is player Then
  Continue For
End If
Yes, I did a forehead slap afterwards..(and to quote Homer Simpson: "Doh!")

Last edited by dotnetwrassler; 05-29-2015 at 09:23 PM.
Reply With Quote
  #108  
Old 06-16-2015, 05:59 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default GD_Eye_3D_viewer

A very minor update to cleanup the PS7 code attachment.
Added layer visibility checkboxes and some branding that brought
the attachment to close to the forum limit of 2MB.

I have a version that incorporates more of the gFill class stuff,
but it's too large to upload so this may be the end of the line for this thread.

I've been approached by a guy whose company is in a local tech incubator.
He has a prototype of a 3D printer (with laser scanner combo) device.

I modified this attached code to do patching of the 3D meshes after scanning,
using a modified version of the delaunay triangular code from this thread,
and then spit out 3D printing oriented g-Code (similar to what slic3r does).


He seems happy with the demo code even though it has a little pre-beta roughness-around-the-edges.

I'm supposed to meet with him and his IP (Intellectual Property) attorney later this month,
and I'm thinking that after the meeting this code will get smothered by an NDA (non-disclosure agreement) blanketing.

It's strange how these things go...oh well.
Hopefully everyone viewing this thread will realize how totally unique it was..
Attached Files
File Type: zip GD_Eye_3D_viewer.zip (1.74 MB, 16 views)
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
 
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
 
-->