Autor Beitrag
kompas
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Mo 26.07.10 21:00 
hallo.

also jetz habe ich meine hände in dem schmutz.
und sowie ich nur c++ quelle code gefunden habe für 3d objekt file zu speichern, also muss ich jetzt, für einfach zu machen, die c++ in delphi sprache umändern, so dass ich sie in mein converter program einfügen kann.

und so, für den moment, starte ich mit einem problem.
www.jmdoudoux.fr/div...heses%20langages.htm

hier zum beispiel, dies werdet mir schon hilflich sein, aber leider, hier gebe es nur c# programmation, und nicht c++.

also kann jemanden mir helfen bei diese umänderung arbeit.

Beispiel:
ausblenden Quelltext
1:
2:
3:
4:
5:
# CLoad3DS::CLoad3DS()
# {
# m_CurrentChunk = new tChunk; // Initialize and allocate our current chunk
# m_TempChunk = new tChunk; // Initialize and allocate a temporary chunk
# }

CLOAD3DS
This constructor initializes the tChunk data

also tChunk funktion da kenne ich mich nicht richtig aus, und so in delphi, wie könnte dies interpretiert werden?
danke!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 26.07.10 21:16 
Das kannst du praktisch 1:1 übersetzen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
constructor TCLoad3DS.Create();
begin
  m_CurrentChunk := TChunk.Create(); // Initialize and allocate our current chunk
  m_TempChunk := TChunk.Create(); // Initialize and allocate a temporary chunk
end;
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Mo 26.07.10 21:22 
danke, aber hier habe ich noch etwass anderst gefunden!

schaue mal, ob dies nicht das selbe wehre?
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
type

  T3DModel = class;

// TChunk only used for loading the 3ds file. This class is destroyed after
// loading
  TChunk = class(TObject)
  private
    FId:Word;
    FLength:Integer;
    FBytesReaded:Integer;
    FModel:T3DModel;
    FFileHandle:Integer;
    function GetBytesRemaining: Integer;
  public
    constructor Create(Model:T3DModel);
    destructor Destroy;override;
    function Read:Integer;
    function ReadBuffer(var Buffer; Count:Integer):Integer;
    function ReadRemainingBuffer(var Buffer):Integer;
    procedure ProcessNextChunk(PreviousChunk:TChunk);
    procedure NexFilePosition;
    function ReadObjectString:string;
    function WaitForLength:Boolean;
    procedure UpdateByteCounter(Value:Integer);
    property Id:Word read FId;
    property Length:Integer read FLength;
    property BytesReaded:Integer read FBytesReaded;
    property BytesRemaining:Integer read GetBytesRemaining;
    property FileHandle:Integer read FFileHandle write FFileHandle;
end;


also muss dies alles zugeordnet werden, für die zwei kleine linien wie in c++ geschrieben wurden?

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 26.07.10 21:25 
user profile iconkompas hat folgendes geschrieben Zum zitierten Posting springen:
schaue mal, ob dies nicht das selbe wehre?
Das ist ja ein anderer Teil des Codes. Letztlich lässt sich das meiste fast direkt übersetzen. Nur bei sprachspezifischen Befehlen muss man halt etwas Hand anlegen.
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Mo 26.07.10 21:29 
ja ok, danke janicke, also werde ich mal gut bemerken wenn so ein kode bei dem c++ sprache Vorkommt.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Mo 26.07.10 21:43 
Ich weiß nicht ob du das richtig verstanden hast. Der erste Code ist eine procedure (constructor) in C++. Der Contructor dient zur Erstellung der Klasse.

Der zweite Code ist eine Klassendefinition in Delphi. Also...eine Liste an proceduren, aber ohne Implementierung erstmal. Der Constructor ist auch darunter. Die "property"-Zeilen kannst du meines Wissens so nicht in C++ umsetzen. In C++ sind dies Getter und Setter Methoden üblicherweise. Die Getter und Setter kannst du aber umgekehrt in Delphi auch verwenden.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Mo 26.07.10 23:03 
hallo xion!

doch ich habe es richtig verstanden.
Denn so fangt dass program unter c++ code ann.

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
# //***********************************************************************//
# // //
# // - "Talk to me like I'm a 3 year old!" Programming Lessons - //
# // //
# // $Author: DigiBen digiben@gametutorials.com //
# // $Program: 3DS Loader //
# // $Description: Demonstrates how to load a .3ds file format //
# // $Date: 10/6/01 //
# // //
# //***********************************************************************//
#
# #include <math.h>
# #include "3ds.h"
#
# // This file handles all of the code needed to load a .3DS file.
# // Basically, how it works is, you load a chunk, then you check
# // the chunk ID. Depending on the chunk ID, you load the information
# // that is stored in that chunk. If you do not want to read that information,
# // you read past it. You know how many bytes to read past the chunk because
# // every chunk stores the length in bytes of that chunk.
#
# ///////////////////////////////// CLOAD3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This constructor initializes the tChunk data
# /////
# ///////////////////////////////// CLOAD3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# CLoad3DS::CLoad3DS()
# {
# m_CurrentChunk = new tChunk; // Initialize and allocate our current chunk
# m_TempChunk = new tChunk; // Initialize and allocate a temporary chunk
# }


also hier, muss ich es umändern sowie Jaenicke mir es als beispiel umgeändert hat, danke an ihn!
also start es mit dem constructor.

aber hier habe ich noch eine weitere frage.

also hier arbeite ich bei der umänderung von dem 3ds.cpp zu 3DS.pas file.
und so, als weitere frage, kann man in den delphi sprache, alles wie in dem .cpp file, geschrieben war, in den .Pas file schreiben, oder werden einigen eher in andere files zugeteilt?

also hier für mir antworten zu können.
hier der vollständige c++ code, wie ich will auf delphi umschreiben.

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:
694:
695:
696:
697:
698:
699:
700:
701:
702:
703:
704:
705:
706:
707:
708:
709:
710:
711:
712:
713:
714:
715:
716:
717:
718:
719:
720:
721:
722:
723:
724:
725:
726:
727:
728:
729:
730:
731:
732:
733:
734:
735:
736:
737:
738:
739:
740:
741:
742:
743:
744:
745:
746:
747:
748:
749:
750:
751:
752:
753:
754:
755:
756:
757:
758:
759:
760:
761:
762:
763:
764:
765:
766:
767:
768:
769:
770:
771:
772:
773:
774:
775:
776:
777:
778:
779:
780:
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792:
793:
794:
795:
796:
797:
798:
799:
800:
801:
802:
803:
804:
805:
806:
807:
808:
809:
810:
811:
812:
813:
814:
815:
816:
817:
818:
819:
820:
821:
822:
823:
824:
825:
826:
827:
828:
829:
830:
831:
832:
833:
834:
835:
836:
837:
838:
839:
840:
841:
842:
843:
844:
845:
846:
847:
848:
849:
850:
//***********************************************************************//
# // //
# // - "Talk to me like I'm a 3 year old!" Programming Lessons - //
# // //
# // $Author: DigiBen digiben@gametutorials.com //
# // $Program: 3DS Loader //
# // $Description: Demonstrates how to load a .3ds file format //
# // $Date: 10/6/01 //
# // //
# //***********************************************************************//
#
# #include <math.h>
# #include "3ds.h"
#
# // This file handles all of the code needed to load a .3DS file.
# // Basically, how it works is, you load a chunk, then you check
# // the chunk ID. Depending on the chunk ID, you load the information
# // that is stored in that chunk. If you do not want to read that information,
# // you read past it. You know how many bytes to read past the chunk because
# // every chunk stores the length in bytes of that chunk.
#
# ///////////////////////////////// CLOAD3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This constructor initializes the tChunk data
# /////
# ///////////////////////////////// CLOAD3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# CLoad3DS::CLoad3DS()
# {
# m_CurrentChunk = new tChunk; // Initialize and allocate our current chunk
# m_TempChunk = new tChunk; // Initialize and allocate a temporary chunk
# }
#
# ///////////////////////////////// IMPORT 3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This is called by the client to open the .3ds file, read it, then clean up
# /////
# ///////////////////////////////// IMPORT 3DS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# bool CLoad3DS::Import3DS(t3DModel *pModel, const char *strFileName)
# {
# char strMessage[255] = {0};
#
# // Open the 3DS file
# m_FilePointer = fopen(strFileName, "rb");
#
# // Make sure we have a valid file pointer (we found the file)
# if(!m_FilePointer)
# {
# // sprintf(strMessage, "Unable to find the file: %s!", strFileName);
# // cout << strMessage << endl;
# return false;
# }
#
# // Once we have the file open, we need to read the very first data chunk
# // to see if it's a 3DS file. That way we don't read an invalid file.
# // If it is a 3DS file, then the first chunk ID will be equal to PRIMARY (some hex num)
#
# // Read the first chuck of the file to see if it's a 3DS file
# ReadChunk(m_CurrentChunk);
#
# // Make sure this is a 3DS file
# if (m_CurrentChunk->ID != __H3DS__PRIMARY)
# {
# // sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);
# // cout << strMessage << endl;
# return false;
# }
#
# // Now we actually start reading in the data. ProcessNextChunk() is recursive
#
# // Begin loading objects, by calling this recursive function
# ProcessNextChunk(pModel, m_CurrentChunk);
#
# // After we have read the whole 3DS file, we want to calculate our own vertex normals.
# ComputeNormals(pModel);
#
# // Clean up after everything
# CleanUp();
#
# return true;
# }
#
# ///////////////////////////////// CLEAN UP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function cleans up our allocated memory and closes the file
# /////
# ///////////////////////////////// CLEAN UP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::CleanUp()
# {
#
# fclose(m_FilePointer); // Close the current file pointer
# delete m_CurrentChunk; // Free the current chunk
# delete m_TempChunk; // Free our temporary chunk
# }
#
#
# ///////////////////////////////// PROCESS NEXT CHUNK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads the main sections of the .3DS file, then dives deeper with recursion
# /////
# ///////////////////////////////// PROCESS NEXT CHUNK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ProcessNextChunk(t3DModel *pModel, tChunk *pPreviousChunk)
# {
# t3DObject newObject = {0}; // This is used to add to our object list
# tMaterialInfo newTexture = {0}; // This is used to add to our material list
# unsigned int version = 0; // This will hold the file version
# int buffer[50000] = {0}; // This is used to read past unwanted data
#
# m_CurrentChunk = new tChunk; // Allocate a new chunk
#
# // Below we check our chunk ID each time we read a new chunk. Then, if
# // we want to extract the information from that chunk, we do so.
# // If we don't want a chunk, we just read past it.
#
# // Continue to read the sub chunks until we have reached the length.
# // After we read ANYTHING we add the bytes read to the chunk and then check
# // check against the length.
# while (pPreviousChunk->bytesRead < pPreviousChunk->length)
# {
# // Read next Chunk
# ReadChunk(m_CurrentChunk);
#
# // Check the chunk ID
# switch (m_CurrentChunk->ID)
# {
# case __H3DS__VERSION3DS: // This holds the version of the file
#
# // This chunk has an unsigned short that holds the file version.
# // Since there might be new additions to the 3DS file format in 4.0,
# // we give a warning to that problem.
#
# // Read the file version and add the bytes read to our bytesRead variable
# m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
#
# // If the file version is over 3, give a warning that there could be a problem
# // if (version > 0x03)
# // cout << "This 3DS file is over version 3 so it may load incorrectly" << endl;
# break;
#
# case __H3DS__OBJECTINFO: // This holds the version of the mesh
#
# // This chunk holds the version of the mesh. It is also the head of the MATERIAL
# // and OBJECT chunks. From here on we start reading in the material and object info.
#
# // Read the next chunk
# ReadChunk(m_TempChunk);
#
# // Get the version of the mesh
# m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);
#
# // Increase the bytesRead by the bytes read from the last chunk
# m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;
#
# // Go to the next chunk, which is the object has a texture, it should be MATERIAL, then OBJECT.
# ProcessNextChunk(pModel, m_CurrentChunk);
# break;
#
# case __H3DS__MATERIAL: // This holds the material information
#
# // This chunk is the header forthe material info chunks
#
# // Increase the number of materials
# pModel->numOfMaterials++;
#
# // Add a empty texture structure to our texture list.
# // If you are unfamiliar with STL's "vector" class, all push_back()
# // does is add a new node onto the list. I used the vector class
# // so I didn't need to write my own link list functions.
# pModel->pMaterials.push_back(newTexture);
#
# // Proceed to the material loading function
# ProcessNextMaterialChunk(pModel, m_CurrentChunk);
# break;
#
# case __H3DS__OBJECT: // This holds the name of the object being read
#
# // This chunk is the header forthe object info chunks. It also
# // holds the name of the object.
#
# // Increase the object count
# pModel->numOfObjects++;
#
# // Add a new tObject node to our list of objects (like a link list)
# pModel->pObject.push_back(newObject);
#
# // Initialize the object and all it's data members
# memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));
#
# // Get the name of the object and store it, then add the read bytes to our byte counter.
# m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);
#
# // Now proceed to read in the rest of the object information
# ProcessNextObjectChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);
# break;
#
# case __H3DS__EDITKEYFRAME:
#
# // Because I wanted to make this a SIMPLE tutorial as possible, I did not include
# // the key frame information. This chunk is the header forall the animation info.
# // In a later tutorial this will be the subject and explained thoroughly.
#
# //ProcessNextKeyFrameChunk(pModel, m_CurrentChunk);
#
# // Read past this chunk and add the bytes read to the byte counter
# m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
# break;
#
# default:
#
# // If we didn't care about a chunk, then we get here. We still need
# // to read past the unknown or ignored chunk and add the bytes read to the byte counter.
# m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
# break;
# }
#
# // Add the bytes read from the last chunk to the previous chunk passed in.
# pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;
# }
#
# // Free the current chunk and set it back to the previous chunk (since it started that way)
# delete m_CurrentChunk;
# m_CurrentChunk = pPreviousChunk;
# }
#
#
# ///////////////////////////////// PROCESS NEXT OBJECT CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function handles all the information about the objects in the file
# /////
# ///////////////////////////////// PROCESS NEXT OBJECT CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ProcessNextObjectChunk(t3DModel *pModel, t3DObject *pObject, tChunk *pPreviousChunk)
# {
# int buffer[50000] = {0}; // This is used to read past unwanted data
#
# // Allocate a new chunk to work with
# m_CurrentChunk = new tChunk;
#
# // Continue to read these chunks until we read the end of this sub chunk
# while (pPreviousChunk->bytesRead < pPreviousChunk->length)
# {
# // Read the next chunk
# ReadChunk(m_CurrentChunk);
#
# // Check which chunk we just read
# switch (m_CurrentChunk->ID)
# {
# case __H3DS__OBJECT_MESH: // This lets us know that we are reading a new object
#
# // We found a new object, so let's read in it's info using recursion
# ProcessNextObjectChunk(pModel, pObject, m_CurrentChunk);
# break;
#
# case __H3DS__OBJECT_VERTICES: // This is the objects vertices
# ReadVertices(pObject, m_CurrentChunk);
# break;
#
# case __H3DS__OBJECT_FACES: // This is the objects face information
# ReadVertexIndices(pObject, m_CurrentChunk);
# break;
#
# case __H3DS__OBJECT_MATERIAL: // This holds the material name that the object has
#
# // This chunk holds the name of the material that the object has assigned to it.
# // This could either be just a color or a texture map. This chunk also holds
# // the faces that the texture is assigned to (In the case that there is multiple
# // textures assigned to one object, or it just has a texture on a part of the object.
# // Since most of my game objects just have the texture around the whole object, and
# // they aren't multitextured, I just want the material name.
#
# // We now will read the name of the material assigned to this object
# ReadObjectMaterial(pModel, pObject, m_CurrentChunk);
# break;
#
# case __H3DS__OBJECT_UV: // This holds the UV texture coordinates forthe object
#
# // This chunk holds all of the UV coordinates forour object. Let's read them in.
# ReadUVCoordinates(pObject, m_CurrentChunk);
# break;
#
# default:
#
# // Read past the ignored or unknown chunks
# m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
# break;
# }
#
# // Add the bytes read from the last chunk to the previous chunk passed in.
# pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;
# }
#
# // Free the current chunk and set it back to the previous chunk (since it started that way)
# delete m_CurrentChunk;
# m_CurrentChunk = pPreviousChunk;
# }
#
#
# ///////////////////////////////// PROCESS NEXT MATERIAL CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function handles all the information about the material (Texture)
# /////
# ///////////////////////////////// PROCESS NEXT MATERIAL CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ProcessNextMaterialChunk(t3DModel *pModel, tChunk *pPreviousChunk)
# {
# int buffer[50000] = {0}; // This is used to read past unwanted data
#
# // Allocate a new chunk to work with
# m_CurrentChunk = new tChunk;
#
# // Continue to read these chunks until we read the end of this sub chunk
# while (pPreviousChunk->bytesRead < pPreviousChunk->length)
# {
# // Read the next chunk
# ReadChunk(m_CurrentChunk);
#
# // Check which chunk we just read in
# switch (m_CurrentChunk->ID)
# {
# case __H3DS__MATNAME: // This chunk holds the name of the material
#
# // Here we read in the material name
# m_CurrentChunk->bytesRead += fread(pModel->pMaterials[pModel->numOfMaterials - 1].strName, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
# break;
#
# case __H3DS__MATDIFFUSE: // This holds the R G B color of our object
# ReadColorChunk(&(pModel->pMaterials[pModel->numOfMaterials - 1]), m_CurrentChunk);
# break;
#
# case __H3DS__MATMAP: // This is the header forthe texture info
#
# // Proceed to read in the material information
# ProcessNextMaterialChunk(pModel, m_CurrentChunk);
# break;
#
# case __H3DS__MATMAPFILE: // This stores the file name of the material
#
# // Here we read in the material's file name
# m_CurrentChunk->bytesRead += fread(pModel->pMaterials[pModel->numOfMaterials - 1].strFile, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
# break;
#
# default:
#
# // Read past the ignored or unknown chunks
# m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
# break;
# }
#
# // Add the bytes read from the last chunk to the previous chunk passed in.
# pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;
# }
#
# // Free the current chunk and set it back to the previous chunk (since it started that way)
# delete m_CurrentChunk;
# m_CurrentChunk = pPreviousChunk;
# }
#
# ///////////////////////////////// READ CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in a chunk ID and it's length in bytes
# /////
# ///////////////////////////////// READ CHUNK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ReadChunk(tChunk *pChunk)
# {
# // This reads the chunk ID which is 2 bytes.
# // The chunk ID is like OBJECT or MATERIAL. It tells what data is
# // able to be read in within the chunks section.
# pChunk->bytesRead = fread(&pChunk->ID, 1, 2, m_FilePointer);
#
# // Then, we read the length of the chunk which is 4 bytes.
# // This is how we know how much to read in, or read past.
# pChunk->bytesRead += fread(&pChunk->length, 1, 4, m_FilePointer);
# }
#
# ///////////////////////////////// GET STRING \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in a string of characters
# /////
# ///////////////////////////////// GET STRING \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# int CLoad3DS::GetString(char *pBuffer)
# {
# int index = 0;
#
# // Read 1 byte of data which is the first letter of the string
# fread(pBuffer, 1, 1, m_FilePointer);
#
# // Loop until we get NULL
# while (*(pBuffer + index++) != 0) {
#
# // Read in a character at a time until we hit NULL.
# fread(pBuffer + index, 1, 1, m_FilePointer);
# }
#
# // Return the string length, which is how many bytes we read in (including the NULL)
# return strlen(pBuffer) + 1;
# }
#
#
# ///////////////////////////////// READ COLOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in the RGB color data
# /////
# ///////////////////////////////// READ COLOR \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ReadColorChunk(tMaterialInfo *pMaterial, tChunk *pChunk)
# {
# // Read the color chunk info
# ReadChunk(m_TempChunk);
#
# // Read in the R G B color (3 bytes - 0 through 255)
# m_TempChunk->bytesRead += fread(pMaterial->color, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);
#
# // Add the bytes read to our chunk
# pChunk->bytesRead += m_TempChunk->bytesRead;
# }
#
#
# ///////////////////////////////// READ VERTEX INDECES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in the indices forthe vertex array
# /////
# ///////////////////////////////// READ VERTEX INDECES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ReadVertexIndices(t3DObject *pObject, tChunk *pPreviousChunk)
# {
# unsigned short index = 0; // This is used to read in the current face index
# int j;
#
# // In order to read in the vertex indices forthe object, we need to first
# // read in the number of them, then read them in. Remember,
# // we only want 3 of the 4 values read in foreach face. The fourth is
# // a visibility flag for3D Studio Max that doesn't mean anything to us.
#
# // Read in the number of faces that are in this object (int)
# pPreviousChunk->bytesRead += fread(&pObject->numOfFaces, 1, 2, m_FilePointer);
#
# // Alloc enough memory forthe faces and initialize the structure
# pObject->pFaces = new tFace [pObject->numOfFaces];
# memset(pObject->pFaces, 0, sizeof(tFace) * pObject->numOfFaces);
#
# // Go through all of the faces in this object
# for(int i = 0; i < pObject->numOfFaces; i++)
# {
# // Next, we read in the A then B then C index forthe face, but ignore the 4th value.
# // The fourth value is a visibility flag for3D Studio Max, we don't care about this.
# for(j = 0; j < 4; j++)
# {
# // Read the first vertice index forthe current face
# pPreviousChunk->bytesRead += fread(&index, 1, sizeof(index), m_FilePointer);
#
# if(j < 3)
# {
# // Store the index in our face structure.
# pObject->pFaces[i].vertIndex[j] = index;
# }
# }
# }
# }
#
#
# ///////////////////////////////// READ UV COORDINATES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in the UV coordinates forthe object
# /////
# ///////////////////////////////// READ UV COORDINATES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ReadUVCoordinates(t3DObject *pObject, tChunk *pPreviousChunk)
# {
# // In order to read in the UV indices forthe object, we need to first
# // read in the amount there are, then read them in.
#
# // Read in the number of UV coordinates there are (int)
# pPreviousChunk->bytesRead += fread(&pObject->numTexVertex, 1, 2, m_FilePointer);
#
# // Allocate memory to hold the UV coordinates
# pObject->pTexVerts = new vec2 [pObject->numTexVertex];
#
# // Read in the texture coodinates (an array 2 float)
# pPreviousChunk->bytesRead += fread(pObject->pTexVerts, 1, pPreviousChunk->length - pPreviousChunk->bytesRead, m_FilePointer);
# }
#
#
# ///////////////////////////////// READ VERTICES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in the vertices forthe object
# /////
# ///////////////////////////////// READ VERTICES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ReadVertices(t3DObject *pObject, tChunk *pPreviousChunk)
# {
# // Like most chunks, before we read in the actual vertices, we need
# // to find out how many there are to read in. Once we have that number
# // we then fread() them into our vertice array.
#
# // Read in the number of vertices (int)
# pPreviousChunk->bytesRead += fread(&(pObject->numOfVerts), 1, 2, m_FilePointer);
#
# // Allocate the memory forthe verts and initialize the structure
# pObject->pVerts = new vec3 [pObject->numOfVerts];
# memset(pObject->pVerts, 0, sizeof(vec3) * pObject->numOfVerts);
#
# // Read in the array of vertices (an array of 3 floats)
# pPreviousChunk->bytesRead += fread(pObject->pVerts, 1, pPreviousChunk->length - pPreviousChunk->bytesRead, m_FilePointer);
#
# // Now we should have all of the vertices read in. Because 3D Studio Max
# // Models with the Z-Axis pointing up (strange and ugly I know!), we need
# // to flip the y values with the z values in our vertices. That way it
# // will be normal, with Y pointing up. If you prefer to work with Z pointing
# // up, then just delete this next loop. Also, because we swap the Y and Z
# // we need to negate the Z to make it come out correctly.
#
# // Go through all of the vertices that we just read and swap the Y and Z values
# for(int i = 0; i < pObject->numOfVerts; i++)
# {
# // Store off the Y value
# float fTempY = pObject->pVerts[i].y;
#
# // Set the Y value to the Z value
# pObject->pVerts[i].y = pObject->pVerts[i].z;
#
# // Set the Z value to the Y value,
# // but negative Z because 3D Studio max does the opposite.
# pObject->pVerts[i].z = -fTempY;
# }
# }
#
#
# ///////////////////////////////// READ OBJECT MATERIAL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function reads in the material name assigned to the object and sets the materialID
# /////
# ///////////////////////////////// READ OBJECT MATERIAL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ReadObjectMaterial(t3DModel *pModel, t3DObject *pObject, tChunk *pPreviousChunk)
# {
# char strMaterial[255] = {0}; // This is used to hold the objects material name
# int buffer[50000] = {0}; // This is used to read past unwanted data
#
# // *What is a material?* - A material is either the color or the texture map of the object.
# // It can also hold other information like the brightness, shine, etc... Stuff we don't
# // really care about. We just want the color, or the texture map file name really.
#
# // Here we read the material name that is assigned to the current object.
# // strMaterial should now have a string of the material name, like "Material #2" etc..
# pPreviousChunk->bytesRead += GetString(strMaterial);
#
# // Now that we have a material name, we need to go through all of the materials
# // and check the name against each material. When we find a material in our material
# // list that matches this name we just read in, then we assign the materialID
# // of the object to that material index. You will notice that we passed in the
# // model to this function. This is because we need the number of textures.
# // Yes though, we could have just passed in the model and not the object too.
#
# // Go through all of the textures
# for(int i = 0; i < pModel->numOfMaterials; i++)
# {
# // If the material we just read in matches the current texture name
# if(strcmp(strMaterial, pModel->pMaterials[i].strName) == 0)
# {
# // Set the material ID to the current index 'i' and stop checking
# pObject->materialID = i;
#
# // Now that we found the material, check if it's a texture map.
# // If the strFile has a string length of 1 and over it's a texture
# if(strlen(pModel->pMaterials[i].strFile) > 0) {
#
# // Set the object's flag to say it has a texture map to bind.
# pObject->bHasTexture = true;
# }
# break;
# }
# else
# {
# // Set the ID to -1 to show there is no material forthis object
# pObject->materialID = -1;
# }
# }
#
# // Read past the rest of the chunk since we don't care about shared vertices
# // You will notice we subtract the bytes already read in this chunk from the total length.
# pPreviousChunk->bytesRead += fread(buffer, 1, pPreviousChunk->length - pPreviousChunk->bytesRead, m_FilePointer);
# }
#
# ///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
# /////
# ///// This function computes the normals and vertex normals of the objects
# /////
# ///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
#
# void CLoad3DS::ComputeNormals(t3DModel *pModel)
# {
# vec3 vVector1, vVector2, vNormal, vPoly[3];
# int i,j;
#
# // If there are no objects, we can skip this part
# if(pModel->numOfObjects <= 0)
# return;
#
# // What are vertex normals? And how are they different from other normals?
# // Well, if you find the normal to a triangle, you are finding a "Face Normal".
# // If you give OpenGL a face normal forlighting, it will make your object look
# // really flat and not very round. If we find the normal foreach vertex, it makes
# // the smooth lighting look. This also covers up blocky looking objects and they appear
# // to have more polygons than they do. Basically, what you do is first
# // calculate the face normals, then you take the average of all the normals around each
# // vertex. It's just averaging. That way you get a better approximation forthat vertex.
#
# // Go through each of the objects to calculate their normals
# for(int index = 0; index < pModel->numOfObjects; index++)
# {
# // Get the current object
# t3DObject *pObject = &(pModel->pObject[index]);
#
# // Here we allocate all the memory we need to calculate the normals
# vec3 *pNormals = new vec3 [pObject->numOfFaces];
# vec3 *pTempNormals = new vec3 [pObject->numOfFaces];
# pObject->pNormals = new vec3 [pObject->numOfVerts];
#
# // Go though all of the faces of this object
# for(i=0; i < pObject->numOfFaces; i++)
# {
# // To cut down LARGE code, we extract the 3 points of this face
# vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
# vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
# vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];
#
# // Now let's calculate the face normals (Get 2 vectors and find the cross product of those 2)
#
# vVector1 = Vector(vPoly[0], vPoly[2]); // Get the vector of the polygon (we just need 2 sides forthe normal)
# vVector2 = Vector(vPoly[2], vPoly[1]); // Get a second vector of the polygon
#
# vNormal = Cross(vVector1, vVector2); // Return the cross product of the 2 vectors (normalize vector, but not a unit vector)
# pTempNormals[i] = vNormal; // Save the un-normalized normal forthe vertex normals
# vNormal.normalize(); // Normalize the cross product to give us the polygons normal
#
# pNormals[i] = vNormal; // Assign the normal to the list of normals
# }
#
# //////////////// Now Get The Vertex Normals /////////////////
#
# vec3 vSum;
# vec3 vZero = vSum;
# int shared=0;
#
# for(i = 0; i < pObject->numOfVerts; i++) // Go through all of the vertices
# {
# for(j = 0; j < pObject->numOfFaces; j++) // Go through all of the triangles
# { // Check if the vertex is shared by another face
# if (pObject->pFaces[j].vertIndex[0] == i ||
# pObject->pFaces[j].vertIndex[1] == i ||
# pObject->pFaces[j].vertIndex[2] == i)
# {
# vSum += pTempNormals[j];// Add the un-normalized normal of the shared face
# shared++; // Increase the number of shared triangles
# }
# }
#
# // Get the normal by dividing the sum by the shared. We negate the shared so it has the normals pointing out.
# pObject->pNormals[i] = vSum / float(-shared);
#
# // Normalize the normal forthe final vertex normal
# pObject->pNormals[i].normalize();
#
# vSum = vZero; // Reset the sum
# shared = 0; // Reset the shared
# }
#
# // Free our memory and start over on the next object
# delete [] pTempNormals;
# delete [] pNormals;
# }
# }
#
#
# /////////////////////////////////////////////////////////////////////////////////
# //
# // * QUICK NOTES *
# //
# // This was a HUGE amount of knowledge and probably the largest tutorial yet!
# // In the next tutorial we will show you how to load a text file format called .obj.
# // This is the most common 3D file format that almost ANY 3D software will import.
# //
# // Once again I should point out that the coordinate system of OpenGL and 3DS Max are different.
# // Since 3D Studio Max Models with the Z-Axis pointing up (strange and ugly I know! :),
# // we need to flip the y values with the z values in our vertices. That way it
# // will be normal, with Y pointing up. Also, because we swap the Y and Z we need to negate
# // the Z to make it come out correctly. This is also explained and done in ReadVertices().
# //
# // CHUNKS: What is a chunk anyway?
# //
# // "The chunk ID is a unique code which identifies the type of data in this chunk
# // and also may indicate the existence of subordinate chunks. The chunk length indicates
# // the length of following data to be associated with this chunk. Note, this may
# // contain more data than just this chunk. If the length of data is greater than that
# // needed to fill in the information forthe chunk, additional subordinate chunks are
# // attached to this chunk immediately following any data needed forthis chunk, and
# // should be parsed out. These subordinate chunks may themselves contain subordinate chunks.
# // Unfortunately, there is no indication of the length of data, which is owned by the current
# // chunk, only the total length of data attached to the chunk, which means that the only way
# // to parse out subordinate chunks is to know the exact format of the owning chunk. On the
# // other hand, if a chunk is unknown, the parsing program can skip the entire chunk and
# // subordinate chunks in one jump. " - Jeff Lewis (werewolf@worldgate.com)
# //
# // In a short amount of words, a chunk is defined this way:
# // 2 bytes - Stores the chunk ID (OBJECT, MATERIAL, PRIMARY, etc...)
# // 4 bytes - Stores the length of that chunk. That way you know when that
# // chunk is done and there is a new chunk.
# //
# // So, to start reading the 3DS file, you read the first 2 bytes of it, then
# // the length (using fread()). It should be the PRIMARY chunk, otherwise it isn't
# // a .3DS file.
# //
# // Below is a list of the order that you will find the chunks and all the know chunks.
# // If you go to www.wosit.org you can find a few documents on the 3DS file format.
# // You can also take a look at the 3DS Format.rtf that is included with this tutorial.
# //
# //
# //
# // MAIN3DS (0x4D4D)
# // |
# // +--EDIT3DS (0x3D3D)
# // | |
# // | +--EDIT_MATERIAL (0xAFFF)
# // | | |
# // | | +--MAT_NAME01 (0xA000) (See mli Doc)
# // | |
# // | +--EDIT_CONFIG1 (0x0100)
# // | +--EDIT_CONFIG2 (0x3E3D)
# // | +--EDIT_VIEW_P1 (0x7012)
# // | | |
# // | | +--TOP (0x0001)
# // | | +--BOTTOM (0x0002)
# // | | +--LEFT (0x0003)
# // | | +--RIGHT (0x0004)
# // | | +--FRONT (0x0005)
# // | | +--BACK (0x0006)
# // | | +--USER (0x0007)
# // | | +--CAMERA (0xFFFF)
# // | | +--LIGHT (0x0009)
# // | | +--DISABLED (0x0010)
# // | | +--BOGUS (0x0011)
# // | |
# // | +--EDIT_VIEW_P2 (0x7011)
# // | | |
# // | | +--TOP (0x0001)
# // | | +--BOTTOM (0x0002)
# // | | +--LEFT (0x0003)
# // | | +--RIGHT (0x0004)
# // | | +--FRONT (0x0005)
# // | | +--BACK (0x0006)
# // | | +--USER (0x0007)
# // | | +--CAMERA (0xFFFF)
# // | | +--LIGHT (0x0009)
# // | | +--DISABLED (0x0010)
# // | | +--BOGUS (0x0011)
# // | |
# // | +--EDIT_VIEW_P3 (0x7020)
# // | +--EDIT_VIEW1 (0x7001)
# // | +--EDIT_BACKGR (0x1200)
# // | +--EDIT_AMBIENT (0x2100)
# // | +--EDIT_OBJECT (0x4000)
# // | | |
# // | | +--OBJ_TRIMESH (0x4100)
# // | | | |
# // | | | +--TRI_VERTEXL (0x4110)
# // | | | +--TRI_VERTEXOPTIONS (0x4111)
# // | | | +--TRI_MAPPINGCOORS (0x4140)
# // | | | +--TRI_MAPPINGSTANDARD (0x4170)
# // | | | +--TRI_FACEL1 (0x4120)
# // | | | | |
# // | | | | +--TRI_SMOOTH (0x4150)
# // | | | | +--TRI_MATERIAL (0x4130)
# // | | | |
# // | | | +--TRI_LOCAL (0x4160)
# // | | | +--TRI_VISIBLE (0x4165)
# // | | |
# // | | +--OBJ_LIGHT (0x4600)
# // | | | |
# // | | | +--LIT_OFF (0x4620)
# // | | | +--LIT_SPOT (0x4610)
# // | | | +--LIT_UNKNWN01 (0x465A)
# // | | |
# // | | +--OBJ_CAMERA (0x4700)
# // | | | |
# // | | | +--CAM_UNKNWN01 (0x4710)
# // | | | +--CAM_UNKNWN02 (0x4720)
# // | | |
# // | | +--OBJ_UNKNWN01 (0x4710)
# // | | +--OBJ_UNKNWN02 (0x4720)
# // | |
# // | +--EDIT_UNKNW01 (0x1100)
# // | +--EDIT_UNKNW02 (0x1201)
# // | +--EDIT_UNKNW03 (0x1300)
# // | +--EDIT_UNKNW04 (0x1400)
# // | +--EDIT_UNKNW05 (0x1420)
# // | +--EDIT_UNKNW06 (0x1450)
# // | +--EDIT_UNKNW07 (0x1500)
# // | +--EDIT_UNKNW08 (0x2200)
# // | +--EDIT_UNKNW09 (0x2201)
# // | +--EDIT_UNKNW10 (0x2210)
# // | +--EDIT_UNKNW11 (0x2300)
# // | +--EDIT_UNKNW12 (0x2302)
# // | +--EDIT_UNKNW13 (0x2000)
# // | +--EDIT_UNKNW14 (0xAFFF)
# // |
# // +--KEYF3DS (0xB000)
# // |
# // +--KEYF_UNKNWN01 (0xB00A)
# // +--............. (0x7001) ( viewport, same as editor )
# // +--KEYF_FRAMES (0xB008)
# // +--KEYF_UNKNWN02 (0xB009)
# // +--KEYF_OBJDES (0xB002)
# // |
# // +--KEYF_OBJHIERARCH (0xB010)
# // +--KEYF_OBJDUMMYNAME (0xB011)
# // +--KEYF_OBJUNKNWN01 (0xB013)
# // +--KEYF_OBJUNKNWN02 (0xB014)
# // +--KEYF_OBJUNKNWN03 (0xB015)
# // +--KEYF_OBJPIVOT (0xB020)
# // +--KEYF_OBJUNKNWN04 (0xB021)
# // +--KEYF_OBJUNKNWN05 (0xB022)
# //
# // Once you know how to read chunks, all you have to know is the ID you are looking for
# // and what data is stored after that ID. You need to get the file format forthat.
# // I can give it to you if you want, or you can go to www.wosit.org forseveral versions.
# // Because this is a proprietary format, it isn't a official document.
# //
# // I know there was a LOT of information blown over, but it is too much knowledge for
# // one tutorial. In the animation tutorial that I eventually will get to, some of
# // the things explained here will be explained in more detail. I do not claim that
# // this is the best .3DS tutorial, or even a GOOD one :) But it is a good start, and there
# // isn't much code out there that is simple when it comes to reading .3DS files.
# // So far, this is the best I have seen. That is why I made it :)
# //
# // I would like to thank www.wosit.org and Terry Caton (tcaton@umr.edu) forhis help on this.
# //
# // Let me know if this helps you out!
# //
# //
# // Ben Humphrey (DigiBen)
# // Game Programmer
# // DigiBen@GameTutorials.com
# // Co-Web Host of www.GameTutorials.com
# //
# //
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 27.07.10 05:21 
Das gehört schon alles in die Unit rein.

Anders als bei C++ mit der Unterteilung in Code und Header wird das in Delphi alles in eine Datei geschrieben.
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Di 27.07.10 11:10 
ok danke jaenicke!

eine weitere frage.

hier bei der c++ programmation, wurde
# #include <math.h>
benutzt.
also ist dieser math.h file gleichwert mit dem Math.pas file?

denn hier handelt es sich um mathematic funktionen.

oder gebe es bei delphi mehere files?
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Di 27.07.10 11:22 
K. A. aber ich glaube nicht, dass das gleichwertig ist. Wäre großer Zufall. Also bei den Funktionen musst du probieren, wie das Analogon heißt. Ansonsten hast du mit System und Math in Delphi die mathematischen Funktionen (System z. B. für sin() und cos(), Math den anderen Mist, afaik auch tan().) Hab aber gerade kein Delphi, mit dem ich das ausprobieren könnte.
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Di 27.07.10 11:37 
hallo jakob_ulmann.

aber ich habe dies als Vergleich benutzt.

www.jwrider.com/lab/MATH_PAS.htm (also dies ist für die mathematic funktionen bei delphi)
und dieser weitere link, für die mathematic funktionen wie der math.h file unterstürtzt.
en.wikipedia.org/wiki/Math.h

jetzt bin ich einverstanden, dass entweder math.h oder math.pas file, noch weitere mathematic funktionen unterstürtz.....

denn hier zum beispiel, sowie mein program wie ich diese funktion will einfüge, für 3d model convertion.

also hier als weitere beispiel, wurde bei einem file dies benutzt.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
unit AsphyreMeshes;
//---------------------------------------------------------------------------
// AsphyreMeshes.pas                                    Modified: 11-Oct-2005
// Mesh Storage implementation                                    Version 1.0
//---------------------------------------------------------------------------
// The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//---------------------------------------------------------------------------
interface

//---------------------------------------------------------------------------
uses
 Types, Classes, SysUtils, AsphyreDef, AsphyreMath, AsphyrePrimitives;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Di 27.07.10 11:56 
Da hast du's: math.h definiert cos(). In Delphi ist Cos() in der Unit System definiert. Also musst du System und Math einbinden, um ein etwas Gleichwertiges für dein math.h zu erhalten:

ausblenden C#-Quelltext
1:
#include <math.h>					


wird zu

ausblenden Delphi-Quelltext
1:
uses ..., Math, System, ...;					


(und bei 3D-Sachen ist die Gefahr ja ziemlich groß, auf trigonometrische Funktionen zu stoßen. :wink: )
guinnes
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 182
Erhaltene Danke: 14



BeitragVerfasst: Di 27.07.10 12:06 
user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:

wird zu

ausblenden Delphi-Quelltext
1:
uses ..., Math, System, ...;					
Eher nicht. System ist automatisch in den Uses drin ( nicht sichtbar )
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Di 27.07.10 12:53 
user profile iconguinnes hat folgendes geschrieben Zum zitierten Posting springen:
Eher nicht. System ist automatisch in den Uses drin ( nicht sichtbar )


Richtig! Wie konnte ich das nur vergessen...
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Di 27.07.10 13:36 
ja danke, dies ist dann auch weiter erklärt.

Also als weitere frage.
wenn ich den 3ds.cpp code anschaue, hier habe ich keine spezielle math funktion gesehen.
Also kommt jetzt der warum das der programmer diese math.h in diesem loader einbezogen hat.

eher dass ich etwass in dem program quelle code übersehen habe.
also kann einer schnell der cpp code anschauen, und mir Verraten, ob es ein spezielle sin gebe, für das der programmer diese math.h file zu diesem file einbezogen hat.
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Di 27.07.10 14:39 
Kommentiere doch einfach die #include-Direktive aus und schau, ob der Compiler meckert.

ABER: Ich frage mich, wo der Typ die ganzen Funktionen her nimmt, die er zur Normalenberechnung verwendet. Auf jeden Fall muss er, nach seinem Einrückstil zu urteilen, besoffen gewesen sein, als er den Kot geschrieben hat.
kompas Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 44



BeitragVerfasst: Di 27.07.10 18:36 
warum muss er besoffen gewesen sein, wen er der kode geschrieben hatte?

Stimmt etwas nicht mit den 3d normales programierung?

denn diese Berechnung style, sind auch für die andere loader benutzt,also hier kann ich nachschauen für obj file format loader oder für ms3d für milkshape format.
also es ändernt sich ein bisschen, aber der prinzyp ist das selbe.

also hier eine kleine explikation.

Zitat:
about the averaged normal:
faces that share verticies have different normals for those verticies this creates hard edges when doing lighting etc. to acheive smoothed normals you would do this:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
for each vertex
  find all faces that use the vertex
    sum up normals from each face for that vertex
    divide by number of faces
    store averaged normal and remove obsolete ones
  next
next



und hier weitere info....

Zitat:
This will be:
a) slow (O(M*N))
b) wrong (unnormalized)

A simple solution would be:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
for each vertex {
   normal = zero
}
for each face {
   calculate face normal
   add face normal to all 3 vertices of face
}
for each vertex {
   noramlize normal
}


Runs in O(N+M) and gives normalized results. You could include calculation of whole TBN matrix so you don't have to do another pass. Smoothing groups have to be handeld before this step becouse you need to create duplicated vertices.

ps: If you are using modes exported from 3DS MAX be very carefull since they are often screwed up. Specialy if you used mirroring or some replication.

to add compilication to that, you can use smoothing groups to determine which faces to average against, and also crease angle support (when two normals differ by a large angle (eg. cube faces) maintain more than 1 normal for that vert)