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
  #61  
Old 03-25-2015, 09:40 AM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default


I haven't looked at the details, but it seems you wouldn't want to use FillListBox as a guide, but rather the drawing routine (in paint event), since it draws all the objects.
Code:
  For currentSubObjectIndex = 0 To Import3DSObject.SubObjectArray.Count - 1
    SubObjectObj = Import3DSObject.SubObjectArray.Item(currentSubObjectIndex)
    
    totalVertices = SubObjectObj.VertexArray.Count
    totalTriangles = SubObjectObj.TriangleArray.Count

    'Write out SubObjectObj.SubObjectName

    For i = 0 to totalVertices - 1
       VertexObj = SubObjectObj.VertexArray.Item(i)
       'Write out VertexObj.X, Y and Z
    Next

    For i = 0 to totalTriangles - 1
      TriangleObj = SubObjectObj.TriangleArray.Item(i)
      'Write out TriangleObj.V1, V2, V3
    Next

  Next
I see those are still ListArrays and should probably changed to List(Of Vertex) and List(Of Triangle), but in anycase, the above loops should access what you need I think.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #62  
Old 03-25-2015, 09:51 AM
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,058
Default

Is there a reason you are wanting to use an Ini file (which is a fairly flat structure) to store what is essentially a hierarchical structure?

I would strongly suggest using XML or even something like Json - there are built in tools to handle XML or newtonsoft.com has a free Json serialiser that can be installed in seconds via nuget and would turn your entire serialisation logic into something like
Code:
'taken from the btnSaveIni_Click event
If saveFileDialog1.ShowDialog() = DialogResult.OK Then
    myStream = saveFileDialog1.OpenFile()

    Dim sw As New StreamWriter(myStream)
    Dim json As New JsonSerializer

    json.Serialize(sw, Import3DSObject)
    sw.Close()
End If
Reloading into the Import3DSObject structure would be as simple as
Code:
Dim myStream As Stream
Dim loadFileDialog1 As New OpenFileDialog

loadFileDialog1.Filter = "INI files (*.ini)|*.ini|All files (*.*)|*.*"
loadFileDialog1.FilterIndex = 1
loadFileDialog1.RestoreDirectory = True
loadFileDialog1.FileName = OpenFileDialog1.FileName

If loadFileDialog1.ShowDialog() = DialogResult.OK Then
    myStream = loadFileDialog1.OpenFile()
    Dim sr As New StreamReader(myStream)

    Dim data As String = sr.ReadToEnd
    Import3DSObject = JsonConvert.DeserializeObject(Of Import3DS)(data)
End If
It would give you a fairly simple text based format, that properly supports nested structures without you having to deal with the complexity of ini files.

That way you could probably remove the entire Ini file related code as well.

Edit: Additional thoughts....

If you are using the Import3DS structure as your basis for your actual rendering rather than a specific format such as .3ds then this could be a much simpler way of dealing with multiple formats. Also if you have named entries in these structures you might find using a Dictionary easier than a List as it allows for items to be identified by a key.

Also to keep the file size down you might want to mark the public property ByteArray with the <JsonIgnore> attribute - or better still make it private and possibly pass it in through a constructor rather than a property.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags

Last edited by PlausiblyDamp; 03-26-2015 at 04:50 AM. Reason: Additional thoughts....
Reply With Quote
  #63  
Old 03-25-2015, 10:39 AM
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,058
Default

Quote:
Originally Posted by dotnetwrassler View Post
Trying to figure out how to do this would be much easier if I didn't have to deal with a class that sits outside the form.

For a modularization optimization standpoint maybe I need to create a "SharedData" class
which has all the List type variables declared with Public Shared scoping.

That way such a class could be the "bridge" (focal point) between the IniFile class and the MainForm code.
A single place I could debug everything that is happening with the data instead of having to jump around looking a breakpoints in different tabs.

..or (here's the lazy programmer speaking) maybe just dump all the IniFile class code directly onto the form?

Probably keeping everything separate is better from a code design standpoint but
from a "minimizing scoping tediousness" standpoint I'm tempted to go the other way..
As a general rule it is nearly always better to keep bits of code isolated from each other, otherwise every time you make a change in one place you need to make the same change (or related changes everywhere).

I personally try to keep the number of form level (and class level variables), especially public ones, to a minimum. If a variable is only used in one function it is much cleaner to declare it in that one function. If two functions use a variable for the same reason but there is no need for the contents of the variable to be shared between functions then just have each function declare it's own copy of the variable.

As an example your main form contains a lot of form level variables (i, j, TriangleObj, Total_Row, Html_Str etc.) that are either only used in one function or are used independently in multiple functions. Keeping these variables closer to where they are used will make for more maintainable code.

I would certainly consider moving the actual 3d object into a class separate from the form - that way loading and saving the 3d structures would be independent of the form itself and this could facilitate the loading of different formats easily.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags

Last edited by PlausiblyDamp; 03-25-2015 at 12:32 PM.
Reply With Quote
  #64  
Old 03-27-2015, 01:08 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Re: Advice and Intent

Thanks PlausiblyDamp and passel, for the advice.

In regard to XML I explain my reasons for not choosing it in post #53.
They pretty much apply to JSON as well (including the fact that while there are JSON .Net tree-style viewers,
they are not what I call "smart viewers").

Quote:
Originally Posted by PlausiblyDamp
Is there a reason you are wanting to use an Ini file (which is a fairly flat structure)
That's it. Right there.
I really do want a fairly flat structure (even if I have to coerce hierarchical data into such).

boops boops also mentioned Serialization (back in post #52):
Quote:
Originally Posted by boops boops
For the 3DScene program, it should only take a dozen or so lines of Serialization code to save and load scenes.
It will be interesting to see what he comes up with..

Quote:
Originally Posted by passel
I haven't looked at the details, but it seems you wouldn't want to use FillListBox as a guide,
but rather the drawing routine (in paint event), since it draws all the objects.
Did you mean the 'PictureBox_Render_Paint' code.
I've looked at it, but it's got some very deep nesting..both If..EndIf and For..Next.

Should I solve a thorny nesting issue by looking at some other thorny nested code?
I think not.
However at some point, though, I will have to convert that render paint code into
something that is compatible with the code for Perspective Scene.
I have no idea how to do that at this point.

Quote:
Originally Posted by PlausiblyDamp
As a general rule it is nearly always better to keep bits of code isolated from each other,
otherwise every time you make a change in one place you need to make the same change (or related changes everywhere).
I tend to agree with this rule - not for theoretical reasons, but practical ones.
If you can keep the scoping isolated there is less switching back and forth between document tabs in the .Net IDE.

Quote:
Originally Posted by PlausiblyDamp
I would certainly consider moving the actual 3d object into a class separate from the form - that way
loading and saving the 3d structures would be independent of the form itself and this could facilitate the loading of different formats easily.
I agree it would be nice in principal, but this 3DS loader code may eventually "disappear" after the merger with e Perspective Scene code.

Do I want to spend a lot of time refactoring code
(just to isolate code separately from the form,
and make it seem more "design principals pretty"),
when the main challenge is to get it ready for merging.


'************a little side commentary******************

I don't really know how to explain what I mean when I say - "getting it ready to be merged".

It's something that is (or can be) very complicated.

There has never (in the whole history of this forum) been even an attempt to have a set of
guidelines, principals and procedures regarding optimizing multiple code bases strictly for the purpose of merging.

Especially when two sets of code were written by two different authors, in two different time periods,
using two different sets of data structures and with
two different sets of reasons (motivations/purposes) in coding the way they did.

You have to find the underlining "touch-points" of commonality.
This is a pattern recognition thing.
Something computers lack the ability to do in a general way.

Yes, there are algorithms in looking at specific types of patterning,
but in terms of "semantic mediation ontology",
the word "ontology" deals with the philosophical study of the nature of being.

I don't want to get all metaphysical, but both reality and code had a kind of "fluidity".

You could say the term (in a very vague and "loose coupled" way) is related to "translation".

However, did you every hear the phrase "the meaning got lost in translation"?
Most of the time this happens because of "contextualization discrepancies".

I'll throw in one of my favorite quotes from the Matrix movie:
Quote:
Do not try and bend the spoon. That's impossible. Instead only try to realize the Truth... There is no spoon... Then you'll see that it is not the spoon that bends, it is only yourself
You can not get "lost"..you can not lose yourself in the act of "bending" (code not spoons)..if you don't lose the "pattern" you are trying to "couple".

You could say 3D is Point3Ds(vertices), Faces(groupings) and Pixels (Textures/Tinting).
So..really..how is that any which way different from 2D?
Even 2D has z-ordering.

The 3D points (and how they are contextualized) are the commonality.



Right now the last dozen few posts by passel and PlausiblyDamp just want to concentrate on coding techniques.
This is all well and good, but I'm really more concerned at this point in what it will take to get past the points in between
and get to the final set of code that will support the design I want.


It's like I want to get, as directly as possible, from A to B to C, while minimizing step B.
However what you both are saying is:
Quote:
This is really not an A to C problem, but and A to Z problem,
and we have so many options we want you to try
in optimizing each of the steps along the way
(steps C thru Y for instance).
What I'm looking for is a way to bypass half-steps and provide a higher "code correlation" between
the code in the attachments to posts #47 & #48 and
the "3DS_File_Loader_slight_revision.zip " code attached to post 50.

Or..maybe to put it another way - merge (or get ready to merge) first, then optimize later.

'**********end of side commentary********************

Believe it not though, slogging through 'injecting' the ini files code is actually giving me
a better understanding of the intent of the 3DS loader code overall.


'***************the part about intent***************
When I say "intent" you will proabably not realize what I mean.
I mean the deepest underlying understanding.

Think of it this way.

Medieval peasants/serfs saw the spires of Gothic cathedrals reaching to the sky and then went inside
to be bathed by the colored light streaming photonic visions of Bible passages that had only heard about (never read).

For the medieval stone-workers, the Gothic cathedral was all about a series of hidden
masonry structures supporting the flying buttresses
(as well as, only recently discovered, a set of under-girding metal structures
that support the stone work during construction).

The designers of Gothic cathedrals had to conceptualize things at a different level --understanding
the physics principals of the way stone couple be shaped to support load bearing against
gravity (using pointed arches and ceilings vaulted in certain ways to distribute forces.

Designing Gothic cathedrals to work in "partnership" with these load bearing physics was the intent as much as
the intent to designing the highest buildings possible of their day,
to reach as high as possible towards the heavens (and God).

I guess that's the best analogy I can give for intent (hopefully it was enough).

'***************end of - the part about intent***************

It's corollary: engineering and design don't have to be separate but (with careful consideration) can be (at least in some ways) synergistic.

It's just hard to teach other people my particular principles of "careful consideration".

However, I will keep refactoring until the right pattern (hopefully) emerges.

Last edited by dotnetwrassler; 03-27-2015 at 01:36 AM.
Reply With Quote
  #65  
Old 03-27-2015, 06:29 AM
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,058
Default

Quote:
Originally Posted by dotnetwrassler
Thanks PlausiblyDamp and passel, for the advice.

In regard to XML I explain my reasons for not choosing it in post #53.
They pretty much apply to JSON as well (including the fact that while there are JSON .Net tree-style viewers,
they are not what I call "smart viewers").
I would consider the format you are saving and loading from separate from how you choose to display this information. You say there are no built in controls that handle XML or Json well enough for displaying this information, I imagine there are even less built in controls that handle the display of a custom .ini file format. If you can get from a file format to a workable internal format (objects, properties, classes etc.) then whatever control(s) you work with for the UI would use this internal structure - not the persistence format.

Quote:
Originally Posted by dotnetwrassler
boops boops also mentioned Serialization (back in post #52):
It will be interesting to see what he comes up with..
Using the built in serialization support could be a matter of adding the <Serializable> attribute to the Import3DS, Triangle, Vertex and SubObject3D classes and then using code like
Code:
If loadFileDialog1.ShowDialog() = DialogResult.OK Then
    myStream = loadFileDialog1.OpenFile()
    Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter

    import3DsObject = DirectCast(formatter.Deserialize(myStream), Import3DS)
    myStream.Close()
End If
'and
If saveFileDialog1.ShowDialog() = DialogResult.OK Then
    myStream = saveFileDialog1.OpenFile()

    Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
			formatter.Serialize(myStream, _import3DsObject)
End If
myStream.Close()
to load and save the structure to a binary format.

Quote:
Originally Posted by dotnetwrassler
Do I want to spend a lot of time refactoring code
(just to isolate code separately from the form,
and make it seem more "design principals pretty"),
when the main challenge is to get it ready for merging.
If the code is cleaner and more isolated now then you will probably find the merging easier later, clean code is more than just "design principal pretty". Clean code is ultimately more understandable and maintainable.


Quote:
Originally Posted by dotnetwrassler
There has never (in the whole history of this forum) been even an attempt to have a set of
guidelines, principals and procedures regarding optimizing multiple code bases strictly for the purpose of merging.

Especially when two sets of code were written by two different authors, in two different time periods,
using two different sets of data structures and with
two different sets of reasons (motivations/purposes) in coding the way they did.

You have to find the underlining "touch-points" of commonality.
This is a pattern recognition thing.
Something computers lack the ability to do in a general way.
This is all down to the overall design of the software and how you need to merge things, if the code functions correctly as it stands then often encapsulating the exiting code behind interfaces or some other form of object model is enough. Once code has been cleanly encapsulated then it doesn't really matter exactly what you are working with, just how you interact with it.

Quote:
Originally Posted by dotnetwrassler
You could say 3D is Point3Ds(vertices), Faces(groupings) and Pixels (Textures/Tinting).
So..really..how is that any which way different from 2D?
Even 2D has z-ordering.

The 3D points (and how they are contextualized) are the commonality.
It all depends on what you consider to be the appropriate level of abstraction in modelling the problem, part of design is deciding what level of abstraction is appropriate. If you had to write software that dealt with both 2d and 3d rendering and needed to do so seamlessly then abstracting everything to a 3d point might make sense. If you are dealing with a 3d rendering system then higher level abstractions like Points, faces, textures, lights and cameras might make a lot more sense.

Quote:
Originally Posted by dotnetwrassler
Right now the last dozen few posts by passel and PlausiblyDamp just want to concentrate on coding techniques.
This is all well and good, but I'm really more concerned at this point in what it will take to get past the points in between
and get to the final set of code that will support the design I want.
These don't need to be opposing views, getting from one code model to the final code model is far easier if the code models are clean and understandable. Being able to add / remove or modify a single part of a model without worrying about dozens of dependencies can make this code evolution a lot easier.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #66  
Old 03-28-2015, 10:56 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Some thoughts on a 3Dobject Structure..

Thanks for the extended response to my last post, PlausiblyDamp.

Just a few quick remarks in response though..

No binary - I want ASCII text that anybody to be able to open/view the info saved to file in notepad/wordpad.

Yes, clean code is probably ultimately more understandable and maintainable, but the process (my process) of doing code mergers is inherently "messy"
and having clean code to start with doesn't necessarily make the process any easier.
It's all in how far apart the two (or more codebases) are to start with that determines the ease of merging,
not necessarily the "cleanliness' of the codebases involved in the merger.

Quote:
Originally Posted by PlausiblyDamp
Once code has been cleanly encapsulated then it doesn't really matter exactly what you are working with, just how you interact with it.
I totally agree.
Once the data structures are designed/set-up, I don't want to mess with them (or even have to think about them).
Just dump all the data in and cherry pick what's needed as it needed.

Quote:
Originally Posted by PlausiblyDamp
If you are dealing with a 3d rendering system then higher level abstractions like Points, faces, textures, lights and cameras might make a lot more sense.
Thank you (for agreeing).
Quote:
Originally Posted by PlausiblyDamp

Being able to add / remove or modify a single part of a model without worrying about dozens of dependencies can make this code evolution a lot easier.
Dependencies bad --got it.




>>>>>Thoughts on a 3Dobject Structure

So here's my thinking at this point.
StreamWriter gulps the data from the file.
Spits out into something that can hold the data in memory.
What is that something?

Maybe a class?
Classes aren't just about functions and subs.
They also can contain variable and properties.
Which can be used to store a bunch of values.

But what I'm really think that a 3DObject data type should be
is like a UDT (user-defined data type) under VB6.

The closest equivalent that I know of in VB.Net is a Structure.

There is an advantage to using classes, though, instantiation.
At the point (or moment) of instantiation, the newly created class instance can give us the opportunity to "autoload" data.
Could we take advantage of a class and a structure together?
Tuck one inside the other and be able to use someclass.somestructure.attribute to be able to get the data back out.

This MSDN Structure page has some interesting things to say:
Quote:
Structures support many of the same features as classes.
For example, structures can have properties and procedures, they can implement interfaces, and they can have parameterized constructors.

However, there are significant differences between structures and classes in areas such as inheritance, declarations, and usage.
Also, classes are reference types and structures are value types.

You can use Structure only at namespace or module level.
This means the declaration context for a structure must be a source file, namespace, class..
So a Structure can have a class as it's "declaration context".
Sounds promising.

I had been thinking of storing the 3D points in a kind of Excel table (represented by a 2D array) where the columns would be X, Y, and Z
and the rows would be the list of such points.

The issue - a 3D "face" is basically a 3D version of a 2D polygon.
So you could have faces that use 3 points, 4 points, 5 or more points.

If you try merge all these face tables (2d arrays) into some kind of super array then it's going to end up being
a "ragged" (sparse) array where you are mixing 3 point faces with faces containing 100 points.




Of course collection storage (like Lists) don't have indexes, so you don't have to use a count variable to loop through them.

How about putting the face point "table" data into a Dictionary that is stuffed into a List.

I know using Dictionaries can be optimal over using a HashTable per this CodeProject test.
According to this StackOverFlow thread:
Quote:
The performance for getting an item from a Dictionary is affected very little by the number of items. The items are divided into buckets according to their hash code, so there are generally only a single or very few items in each bucket. The operation is close to a O(1) operation.
So maybe...loop through the StreamWriter data,
create a 3DPoint Dictionary (with X,Y,Z keys),
then feed that into a "face" data List<T>,
which in turn gets put into a 3DObject Structure, inside a 3DObject class?

No -it would have to be more complicated than that.
There could be multiple 3DObjects that make up each 3D "Model".

There would also have to be a way to store "gFills" (either a tint color, a gradient of some type or a texture).

I have to think about this a little more..
Reply With Quote
  #67  
Old 03-28-2015, 04:27 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Some thoughts on a 3Dobject Structure..Part 2

Okay..I was getting a little confused trying to sort through all the possible ways of storing data in VB.Net
at the same time as I was trying to figure out how the object relationships needed to be organized.


To clarify my thinking I decided I needed to come up with a diagram exploring the 3D Object Hierarchy (see attached picture below).


What is this diagram representing?

Nested boxes/rectangles generally represent classes of one or more objects...at least for all of the "data containers" above 3DObject.

I'd like to use classes just so each level of nesting can have it's own transform methods*** (and centering specification).

So, for example:
There can be multiple 3DObjects in a SubObject(ModelPart).
There can be multiple SubObjects in a Model.
There can be multiple Models in a ModelGroup.
A Scene can contain multiple ModelGroups (and so forth).
The scene class also has a scale-factor property and an optional gFill background property.

Why a ModelGroup?
1.) What if you wanted to move groups of SubModels(ModelParts) together as one?
2.) What if (for example) you had a 3D scene which consisted of a fighter plane sitting on the tarmac of an airport.

In such a scene the ModelGroups could be:
a.) A aircraft hanger
2.) An air traffic control tower
3.) The F-22 plane.

Inside the F-22 plane would be Models for things like different sub-systems, the aircraft body, avionics system, and engines (Pratt & Whitney F119-PW-100 turbofan).

The engines would have different SubModels/ModelParts assemblies, which would further decomposed into a set 3DObjects.

This example represents about as far as I would want to go in pushing the nesting of the 3D Object Hierarchy.

Take a look at the pdf for Autodesk Inventor 2014 API Object Hierarchy.
Don't ever want go there!




I'm thinking that, though, that for the time being, the ModelGroup though may be fall under
the "to be developed.." category (for future development).
Not absolutely needed at this point.



3DObject is a class.
Geometry is a Structure inside the 3DObject class.

With all due apologies to boops boops,
hard coding platonic solids only gets one so far.

The way Perspective Scene works will have to be adjusted to allow for:
1.) reasonably handling much more complex models (with faces in the tens of thousands)
2.) allow loading of models/submodels, and saving of runtime edited models/submodels..maybe even whole scenes.


Here's what I thinking/imagining:

When a new 3DObject is created, the faces List collection is the sole required parameter (basically loading in the needed Geometry).

The sequence (when creating a 3DObject from the contents of a file):
You must start out specifying (loading) the 3D points (vertices).
Each 3D point will probably a Dictionary object specifying keys for X, Y and Z.

Then faces (3D polygons) are created from List (not an ArrayList) of 3D points.
Theses individual faces are then added into a List of faces that are fed into creating the 3DObject.


I would like for Faces and Edges and 3Dpoints to all have visible/non-visible options as well as
highlighted/non-highlighted options (for editing/dragging "specifier" purposes)


A SubModel list can then be created from/using at least one 3D object.




What about the gFill?

This is a set of variables set as 3DObject class properties (with proper getters and setters).
gFill, though, is an purely optional part of the instantiation of the 3DObject class.

This means a 3DObject can be rendered without any graphic fills (simply as a wireframe).


If specified, the gFill Structure contains a Integer value, representing the type of fill as well as
color/texture info associated with the type of fill specified.

This leaves open whatever special (custom) shader types that boops boops might come up with.

Thus the 3DObject class can contain up to three Structures (custom types):
  1. Geometry (corresponding roughly to the base Polyhedra class in the Perspective Scene codebase)
  2. optional gFill
  3. Positioning (which includes the mandatory Center property value and other optional values...such things as:
  • --A.) Camera - only one position (frustrum culling automatically handled)!
  • --B.) optional Lighting value(s) (if not ambient, then probably one or more spotlights)
  • --C.) Scale factor - this could be done at the level of a 3Dobject of any of the higher levels


The 3D file will also probably have a default scaling factor for the scene as a whole.



***Note: Transforms methods to include Scaling, Rotation, and X,Y,Z axial displacement.



None of the above is too far away from the way things are structured in the Perspective Scene code attachments to this thread right now.

Only added a scale-factor is new (from the 3DS loader code) and texture mapped gFilling is still something
that I can hope can be rolled in using the 4 point distort code.
"Highlighting" a face could be as simple as thickening the lines that mnake up the Edges.
"Highlighting" a 3DPoint could be easily accomplished by changing the shape or color over the selected 3DPoint (corner).

The above doesn't even require "upgrading" the rotation to use the quaternion class.


Anyway..this preliminary organizational scheme should (hopefully) give me the minimum amount of understanding I need
to further work on the StreamWriter FileIO coding.

Coercing the above hierarchical relationships into a flat .ini file will be a little involved..stay tuned (but be patient)..
Attached Images
File Type: jpg 3D_object_hierarchy_diagram.jpg (77.0 KB, 6 views)

Last edited by dotnetwrassler; 03-28-2015 at 05:31 PM.
Reply With Quote
  #68  
Old 03-29-2015, 12:59 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Update for .3ds file to .ini file converter

It's not quite as "cleaned up" as I would like, but attached 2e revision code works,
(i.e. nests vertices and faces under each sub-model sections when writing out .ini file)

Threw in a couple new .3ds models. Try the new "high poly" rounded cube.

The inifile for the LeonardoVehicle model ended up being over 8MB unzipped with over 91,000 vertices and just as many triangles.

Try writing out (hard-coding) that by hand into a Polyhedra inherits class code.

Next step - try to figure out how to load a 3D model (written out as an ini file) and then render it using the Perspective Scene code..
Attached Images
File Type: jpg screenshot-new_high_poly_rounded_cube_model-wireframe_render .JPG (131.0 KB, 4 views)
Attached Files
File Type: zip 3DS_file_to_Ini_file_converter2e.zip (675.7 KB, 18 views)
File Type: zip LeonardoVehicle_inifile.zip (1.80 MB, 17 views)

Last edited by dotnetwrassler; 03-29-2015 at 01:28 AM.
Reply With Quote
  #69  
Old 03-29-2015, 02:47 AM
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,058
Default

Quote:
Originally Posted by dotnetwrassler View Post
It's not quite as "cleaned up" as I would like, but attached 2e revision code works,
(i.e. nests vertices and faces under each sub-model sections when writing out .ini file)

Threw in a couple new .3ds models. Try the new "high poly" rounded cube.

The inifile for the LeonardoVehicle model ended up being over 8MB unzipped with over 91,000 vertices and just as many triangles.

Try writing out (hard-coding) that by hand into a Polyhedra inherits class code.

Next step - try to figure out how to load a 3D model (written out as an ini file) and then render it using the Perspective Scene code..
Just to push a non ini file solution again.... Using the Json serialiser it resulted in a file of *only* 4.7M , however the loading and rendering logic was only a few lines ofcode - no need to try and recreate things from your own custom format.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #70  
Old 03-29-2015, 03:05 AM
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,058
Default

Quote:
Originally Posted by dotnetwrassler View Post
Maybe a class?
Classes aren't just about functions and subs.
They also can contain variable and properties.
Which can be used to store a bunch of values.

But what I'm really think that a 3DObject data type should be
is like a UDT (user-defined data type) under VB6.

The closest equivalent that I know of in VB.Net is a Structure.
Structures are similar to UDTs, however they do have some differences, also classes and structures are very similar in how you use them in code.

As a general rule unless you have very specific reasons for choosing a structure you are probably better off with a class.

Quote:
Originally Posted by dotnetwrassler View Post
I had been thinking of storing the 3D points in a kind of Excel table (represented by a 2D array) where the columns would be X, Y, and Z
and the rows would be the list of such points.

The issue - a 3D "face" is basically a 3D version of a 2D polygon.
So you could have faces that use 3 points, 4 points, 5 or more points.

If you try merge all these face tables (2d arrays) into some kind of super array then it's going to end up being
a "ragged" (sparse) array where you are mixing 3 point faces with faces containing 100 points.
One possible structure I have seen used in other systems is you effectively have two arrays / lists - one is a series of 3d points and the other is a series of indexes into these points - as an example WPF / XAML does things this way to describe a mesh. this way you don't need to have multiple vertex entries for a point shared by multiple trianges.


Quote:
Originally Posted by dotnetwrassler View Post
I know using Dictionaries can be optimal over using a HashTable per this CodeProject test.
According to this StackOverFlow thread:
plus a dictionary is a generic type and therefore strongly typed.

Quote:
Originally Posted by dotnetwrassler View Post
No -it would have to be more complicated than that.
There could be multiple 3DObjects that make up each 3D "Model".
A 3DObject could contain a series of "simple" objects (faces, triangles or similar) or other 3DObjects, that way rendering a 3DObject would either render the primitives it contains or recurse through the 3DObjects it is made up off. This could allow an arbitrary nesting of objects.

Quote:
Originally Posted by dotnetwrassler View Post
There would also have to be a way to store "gFills" (either a tint color, a gradient of some type or a texture).
If a 3DObject had a property for the "gFill" then you could render the assigned gFill for an object or use the one from the parent 3DObject if nested and the current object doesn't have one.

EDIT:
Thinking about this a bit more you might find out that something as complex as a 3D renderer might need more than one overall model. You might have the 3D model for the logical design etc (ModelGroups, 3DObjects and their groupings etc) and then a much more basic model (Vertexes, textures) for the actual render to work with.

You would be loading and saving the more expressive 3D model and when you choose to render it you convert this high level model into a much more fundamental set of primitives for actually displaying on screen.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags

Last edited by PlausiblyDamp; 03-29-2015 at 03:20 AM. Reason: Further thoughts
Reply With Quote
  #71  
Old 03-29-2015, 08:14 AM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default

Quote:
Originally Posted by dotnetwrassler View Post
...
The inifile for the LeonardoVehicle model ended up being over 8MB unzipped with over 91,000 vertices and just as many triangles....
But you know by looking at your GUI which shows Total Vertices: and Total Triangles: above the listboxes, the numbers should be half those numbers.
You're adding the verticies and triangles to your list twice so you end up with twice the number in your ini file (at least the first time). If you save the ini file again, you'll add them again, so square the file size each time.

You should do a
str3DObjectsVertices.Clear()
str3DObjectsTriangles.Clear()
before starting your subobj loop in the SaveTransfer sub.

You're also messing up your vertices List by putting the triangle list at the front of it after loading a file or saving an ini.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #72  
Old 03-29-2015, 09:27 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Future ideas (..and a few corrections needed)

Quote:
Originally Posted by PlausiblyDamp
As a general rule unless you have very specific reasons for choosing a structure you are probably better off with a class.
The reason is because I've used UDTs under VB6 and that's what makes Structures so attractive.
Classes are more "hard core"..and also unique/original (hard to "pattern match" to establish a way of templating them in my mind).

But yes I do realize they are more powerful.
Unfortunately my understanding of them (like crafting good constructors) is limited/weak.
Quote:
Originally Posted by PlausiblyDamp
..series of indexes into these points...this way you don't need to have multiple vertex entries for a point shared by multiple triangles.
Yes.
A very interesting idea.
This "indexing" almost sounds something like something pointers do.

But I have no idea how to implement it.

There are so few large WPF samples written in VB.Net.

The best WPF ones I've seen are the Petzold examples and I have no VB.Net translation for them.

Working in some kind of mesh implementation to what we are doing would be highly desireable, though..

Most of the high poly (high polygon count) models uses meshes or have
very dense "mesh-like" planes (membrane surfaces?) made from tessellating triangle grids.

Quote:
Originally Posted by PlausiblyDamp
If a 3DObject had a property for the "gFill" then you could render the assigned gFill for an object or
use the one from the parent 3DObject if nested and the current object doesn't have one.
Yes.
I was thinking of this also (even though I didn't mention it).
If only I could get boops boops to adjust the Perspective Scene code to be more "texture friendly".
Getting gFill to work with that codebase means I need an "injection point" for texturing and right now the code is not structured in that way.

Quote:
Originally Posted by PlausiblyDamp
Just to push a non ini file solution again.... Using the Json serializer it resulted in a file of *only* 4.7M
I'm actually not worried about the size of the file.

I have a 16 terabyte NAS - multi-terabyte hard drives are relatively cheap
(and used ones are starting to show up more and more at FreeGeek,
where I can get computer components for pennies on the dollar --since I have/get a volunteer discount).

The reason I included the ini file zipped because I suspected something was a little off, and
I wanted someone (hopefully passel) to look at it.

And it looks like he did:
Quote:
Originally Posted by passel

You're adding the vertices and triangles to your list twice so you end up with twice the number in your ini file (at least the first time). If you save the ini file again, you'll add them again, so square the file size each time.

You should do a
str3DObjectsVertices.Clear()
str3DObjectsTriangles.Clear()
before starting your subobj loop in the SaveTransfer sub.

You're also messing up your vertices List by putting the triangle list at the front of it after loading a file or saving an ini.
Thanks.
I've take a look at making corrections for a future version..
I have switched to using Framework 4.0 and targeting for CPU "x86" (32 bit) while debugging based on your suggestion.



Note to passel:
If you have any time in the next month or so (I know you're day job keeps you very busy),
can you look at the render loop works for the import3ds code and compare it to how
boops boops rendering goes in the Perspective Scene attachments.

I still trying to work out some kind of "code correspondence" between the two code bases in my head (in pre-merger preparation)

The way the drag rotation happens in the Import3DS code is superior what's happening in terms of dragging for the PerspectiveScene code
and I would like to make it part of the final merge,
but all that nested looping..it's just too much to step thru in the IDE
so what's happening with the code is rather "opaque" to me.





The other thing - there is an issue with the scaling in the Import3DS code.

You'll notice it with the high poly rounded cube model.

If you scale up to fast (by too large an amount at one time) the model disappears from view.

What you end up having to do is:
1.) Move the model to the lower right hand corner.
2.) Scale up just a small amount
3.) Repeat

Eventually you can get it to scale up to the size you need
but having some kind of "auto center while scaling" option would definitely be preferable.

Last edited by dotnetwrassler; 03-29-2015 at 09:48 AM.
Reply With Quote
  #73  
Old 03-29-2015, 01:59 PM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default

Quote:
Originally Posted by dotnetwrassler View Post
Quote:
Originally Posted by PlausiblyDamp
As a general rule unless you have very specific reasons for choosing a structure you are probably better off with a class.
The reason is because I've used UDTs under VB6 and that's what makes Structures so attractive.
Classes are more "hard core"..and also unique/original (hard to "pattern match" to establish a way of templating them in my mind).

Unfortunately my understanding of them (like crafting good constructors) is limited/weak.
The reality is there can be little difference in how you use the Structure compared to a Class in VB.Net
If you create a structure, you can just change the word "Structure" to Class at the top and bottom and you have a class. As already mentioned in your reading, the primary difference is one is a value type and one is a reference type, so structures don't have a constructor and you don't instantiate them, just declare them. If you already had code using the structure, you would need to add code somewhere before you actually use them to instantiate the instance, but other than that additional line to create the instance, the rest of the code will usually work as written, although what is happening under the hood is different.
Likewise, you can often change a class to a structure just by changing the word Class to the word Structure. In that case you would remove the instantiations. If you had code in the constructor, you might want to move it into an Init routine so you can call it to initialize some components of the structure in place of the constructor.
Bottom line, if you're willing to use a Structure, a Class doesn't have to be any more "complicated" then what you would do to create a Structure.
Quote:
Originally Posted by dotnetwrassler View Post
Quote:
Originally Posted by PlausiblyDamp
..series of indexes into these points...this way you don't need to have multiple vertex entries for a point shared by multiple triangles.
Yes.
A very interesting idea.
This "indexing" almost sounds something like something pointers do.

But I have no idea how to implement it.
Perhaps you don't realize that
1: that is a common thing to do, and
2: that is what the Import3DS code is doing.
Just look at the list boxes. The bottom list box is the list of triangles, and the three numbers in the triangle object are indexes ("pointers") to the 3d coordinates in the Vertex list.
With the default object that is displayed when you start the program up, look at Triangles 1, 4 and 6. Those three triangles share Vertex 1 (57.29, 57.29, 57.29) as one of their corners.
Quote:
Originally Posted by dotnetwrassler View Post
...
Quote:
Originally Posted by PlausiblyDamp
Just to push a non ini file solution again.... Using the Json serializer it resulted in a file of *only* 4.7M
I'm actually not worried about the size of the file.
As noted, the files size between Json, XML, or ini should be fairly close in size. The ini file was built incorrectly which accounts for its larger size.
Probably, as the ini file is a fairly simple text structure, the size order will probably be .ini, Json, XML, but with not that much difference in size.
If I wanted to create a text based implementation, I would probably try XML, as it should be built in to .Net without having to grab any third party implementation, although I get the impression that Json is probably a simpler structure.
I also haven't dealt with Json or XML really at this point, but would be inclined to try the XML as I have used Binary Serialization in .Net so XML serialization would probably be just a matter of choosing a different serializer/deserializer object so be transparent to my existing code otherwise.
Quote:
Originally Posted by dotnetwrassler View Post
Note to passel:
If you have any time in the next month or so ...,
can you look at the render loop works for the import3ds code and compare it to how
boops boops rendering goes in the Perspective Scene attachments.
The way the drag rotation happens in the Import3DS code is superior what's happening in terms of dragging for the PerspectiveScene code
and I would like to make it part of the final merge,
but all that nested looping..it's just too much to step thru in the IDE
so what's happening with the code is rather "opaque" to me.
The drag rotation in the Import3DS code is not necessarily superior. It is actually quite simple.
If you drag left and right it just adjusts the rotation angle value of the Y axis.
If you drag up and down it just adjusts the rotation angle value of the X axis.
I haven't looked at the more recent versions of boops boops code, so don't know what improvements have been made, but the original code had a common flawed implementation that most programmers would start with initially, and that is by defining the object coordinates in "World" coordinates, rather than in Model coordinates.
Then to move or rotate the object required adjusting those coordinates in World coordinates to move it around the screen.
Later, the idea of a "Center" coordinate, still in world coordinates, to identify where the object's center is was added, so you could translate the object to 0,0, do the rotation and translate back to rotate the object, but this modification of the objects coordinates to define its location and orientation in space while being intuitive, and giving some immediate joy when rendering, is cumbersome to use as it mostly only allows relative movement.
You can rotate the current state of the object in any direction by some delta values, but if I were to ask what was the current pitch, roll and yaw of the object, would it be easily answered?
Would I know how to rotate it back to a 0,0,0 (roll, pitch, yaw) orientation to set it down on a flat surface?
I don't know if those issues have been addressed.

On the other hand, the Import3DS generally maintains the graphics object the way one would expect, if they had more experience with 3D objects, or had time enough to "discover" these needs on their own.
You have a list of objects (called subobjects, which could only be one in most of the cases you have).

Each object has a list of 3d points (aka vertexes or vertices), which defines all the points associated with the object, and are in object space. The coordinates 0,0,0 would normally be the reference point of the object, and the center of rotation of the object, unless a 3d offset was provided.
<In my line of work, there usually is an offset to the center of rotation. The 0,0,0 coordinate of the model is often a point where the model would touch the "ground", so an altitude of 0.0 would have the wheels on the ground, but once in the air, you would want the model to rotate around its center of gravity (cg), which would not be at the 0,0,0 point>.

Each object has a list of triangles, each triangle made up of three pointers (indexes/indices) to a coordinate from the objects vertex list.

These lists of vertices and triangles are never modified. To place the model in World space, you would transform the points writing them out to a new array, and use those transformed points to draw the current state of the object.
In the case of Import3DS, it simply applies the rotation around the X and Y axis, and scales the numbers by the Scale factor. It writes the results out to the ArrayList, points2DMainArray, which is indexed by the subobject index.

Import3DS does no perspective calculations, does no Z-Ordering of the rendering, and defaults the 0,0 2D "World" coordinate (since there is no perspective, the Z coordinate only applies to calculating the new 3d coordinates in model space when rotating the model, it has no effect on the rendering so all the points for rendering are 2D, as are the "World" coordinates).

Since the model's original coordinates are never modified, they always represent an original 0,0,0 roll, pitch and yaw of the model. You can set the models roll, pitch and yaw to any set of values, and then transform the original points to their new positions.

Quote:
Originally Posted by dotnetwrassler View Post
The other thing - there is an issue with the scaling in the Import3DS code.

You'll notice it with the high poly rounded cube model.

If you scale up to fast (by too large an amount at one time) the model disappears from view.
...
Eventually you can get it to scale up to the size you need
but having some kind of "auto center while scaling" option would definitely be preferable.
I already made some changes in a previous version of the code to handle the rendering in a more user friendly manner. I basically was looking at some optimizations.
Primarily, the use of .Refresh over .Invalidate is used too often, which makes the scaling more difficult for the user.

1, there is a .Refresh in the MouseDown event. There is no reason for it being there. Nothing has changed state as a result of a MouseDown in the picturebox, so I removed it.

2, there is a .Refresh in the MouseMove event. This causes the MouseMove event to hang while the paint event is being processed to redraw the picturebox. Meanwhile, there are more MouseMove events coming in, so they will be processed in turn, with a full drawing being done with each event processed. Since the drawing is much slower than the mouseevents, you don't want to do the drawing inline. Make that a .Invalidate so multiple move events can be processed between redraws, to keep from building up a backlog of events and drawing.

3, the NumericUpDown+Scale_ValueChanged event. The same, or possibly worse, than the MouseMove event. You spend all your time drawing, so can't see the NumericUpDown text changing to even know where your scale value is until all the drawing is done. It is easy to scale to 0 in that case, so draw nothing. Change that to an .Invalidate, and you should have more control over the scaling.

Reached 10,000 limit. Have to stop here.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-29-2015 at 03:03 PM.
Reply With Quote
  #74  
Old 03-29-2015, 03:04 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default re: passel's code analysis

Quote:
If you had code in the constructor,
you might want to move it into an Init routine
so you can call it to initialize some components of the structure
in place of the constructor.
I understand you don't instantiate structures, you just declare them.
Then you lost me: Structures have Init routines?

edit1:
Found this MSDN article which says:
Quote:
In Visual Basic 6.0, all members of a user-defined type (UDT) were initialized when they were declared..
In VB.NET, user-defined types are replaced by structures.
Members that require parameterless constructors..require initialization.
During upgrade, an Initialize() subroutine is added to the structure. Calls to the Initialize subroutine must be added whenever the structure is declared.
I tend to see "Public Sub New(" more than I see "Public Sub Initialize()"

Per this page:
Quote:
We do not need to use a New Sub (a constructor).
So neither New() or Initialize() are really mandatory?

Quote:
Perhaps you don't realize that
1: that is a common thing to do, and
2: that is what the Import3DS code is doing.
..the three numbers in the triangle object are indexes ("pointers")..
They were all just numbers to me.
No I didn't realize some were indexes.

Quote:
The drag rotation in the Import3DS code is not necessarily superior. It is actually quite simple.
Simple for you!

The reason I say it's superior is that the in the Perspective Scene code you can't actually rotate in three dimensions at all.
I believe you can just drag in 2D in the x and y directions.
The platonic solids can't really be drag-rotated around in a pitch/yaw kind of way..

Quote:
I haven't looked at the more recent versions of boops boops code, so don't know what improvements have been made, but the original code had a common flawed implementation that most programmers would start with initially, and that is by defining the object coordinates in "World" coordinates, rather than in Model coordinates.
Then to move or rotate the object required adjusting those coordinates in World coordinates to move it around the screen.
Later, the idea of a "Center" coordinate, still in world coordinates, to identify where the object's center is was added, so you could translate the object to 0,0, do the rotation and translate back to rotate the object, but this modification of the objects coordinates to define its location and orientation in space while being intuitive, and giving some immediate joy when rendering, is cumbersome to use as it mostly only allows relative movement.
You can rotate the current state of the object in any direction by some delta values, but if I were to ask what was the current pitch, roll and yaw of the object, would it be easily answered?
Would I know how to rotate it back to a 0,0,0 (roll, pitch, yaw) orientation to set it down on a flat surface?
I don't know if those issues have been addressed.
No it basically hasn't changed.

..and no it's not more intuitive for me (maybe for boops boops).

Oh, did you read in post #52 where boops boops admitted:
Quote:
Originally Posted by boops boops
The 3DScene code has its "world" coordinates locked to the "device" coordinates: X and Y are always screen X and Y.
It makes several things easier, but it may turn out to be a limitation.
In trying to merge the two codebases together I improve it by incorporating a bit of the Import3DS rendering code.

By the way, none of the code samples I looked at had the ability
to precisely answer the questions you had at the end of that extended quote above.

I wanted one that could show the vertices and let you edit/adjust each individually in a textbox or with spinner/trackbar/slider controls.
This level of fine tuning control just was not there in all the open source demos I looked at.
The closest was the small incremental transform/rotation changes that could be made via button pressing using the quaternion code.

Even for that one setting things down on a flat surface is impossible.
I have a hard time doing that in 3D Studio Max, Maya, and Sketch-up.

The "snap to" feedback (when you are trying to align anything with anything else),
is really just not there in most commercial 3D editing programs.
And it would certainly help..as you struggle to use a 2D mouse in a 3D space.

Quote:
On the other hand, the Import3DS generally maintains the graphics object the way one would expect,
if they had more experience with 3D objects, or had time enough to "discover" these needs on their own.
So basically one is using model coordinates and the other is using World coordinates.
Great.
Sounds like a Grand Canyon of a code gap/difference between them.

Quote:
Originally Posted by passel (with my editing)
Each object has a list of 3d points (aka vertexes or vertices), which defines all the points associated with the object, and are in object space.

Each object has a list of triangles, each triangle made up of three pointers (indexes/indices) to a coordinate from the objects vertex list.

These lists of vertices and triangles are never modified.

In the case of Import3DS, it simply applies the rotation around the X and Y axis, and scales the numbers by the Scale factor. It writes the results out to the ArrayList, points2DMainArray, which is indexed by the subobject index.
I understand what you are saying (in this edited version of what you said).

The rest of it regarding "0,0,0 (roll, pitch, yaw) orientation" and coordinate spaces went over my head.

Is it anything like on this page:
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx

I found this page which says:
Quote:
A vector space is a mathematical structure that is defined by a given number of linearly independent vectors..

When an artist authors a 3D model he creates all the vertices and faces relatively to
the 3D coordinate system of the tool he is working in, which is the Model Space.
All the vertices are relative to the origin of the Model Space

It's important to understand that a vector only makes sense within a coordinate system; if we don't specify the space we can't represent any point.
I sorta understand that.
I even got a little further (into the section on "transformations in a vector space"), because it had some understandable diagrams (which was helpful).
Then I got to the matrix math and my eyes started to glaze over (Sorry).

Down towards the end of the article it talks about "Model Space, World Space, View Space" and
I actually got something out of (half-understood) the article's discussion of view-space in relation to projection space.
A "view space" is basically a viewport, right?
The whole projection thing reminds me of some of the diagrams for frustrum culling.

Quote:
<In my line of work, there usually is an offset to the center of rotation. The 0,0,0 coordinate of the model is often a point where the model would touch the "ground", so an altitude of 0.0 would have the wheels on the ground, but once in the air, you would want the model to rotate around its center of gravity (cg), which would not be at the 0,0,0 point>.
Yours is the superior expertise in this area.
I respect what you are saying, but what seems easy for you to understand (because you work with it all the time),
is nearly impossible for me to fully grasp.

Of course if there were a lot of .Net 3D coordinate space code (that didn't use OpenGL, Direct/XNA or WPF),
I could look at multiple code samples and try to understand things by comparing the coding differences.
I can't really exploit that in this case.

Quote:
Originally Posted by passel
Since the model's original coordinates are never modified, they always represent an original 0,0,0 roll, pitch and yaw of the model.
You can set the models roll, pitch and yaw to any set of values, and then transform the original points to their new positions.
This actually sounds like a good thing.
Would you say that is superior (more "coding correct") approach to what the boops boops code is doing with World coordinates?

It "feels" superior - I can position the models better.
I think from the perspective of an average user
(not necessarily someone who has spent a lot of time in 3D editors)
it would seem to be more intuitive.

Quote:
Originally Posted by passel

I already made some changes in a previous version of the code to handle the rendering in a more user friendly manner.
Definitely thanks for all your help so far..

Quote:
3, the NumericUpDown+Scale_ValueChanged event. The same, or possibly worse, than the MouseMove event.
You spend all your time drawing, so can't see the NumericUpDown text changing
to even know where your scale value is until all the drawing is done.
It is easy to scale to 0 in that case, so draw nothing.
Change that to an .Invalidate, and you should have more control over the scaling.
I looked at all three points and they all appear valid,
but in regard to "having more control over scaling" this doesn't really answer specifically:

"How can one use the 'more control you get over scaling' to provide auto centering of
the model after the scaling numeric adjustments are done internally,
but before the model is re-rendered at a different size (in Model space maybe)?"

It seems like there has to be some kind of transform applied to do this..I
just don't know what that transform might/would be.

Last edited by dotnetwrassler; 03-29-2015 at 05:42 PM.
Reply With Quote
  #75  
Old 03-29-2015, 05:32 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Some extra stuff on VB.Net Structures..

I reached my 10,000 limit in my response to passel above,
but I wanted to include a few extra links on Structures.

Here is the Tutor's Corner thread on Structures in VB.Net, where it says:
Quote:
No Initialization in Structures
Some of the most common mistakes I know I'm guilty of when working with structures is
forgetting that structures cannot be initialized.
In other words, you can't do this:
Code:
Private Structure tUsers
    Dim sFirstName As String = "John"
    Dim sLastName As String = "Doe"
End Structure


Some of the links in that old Tutor's Corner thread are broken, so here's some others:

An oldie: MSDN :Using Classes and Structures in Visual Basic .NET 2003
Summary: This article is intended to help developers choose between a class and a structure when writing an application.

MSDN: Structures and Classes
Has lists of similarities and differences.

MSDN: Structures and Other Programming Elements (Visual Basic)
Towards the bottom its says:
Quote:
You can pass a structure as a procedure argument.
You can also return a structure from a Function procedure.
Yow!
I would never have thought of doing either of those two things..

This Code Project article says:
Quote:
The default accessibility for a structure is Public.

You can use Private, Protected and Friend keywords also. You must specify accessibility for every member you declare inside a Structure.

If you declare them with Dim statement, they are considered as Public.

If you assign one Structure variable to another, a new copy is created in the other variable.
Hence the changes to the values of first variable does not happen to the second.
I'm used to Dims at the top of forms defaulting to Private,
so this is a little weird/different..

Last edited by dotnetwrassler; 03-29-2015 at 05:46 PM.
Reply With Quote
  #76  
Old 04-02-2015, 07:22 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Getting "coordinated" in a 3D space and code limitations/flaws

To passel - please see the auto-centering question at the bottom of my post #74 (and the related question*** below).



I have been thinking about passel's analysis of the way the Import3DS code and boops boops perspective scene code handle 3D models in a 3D space.

3D points (or vertices) are basically a sequence of 3 numbers representing X, Y and Z values.

Ah, but when you say "values" - what exactly are these values referring (making reference) to?

They are referring to relative positions in some kind of coordinate space.
(a little light bulb should go on in your head at saying this - in my dimwitted notions took a while for this light bulb to come on).



Let us (at this point - pun semi-intended) make a point of giving a link to the Wikipedia article on the Cartesian coordinate system.

The article starts out with the classic 2D graphing that most of the readers of this thread may remember
from their high school trig/geometry class (I guess I was pretty much "mentally checked-out" at this point in high school --
had other things going on that were of more concern to me).

If you scroll down the Wikipedia article page, though, it has a section on "A three dimensional Cartesian coordinate system".

Going to a 2D Cartesian coordinate system to a 3D Cartesian coordinate system not only involves a "dimensional leap" but also a leap in thinking.

Because just below that the article notes you can have "coordinate surfaces",
which (if you follow the link) takes you to this page:
http://en.wikipedia.org/wiki/Coordin...dinate_surface

where it says:
Quote:
In three-dimensional space, if one coordinate is held constant and the remaining coordinates are allowed to vary, then the resulting surface is called a coordinate surface.
Does that statement make you feel like you've taken the red pill and started down the rabbit hole?

It does to me.

How about this quote (from further on down the page of the original article):
Quote:
Cartesian coordinates are an abstraction that have a multitude of possible applications in the real world. However, three constructive steps are involved in superimposing coordinates on a problem application. 1) Units of distance must be decided defining the spatial size represented by the numbers used as coordinates. 2) An origin must be assigned to a specific spatial location or landmark, and 3) the orientation of the axes must be defined using available directional cues for (n-1) of the n axes.
The emphasis on the word "abstraction" is mine - it's basically saying "we're creating our own mathematical version of "reality".

Let's step back for a moment from this abyss and go back to 2D space.
Whew!
The "unreality" (no standard absolutely "correct" way) involved in creating a 3D coordinate system can be daunting.






Even for 2D coordinate systems, the matrix math for mapping points between [multiple] 2D coordinate systems is not simple.

Fortunately for most programmers Windows provides one standard way of dealing with it's own internal world coordinate system.

However, as noted on this MSDN Coordinate Spaces and Transformations page:
Quote:
There are four coordinate spaces: world, page, device, and physical device (client area, desktop, or page of printer paper).
So here's the long and short of things:
No matter which 3D coordinates spaces you decide to use (a "world coordinates" space or a "model space")
you still have to translate whatever theoretical abstraction of 3D coordinate space you make up
into a 2D "view space" that is tied to a device or "physical device" space.



The quaternion code (attachments to post #4, #8, & #32), besides being the only one that uses quaternions for rotation,
also does a few other things that the codebases for 3DSImport and boops boops' PerspectiveWarp/PerspectiveScene do not:
1.) The code allows texturemapping
2.) The code has a different way of doing "view projection" that allows a rotated camera view that seems to be separate
from the actual mathematical rotation of the model (in "world space" or "model space" I couldn't say for sure).

This is the key to understanding things for me.
boops boops code moves the 3D points in world coordinate space (which is "locked" to device space).

The 3DSImport code is basically (in my way of thinking) moving only a camera viewpoint around in "model space".




What passel failed to explain is the implications of this.

All coordinate systems have embedded within them the concept of "origin".
The origin is important for a variety of reasons.

One of them is that it is frequently used as the "pivot point" around which rotations occur.

Perhaps many of the readers of this thread are wondering "where is dotnetwrassler getting all these really interesting .3ds test models?"

Good question! (thanks for asking)

Although I have a very old copy of 3D Studio Max (and could create them manually),
it's actually very tedious and time consuming to try and create anything in the 3D Studio Max editing software,
because in terms of workflow within the software there are dozens of individual steps
to doing what should be seemingly simple things.

For example - you want to create 2 cubes and attach/connect one of the corners of one cube at an angle to the other cube.

Just the "aligning-of-the-two-cubes" part could take several minutes.

Then once the alignment part is complete you have to "break apart" the lines leading to the corners in questions for both cubes,
then "merge" the broken pieces back together and then
get everything to "reconnect" properly.
This break-merge-reconnect could take hours (sometimes days with a lot of undo-es)

So I'm using Sketchup (which used to be a Google product and is now owned by Trimble Navigation).
The basic (free version) is useless to me because it has no .3ds export.
Only the "Pro" version does that.

However I was able to get a "trial" (30 days only) version of Pro to be able to use the models from their (Google and Trimble's) "3D Warehouse".

The things is, though, when you import a 3D warehouse model it is never automatically placed on the origin
(so it will export properly to .3DS with the center of rotation being the 3D middle/center of the model).

This matters because when the .3DS model is opened up by the 3DSImport code it may not even show up (until you put the scale value to the right place).

So here is what I am conceptually imagining is happening with the 3DSImport code.

As passel says - the 3D Points (vertices) never undergo any kind of transformation (scaling, rotation, etc).

Instead what is happening when you adjust the scaling is that the model gets "pushed back" by the "view projection" provided by its internal camera system.

This "push back" view adjustment is directly tied in with whether the origin is:
1.) in the center of the model
OR
2.) somewhere external to the model.

If it's external to the model then the scaling appears to do an x-y positional transform
(so you have to keep moving the model back to the center of the viewport after each scale operation).

Even worse - if you try to use the rotation-type dragging,
what seems to happen is that the "camera" (used for viewing in the object in a 3D)
will rotate around the origin.

End result - if the origin point is external to the model, this camera rotation will cause even a small rotation drag attempt to "jump" the model out of view.



***
Quote:
Originally Posted by (question for passel)
Is there a way to reset the origin of the "model space" by adjusting the vertices (3D points) of the model somewhere inside the 3DSImport code?

There doesn't appear to be - unless passel knows how it can be done.

I finally realized that's the major flaw of the 3DSImport code - it has no "built in" transform functions.

The difficult task that lies ahead for me --I've got to make a 3Dobject class that translates the .3ds "model space" coordinates (saved to an .ini file) into "world space" coordinates so it can be imported (and viewed/rendered) by boops boops code.

What I'm thinking (as a useful half step to make this "leap") is to create a TriangleStrip class from the Tetrahedron class.

Then trying randomly poking in some random 3DPoints and (tediously) creating multiple triangle Faces joined together.

Then I step through the newly working code and extract the needed 3DPoint/TriangleFace values where I can use to make up an inifile to be imported.

Then write some special ini file import code using StreamWriter.

All that I believe I know how to do - the tricky part is linking/coercing the StreamWriter data into one of boops boops' Polyhedra base objects.



I've got to work today and tomorrow, so I'll shoot for the end of the weekend to at least have the TriangleStrip class done.

Last edited by dotnetwrassler; 04-02-2015 at 08:05 AM.
Reply With Quote
  #77  
Old 04-03-2015, 11:33 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Towards extrapolating vertices (Point3Ds) for a new TriangleStrip class

I've semi-completed task 1 of 4 from the previous post's roadmap:
Quote:
1.) create a TriangleStrip class from the Tetrahedron class.
I'm midway through task 2 of 4:
Quote:
2.) Poke in some semi-random 3DPoints and (tediously) creating multiple triangle Faces joined together..
The attached new PS6 code represents the old PS2 code (attached to the post #40),
merged with the octs and isos code attached to post #48.

This gives the ability to drag-move all the platonic solids,
plus distort the 3D primitives by using vertices (Point3D) dragging.

Note: I also had to merge in some "glue" code from the PS5 code attachment to post #47 to get everything to work.


I've also added in a File menu for the first time to the boops boops code (in anticipation of tasks 3 & 4):
Quote:
3.) I step through the newly working code and extract the needed 3DPoint/TriangleFace values which I can use to make up an inifile to be exported.

4.) Then write some special ini file import code (using StreamWriter) that will create PerspectiveScene objects at runtime.
Adding the file menu meant I had to do a minor re-arrangement the form layout, however.

The working code PS6 attached below will also display (in the title bar of the form, represented by the Me.Text property of the form)
the vertices for Point A (the lower right hand corner of the a TriangleFace, produced by the new TriangleStrip class).
See attached screenshot below of the Point A that can be dragged
to show the vertices numbers moving in the title bar of the form.

Until I can get the user interface to show the x,y,z values all 3 vertices (A, B, and C),
I can't really extrapolate points D, E, and F) for the the adjoining trianglefaces that make up a complete trianglestrip.
(as distinguished from the "triangle fans", mentioned in post #37, that share a central vertex).



Future issues (to be overcome)....

Getting to this point I now realize I'm going to have to do a major re-arrangement the form layout, though.

Even lengthen the form width-wise to accommodate the 5 3D objects,
there is not enough room in the form's titlebar to display the x,y,z values for three or more Point3Ds (vertices).

I wish I had the special scrolling message box form from the earlier ini convertor code already included in the boops boops project,
but I don't..

Thinking about the user interface for future Perspective Scene revisions,
I'm considering that it might be helpful
to have an integrated debug panel directly on the form.

While this will be a bit of work, it may be helpful with the final task of this series:
5.) Find a way to instantiate 3D primitives, using the base Polyhedra class,
in such a way that the vertices/trianglefaces data,
when loaded from a file using StreamWriter,
can generate Point3Ds, Edges, and Faces.

I find it very hard to work with these class objects.
I have never done class instantiation using data loaded from a file at all -- much
less from using 3D data and classes developed by someone else.





This thread is feeling very lonely at this point.
I wish I had someone to help me with those "Future Issues" cited above.
But passel hasn't posted in response to my auto-centering issues above so
maybe he's to busy with a day job to really "dig in" to providing major code help in this thread.
Maybe he thinks everything posted so far is just too "trivial" (and simplistic) to be worth his bothering.





I hope boops boops, though, is still with me "in spirit" -- even though
post #52 (in the middle of March) was the last boops boops post.




*****For boops boops only (all others please ignore)**********

If, at some point point, there may be discovered/invented some GDI+ extended VB.Net code
that can do quaternion rotation using spherical coordinates,

One of the the things that may be necessary in developing such code
is an understanding of SLERP-ing (Spherical Linear intERPolation) --using the "great circle" of a 4-D unit sphere, of course.

There is a nice pdf slide show here.

On page 5 (of the above linked to pdf) it talks about "interpolation with smooth velocities".

Which eventually (if you do a bit of searching) will lead to this StackOverFlow thread on:
"Finding quaternion that representing the rotation from one vector to another",
which seeks to answer the question:
Quote:
I have two vectors u and v.
Is there a way of finding a quaternion representing the rotation from u to v?


It should be noted at this point we are leaving behind any hope of finding VB.Net code to do these things,
It's even rare to find code for quaternion manipulations/transforms mentioned in a C# context that doesn't involve DirectX/XNA, WPF, or OpenGL.



That StackOverFlow post leads to:
Quaternion from two vectors: the final version
How do I use quaternions to perform linear interpolation between matrices?

The big discovery (following the links off that StackOverFlow page) is the Quaternion pages of the http://www.euclideanspace.com site.


I'll start out with this one (because it has a nice diagram):
Maths - Quaternion Interpolation of rotation by half
Here's some others:
Maths - Quaternions
Maths - Quaternion Arithmetic
Maths - Quaternion Notations
Maths - Transformations using Quaternions
Maths - Rotations using quaternions - Samples in 90 degree steps

Why am I posting these links instead of the MSDN equivalent pages?

Because the MSDN simply does not have pages equivalent to these.


If you do a search for "MSDN Quaternions" you'll find DirectX pages (like this one), WPF pages (like this one) and XNA pages (like this one).


What if you searched for "MSDN Quaternion Tutorial".
You probably end up with the pretty much same SERP (search engine results page).

You've got to go digging in the MSDN forum to find pages like this one,
which, although it's in the XNA part of the forum,
does contain some useful general info:

Quote:
I guess that won't make much sense if you don't know what a quaternion is. The mathematical explanation is complex and I've stopped caring about it. If you remember complex numbers from high school, then I'll warn you beforehand that quaternions are much much weirder. A quaternion is a 4 dimensional number. Mind you, I mean a 4 dimensional number, not a vector of 4 elements. For comparison, a complex number is two dimensional. That's why I tell you that quaternions are even weirder.

For 3D game development, however, it is useful to simply think of a quaternion as a rotation about an arbitrary axis. That is, a single rotation around a single arbitrary axis.

As I said, the quaternion is a weird beast. I'm not going to pretend to understand it. The following are some traits of quaternions worth knowing, however:

Quaternions can fully represent the orientation of an object in 3D space (much like the directional vector and a rotation described before, although it can't represent the magnitude)
Quaternions can also represent a rotation around any axis in 3D space (not just the X, Y, and Z axis like Euler rotations)
If you multiply a quaternion representing an object's orientation by a quaternion representing a rotation, the coordinate system used to define the axis of rotation is the rotational quaternion is from the object's space (it is defined by the object's orientation)
If you multiply quaternions representing a series of rotations together (in order), then the resulting quaternion is able to apply those rotations in one operation (much like matrices)
The euclideanspace pages offers (at the very least) a much more rigorous (math-oriented) way of understanding quaternions,
(rather than the more general explanations offered --of which the above MSDN forum post quote is an example).

Hopefully boops boops will take a look at some of these links in order to better understand
how to make the PerspectiveScene code incorporate using quaternion rotation
(using the working VB.Net Quaternion class inside the attachment to post #4).
Attached Images
File Type: jpg screenshot-PS6_with_pointA_labeled.JPG (51.5 KB, 8 views)
Attached Files
File Type: zip PS6c_alphaTriangleStripClass__Shows_Dragged_Point3D.zip (158.4 KB, 22 views)

Last edited by dotnetwrassler; 04-04-2015 at 12:25 AM.
Reply With Quote
  #78  
Old 04-04-2015, 08:24 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default A twisty triangle control for my integrated debug panel

It's really hard to believe that no one has ever posted any VB.Net code for turning a control into a twisty triangle (),
but searching the xvbt forum I didn't find any such controls/code.

They are (in the apple / mac world) also known as a "disclosure triangle" --used in OutlineViews controls.

In HTML5 the disclosure widgets are known as a "details" elements (associated with a summary elements).

Anyway..no matter what you call them they are not one of the standard .Net controls so I had to make my own.

The working demo should attached.

Now (at last) onto the debug panel itself..




Edit1:
It looks like boops boops is helping with this twisty triangle demo as well.

Found this post from another forum where he recommends:
Quote:
2. Use a thicker pen than default because otherwise the border will be clipped by the region.
So I changed the pb1 paint to:
Code:
Private Sub pb1_Paint(sender As Object, _
		e As System.Windows.Forms.PaintEventArgs) Handles pb1.Paint
  Dim pen1 As New System.Drawing.Pen(Color.Black, 3)
  Dim MyPath As New Drawing2D.GraphicsPath
  e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
  MyPath.Reset()
  If blnTwistPaint = False Then
    MyPath.StartFigure()
    MyPath.AddLine(0, pb1.Height, 0, 0)
    MyPath.AddLine(0, 0, pb1.Width \ 2, pb1.Height \ 2)
    MyPath.CloseFigure()
  Else
    MyPath.StartFigure()
    MyPath.AddLine((pb1.Width \ 4), 0, pb1.Width \ 4, 0)
    MyPath.AddLine(pb1.Width - 30, 0, pb1.Width \ 2, pb1.Height - 5)
    MyPath.CloseFigure()
  End If
  e.Graphics.DrawPath(pen1, MyPath)
End Sub
Attached Images
File Type: jpg screenshot_twisty_triangles_demo.JPG (23.7 KB, 2 views)
Attached Files
File Type: zip Twisty_Triangle_Demo.zip (47.1 KB, 12 views)

Last edited by dotnetwrassler; 04-05-2015 at 10:47 AM.
Reply With Quote
  #79  
Old 04-05-2015, 08:15 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default PS6 with major user interface overhaul

New features:
1.) Working TriangleStrip Class
2.) Debug Info panel with twisty triangle reveal
and customize (owner-drawn) tab control
3.) Expand-collapse button for toolstrip control, using shaped picturebox
Since I had to move the toolstrip somewhere, after I put in a File menu on top,
I decided to move it to the right side and make it collapsible
to maximize amount of form width taken up by the main picturebox)

Note: Though this was a lot of work for seemingly little benefit,
I would never have been able to guess at the X,Y,Z values
for vertices D and E without the debug info provided for vertices A, B, and C.

The main issue still remains: how to instantiate class objects at runtime
using data read from an ini file.

Will have to spend some time fighting with the .Net IDE to see what way it will let me do this..
Reply With Quote
  #80  
Old 04-06-2015, 12:40 AM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default

One of the main issues with posting is the large amount of things that could be posted about coordinates systems, rotations, problems with the code, etc. and it is hard for me to decide what do I really have the energy to get into.
But, as it is the start of another week, I need to choose at least a few things and get them posted, and let other stuff go, or I'll put off posting indefinitely.
Quote:
Originally Posted by dotnetwrassler View Post
...
<About the rotation in Import3DS>
The reason I say it's superior is that the in the Perspective Scene code you can't actually rotate in three dimensions at all.
I believe you can just drag in 2D in the x and y directions.
The platonic solids can't really be drag-rotated around in a pitch/yaw kind of way..
In the earlier PerspectiveWarp code, e.g. post #28, you could rotate all three axis using the left and right mouse buttons.
Post #29 modified the right button drag to reverse the rotation around the Z-axis depending on whether the mouse was above or below.
In the later platonic solids, I guess those drags were replaced with the other uses for the mouse to drag shapes around, or modify the shapes.
But you still have the rotations available, and exercised by the two boolean toggles on the left.
If you wanted to do rotations similiar to the Import3DS code, that would be just using the mouse to do the same adjustments to the "Rotate scene" capabilities as was done in posts #28/29.
The rotations wouldn't apply to the individual solids. In the Import3DS code, the mouse movement only affects rotation around two of the three axis and applies to the whole scene (the whole collection of subobjects), not to individual subobjects.
If, like Import3DS, you rotated only the scene, and never move or rotated the individual items, then that would be a simple thing to do. But since you can move the solid from its initial position, and can rotate them, then when you do, the scene rotation goes wacky. I assume it is because the center position is not rotated along with the rest of the verticies, but it may be more than that. I think you will need a different paradigm for rotating and positioning the solids in the perspective scene code to make the this work propertly.
Quote:
Originally Posted by dotnetwrassler View Post
...
The rest of it regarding "0,0,0 (roll, pitch, yaw) orientation" and coordinate spaces went over my head.
I started a long disertation, but really ran out of steam.
I guess I'll just post a link to some PDFs for a "real world" usage, that I deal with in the Simulation arena.
ICDs for the CIGI standard.
If you look at the 3.3 version, there are sections in there describing views, and another on orientation (3.4.1.2). And some more of the model orientation information is gone over in 4.1.2 when describing the Entity Control packet.
While CIGI uses NED as their coordinate sytem,I've also seen ENU (East,North, Up), so the nose of the aircraft points north along the Y axis, and the Wing would be East along the X axis, with Z positive in the "Up" direction.
I've seen others as well.
Quote:
Originally Posted by dotnetwrassler View Post
...
"How can one use the 'more control you get over scaling' to provide auto centering of
the model after the scaling numeric adjustments are done internally,
but before the model is re-rendered at a different size (in Model space maybe)?"

It seems like there has to be some kind of transform applied to do this..I
just don't know what that transform might/would be.
Quote:
Originally Posted by dotnetwrassler View Post
...
...
The 3DSImport code is basically (in my way of thinking) moving only a camera viewpoint around in "model space".
...
All coordinate systems have embedded within them the concept of "origin".
The origin is important for a variety of reasons.

One of them is that it is frequently used as the "pivot point" around which rotations occur.
...
So here is what I am conceptually imagining is happening with the 3DSImport code.
...
what is happening when you adjust the scaling is that the model gets "pushed back" by the "view projection" provided by its internal camera system.

This "push back" view adjustment is directly tied in with whether the origin is:
1.) in the center of the model
OR
2.) somewhere external to the model.

If it's external to the model then the scaling appears to do an x-y positional transform
(so you have to keep moving the model back to the center of the viewport after each scale operation).

Even worse - if you try to use the rotation-type dragging,
what seems to happen is that the "camera" (used for viewing in the object in a 3D)
will rotate around the origin.

End result - if the origin point is external to the model, this camera rotation will cause even a small rotation drag attempt to "jump" the model out of view.
I mentioned that the rotation (and scaling) in the 3DSImport code was simple because it doesn't really have any 3D projection and doesn't operate in the way you've guessed at all.
There is no camera view, and it is not moving the model in depth, i.e. moving the camera closer or further away to scale the image.
It is a simple 2d plot of points, or lines connecting points.
When you drag to move the model, you are simply updating a 2d point (xOffset, yOffset) that is added to each 2d point to draw the image in one place or another.
This xOffset, yOffset value defines where the 2d 0,0 coordinate is located in your window.
It is initially set in Sub initRenderScene(), each time you load a model
Code:
        xOffset = PictureBox_Render.Size.Width / 2
        yOffset = PictureBox_Render.Size.Height / 2 + 100
You can see the 0,0 point is initially 100 pixels below the horizontal and vertical center of the window.
I changed that to be the center of the window (commented out the + 100), as part of my changes to the attached modified version, because I wanted the center to be center intially to get a better feel for what the X,Y model values were when first read from the file.
There are unused variables set in there, in particular xRotAngle and yRotAngle, which could be misleading. A lot of dead code as well, like ini() (values not used), getLimits(), makeYRotation(), and makeXRotation().
In the initRenderScene, the code also presets the initial values that are used in the rotations (xTheta and yTheta)
Code:
        xTheta = 0.3F
        yTheta = 1.3F
If the model is prerotated around two of the axis by some amount, it makes it hard to interpret what the original X and Y values read represent in relation to the model.
These values should probably be displayed for information, or at least the rotation angles around which axis these values are applied to, so you can associate a rotation angle with the orientation you see on the screen.
So, I set the values to 0, so you see the model drawn in its "natural" form as read from the file, rather then pre-rotated around to be displayed "standing up" and viewed from a slight angle.
Besides those initial rotations, there was some adjustments going on in the code that did the rotations, and in the code that processed the mouse input.
The sub named applyProjection, isn't really applying a Projection per se, it is applying the rotations to the two axis the mouse controls (one axis is never rotated), that is, the model is yawed and pitched, but never rolled.
Once the 3d rotations are done the Z depth is ignored (so no perspective) and the x,y values are simply scaled by multiplying by the scalefactor and offset by xOffset,yOffset to be relative to where the origin of the model is.
Code:
      xScr = -x * scaleFactor + xOffset
      yScr = -y * scaleFactor + yOffset
You see there is no camera movement. The collection of 2d x,y values are simply multiplied by a scalefactor to make the image larger or smaller, as you would any 2d plot.
But, in this case, you can see they also negated both the x,y values for some reason, so again, the original x,y values in have been modified to map to the screen differently than how they came out of the file.
Also, if you've looked closely at the standard calculation of x,y values when doing a 2d rotation (which is the same as a rotation around the z-axis in 3d, aka yaw rotation), you would see another "adjustment" to the model coordinates.
The standard 2d rotation of x,y (the first rotation (yaw) in a 3d rotation) would be
X = Cos(angle) * X - Sin(angle) * Y
Y = SIN(angle) * X + Cos(angle) * Y
But in the code here X = Cos(angle)*Y - Sin(angle)*X, so the X and Y inputs are swapped.
Code:
  v11 = -sinth
  v21 = costh
  x = v11 * VertexObj.X + v21 * VertexObj.Y
The same thing with the calclation of Y, but since the code is premultiplying some of the values in some of the vnn variable (like premultiplying matrixes to combine rotations), it is harder to tell.
But, if you set the code up as I did to not have any initial rotations, and there is no Z depth projection going on, the x,y inputs should match the x,y outputs, so in this case, we can verify that x out equals -y in, and y out equals x in.
The two negatives after the rotation we already mentioned, reverses the sign of the rotated x,y to draw on the screen.
The swapping of x,y values essentially rotates the model 90 degrees, when drawn on the screen.
The mouse movement input controls the rotation of two axis, and there the mouse y movement (yTheta) is also negated, so accumulates in the reverse direction, so turns the model in a direction the coder apparently desired.
I removed that negation for my modification, so yTheta moved in the same direction relative to mouse motion as xTheta.

Continued next post:
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
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
 
-->