📄 objekt.cpp
字号:
/* Objekt.CPP
*
* provides Object-Declarations & -operations
*
* Copyright 2003 by PaP / JTMK
*/
#include "stdio.h"
#include <math.h>
#include <windows.h>
#include "SystemIO.h"
#include "objekt.h"
#include "level.h"
#include <gl\glaux.h> // Header File For The GLu32 Library
tObjekt *DaObjekt;
//tSkeletonNode *DaLastNode;
tSkeletonNode *Node[100];
tSkeletonNode *TempNode1[100],*TempNode2[100];
long SkelNodes;
long NodeCnt;
tSkelList *AktList;
void SetMeshPointsRelTo(tGrund *Mesh,tOMatrix Matrix,tP3D Pos)
{
tWandVertice *Temp;
Temp=Mesh->Vertice;
while(Temp!=NULL)
{
Temp->Pos=CalcRelPosition(vSub2(&Temp->WorldPos,&Pos),&Matrix);
Temp=Temp->Next;
}
}
tMeshList *CopyMeshList(tMeshList *Orig)
{
tMeshList *Temp;
if(Orig==NULL) return(NULL);
Temp=(tMeshList*)malloc(sizeof(tMeshList));
// memcpy(Temp,Orig,sizeof(tMeshList));
*Temp=*Orig;
Temp->Mesh=CopyGrund(Orig->Mesh);
Temp->Next=CopyMeshList(Orig->Next);
return(Temp);
}
tSkeletonNode *CopySkelNode(tSkeletonNode *Orig,tSkeletonNode *Father,bool CopyMesh)
{
if(Orig==NULL) return(NULL);
tSkeletonNode *NewNode;
NewNode=(tSkeletonNode *) malloc(sizeof(tSkeletonNode));
TempNode1[SkelNodes]=Orig;
TempNode2[SkelNodes]=NewNode;
SkelNodes++;
// memcpy(NewNode,Orig,sizeof(tSkeletonNode));
*NewNode=*Orig;
if(CopyMesh)
{ NewNode->MeshList=CopyMeshList(Orig->MeshList); }
else
{ NewNode->MeshList=Orig->MeshList; }
NewNode->Father=Father;
// NewNode->MeshS=CopySector(Orig->MeshS,NULL,true,true);
NewNode->Child=CopySkelNode(Orig->Child,NewNode,CopyMesh);
NewNode->Next=CopySkelNode(Orig->Next,Father,CopyMesh);
return(NewNode);
}
tObjekt *CopyObject(tObjekt *Temp,bool CopyMesh)
{
tObjekt *NewO;
NewO=(tObjekt *) malloc(sizeof(tObjekt));
// memcpy(NewO,Temp,sizeof(tObjekt));
*NewO=*Temp;
SkelNodes=0;
NewO->Skel=CopySkelNode(Temp->Skel,NULL,CopyMesh);
NewO->SkelList=CreateSkelList(NewO->Skel,NewO);
return(NewO);
}
// Berechnet das Skelett neu
void ReCalcSkelNode(tSkeletonNode *Temp,tOMatrix *OrigMatrix,tP3D *OldPos,float Time)
{
if(Temp==NULL) return;
Temp->Pos=vAdd5(OldPos,CalcRealPosition(vAdd5(&Temp->OrgPos,vMulK2(&Temp->LastSpeed,Time)),OrigMatrix));
Temp->Matrix=CalcNewMatrix(*OldPos,Temp->Pos,OrigMatrix,Temp->Roll);
ReCalcSkelNode(Temp->Child,&Temp->Matrix,&Temp->Pos,Time);
ReCalcSkelNode(Temp->Next,OrigMatrix,OldPos,Time);
}
void SetRollMesh(tMeshList *Mesh,tOMatrix Matrix,tP3D Pos)
{
if(Mesh==NULL) return;
if(Mesh->Mesh!=NULL)
{
SetMeshPointsRelTo(Mesh->Mesh,Matrix,Pos);
}
SetRollMesh(Mesh->Next,Matrix,Pos);
}
void SetMeshAsItIs(tSkeletonNode *Temp)
{
if(Temp==NULL) return;
SetRollMesh(Temp->MeshList,Temp->Matrix,Temp->Pos);
SetMeshAsItIs(Temp->Child);
SetMeshAsItIs(Temp->Next);
}
void DelMeshList(tMeshList *Temp)
{
if(Temp==NULL) return;
DelMeshList(Temp->Next);
DestroyGrund(Temp->Mesh);
free(Temp);
}
void DelSkel(tSkeletonNode *Temp)
{
if(Temp->Child!=NULL) DelSkel(Temp->Child);
if(Temp->Next!=NULL) DelSkel(Temp->Next);
DelMeshList(Temp->MeshList);
free(Temp);
}
tObjekt *DelObj(tObjekt *Obj)
{
DelSkel(Obj->Skel);
DestroySkelList(Obj->SkelList);
free(Obj);
return(NULL);
}
tSkelList *AddSkelPointToList(tSkeletonNode *Temp)
{
if(Temp==NULL) return(NULL);
tSkelList *TempList;
NodeCnt++;
TempList=(tSkelList*) malloc(sizeof(tSkelList));
TempList->Node=Temp;
TempList->Next=NULL;
if(AktList!=NULL) AktList->Next=TempList;
AktList=TempList;
AddSkelPointToList(Temp->Child);
AddSkelPointToList(Temp->Next);
return(TempList);
}
tSkelList *CreateSkelList(tSkeletonNode *Skel,tObjekt *Obj)
{
tSkelList *Temp;
NodeCnt=0;
AktList=NULL;
Temp=AddSkelPointToList(Skel);
Obj->SkelNodes=NodeCnt;
return(Temp);
}
long GetSkelNumber(tSkeletonNode *Temp,tObjekt *Obj)
{
tSkelList *Temp2;
long I;
I=0;
Temp2=Obj->SkelList;
while(Temp!=Temp2->Node)
{
I++;
Temp2=Temp2->Next;
}
return(I);
}
tSkeletonNode *GetSkelAddr(long Nr,tSkelList *Temp2)
{
long I;
for(I=0;I<Nr;I++) Temp2=Temp2->Next;
return(Temp2->Node);
}
void CalcSkelSpeeds(tSkeletonNode *Temp)
{
if(Temp==NULL) return;
float SpeedMax=1;
float RollMax=SpeedMax;
float SpeedAdd=0.2;
float RollAdd=0.02;
tP3D SpeedVek;
SpeedVek=vSub2(&Temp->ZielOrgPos,&Temp->OrgPos);
if(vLength2(SpeedVek)!=0)
{
vMulK3(&SpeedVek,SpeedAdd);
vAdd4(&Temp->Speed,vMulK2(&SpeedVek,SpeedAdd));
if(vLength2(Temp->Speed)>SpeedMax)
{
Norm(&Temp->Speed);
vMulK3(&Temp->Speed,SpeedMax);
}
}
if(Temp->ZielRoll!=Temp->Roll)
{
Temp->RollSpeed+=(Temp->ZielRoll-Temp->Roll)*RollAdd;
if(Temp->RollSpeed>RollMax) Temp->RollSpeed=RollMax;
if(Temp->RollSpeed<-RollMax) Temp->RollSpeed=-RollMax;
}
CalcSkelSpeeds(Temp->Child);
CalcSkelSpeeds(Temp->Next);
}
void CalcNextPos(tSkeletonNode *Src,tSkeletonNode *Dest)
{
float SpeedBrems=0.8;
Dest->Speed=vMulK2(&Src->Speed,SpeedBrems);
vAdd3v(&Dest->OrgPos,&Src->OrgPos,&Dest->Speed);
}
// Berechnet das n鋍hste Movementframe
void CalcSkelMovement(tSkeletonNode *Temp,bool DoIt)
{
if(Temp==NULL) return;
float SpeedBrems=0.8;
if(DoIt)
{
CalcNextPos(Temp,Temp);
Temp->RollSpeed=Temp->RollSpeed*SpeedBrems;
Temp->Roll=Temp->Roll+Temp->RollSpeed;
}
CalcSkelMovement(Temp->Child,true);
CalcSkelMovement(Temp->Next,true);
}
// Jeweils der Z-Vektor wird weitergegeben
tP3D SkelPhysicAusgleich(tSkeletonNode *Temp)
{
tP3D ZielP,MoveVek;
MoveVek=Temp->Speed;
if(Temp->Father!=NULL) MoveVek=CalcRealPosition(MoveVek,&Temp->Father->Matrix);
if(Temp->Child!=NULL) vAdd4(&MoveVek,SkelPhysicAusgleich(Temp->Child));
// if(Flag(Temp->Flags,_Fixed)) MoveVek=Temp->Speed;
if(Temp->Father!=NULL)
{
Temp->Speed=CalcRelPosition(MoveVek,&Temp->Father->Matrix);
MoveVek=Temp->Speed;
vAdd3v(&ZielP,&Temp->OrgPos,&Temp->Speed);
Norm(&ZielP);
vMulK3(&ZielP,Temp->FatherAbstand);
Temp->Speed=vSub2(&ZielP,&Temp->OrgPos);
vSub3(&MoveVek,&Temp->Speed);
MoveVek=CalcRealPosition(MoveVek,&Temp->Father->Matrix);
}
if(Temp->Next!=NULL) vAdd4(&MoveVek,SkelPhysicAusgleich(Temp->Next));
Temp->LastSpeed=Temp->Speed;
return(MoveVek);
}
tMeshList *AddToMeshList(tMeshList *Pre,tGrund *Mesh,long MatNr)
{
tMeshList *Temp,*Temp2;
Temp=(tMeshList*) malloc(sizeof(tMeshList));
Temp->MatNr=MatNr;
Temp->Mesh=CopyGrund(Mesh);
CalcNormalsBasedOnPolys(Temp->Mesh);
Temp->Next=NULL;
if(Pre==NULL) return(Temp);
Temp2=Pre;
while(Temp2->Next!=NULL)
{
Temp2=Temp2->Next;
}
Temp2->Next=Temp;
return(Pre);
}
tSkeletonNode *ConvertSectorToSkelNode(tSector *Sector,tSkeletonNode *_Father,tP3D OPos,tOMatrix OrgMatrix,tSkeletonNode *DaLastNode)
{
tP3D NPos;
tSkeletonNode *Temp;
if(Sector==NULL) return(NULL);
//if(Flag(Sector->Flags,_SF_SkeletonNode))
if(Sector->Flags&_SF_SkeletonNode)
{
Temp=(tSkeletonNode *) malloc(sizeof(tSkeletonNode));
Node[SkelNodes]=Temp;
SkelNodes++;
Temp->SphereSize=2;
Temp->Father=_Father;
Temp->Pos=Sector->Pos;
if(Temp->Father!=NULL)
{ Temp->FatherAbstand=vLengthSub(&Temp->Pos,&OPos);}
NPos=vSub2(&Temp->Pos,&OPos);
Temp->OrgPos=CalcRelPosition(NPos,&OrgMatrix);
Temp->Pos=vAdd5(&OPos,CalcRealPosition(Temp->OrgPos,&OrgMatrix));
Temp->Roll=0;
Temp->Flags=0;
Temp->Matrix=CalcNewMatrix(OPos,Temp->Pos,&OrgMatrix,Temp->Roll);
Temp->MeshList=NULL;
Temp->ZielOrgPos=Temp->OrgPos;
Temp->ZielRoll=Temp->Roll;
Temp->Speed=vNull;
Temp->RollSpeed=0;
Temp->Next=ConvertSectorToSkelNode(Sector->Next,_Father,OPos,OrgMatrix,DaLastNode);
Temp->Child=ConvertSectorToSkelNode(Sector->SubSector,Temp,Temp->Pos,Temp->Matrix,Temp);
return(Temp);
} else {
Temp=DaLastNode;
SetMeshPointsRelTo(Sector->Mesh,Temp->Matrix,Temp->Pos);
Temp->MeshList=AddToMeshList(Temp->MeshList,Sector->Mesh,Sector->MatNr);
ConvertSectorToSkelNode(Sector->SubSector,_Father,OPos,OrgMatrix,DaLastNode);
return(ConvertSectorToSkelNode(Sector->Next,_Father,OPos,OrgMatrix,DaLastNode));
}
/**/
}
tMeshList *ConvertToMeshList(tMeshList *List,tSector *Sector,tOMatrix *Matrix)
{
if(Sector==NULL) return(List);
if((Sector->Mesh!=NULL)&&(!(Sector->Flags&_SF_SkeletonNode)))
{
SetMeshPointsRelTo(Sector->Mesh,*Matrix,vNull);
List=AddToMeshList(List,Sector->Mesh,Sector->MatNr);
}
List=ConvertToMeshList(List,Sector->SubSector,Matrix);
List=ConvertToMeshList(List,Sector->Next,Matrix);
return(List);
}
void CalcMinMax(tMeshList *List,tP3D *Min,tP3D *Max)
{
tWandVertice *Temp;
if(List==NULL) return;
if(List->Mesh!=NULL)
{
Temp=List->Mesh->Vertice;
while(Temp!=NULL)
{
if(Temp->WorldPos.X<Min->X) Min->X=Temp->WorldPos.X;
if(Temp->WorldPos.Y<Min->Y) Min->Y=Temp->WorldPos.Y;
if(Temp->WorldPos.Z<Min->Z) Min->Z=Temp->WorldPos.Z;
if(Temp->WorldPos.X>Max->X) Max->X=Temp->WorldPos.X;
if(Temp->WorldPos.Y>Max->Y) Max->Y=Temp->WorldPos.Y;
if(Temp->WorldPos.Z>Max->Z) Max->Z=Temp->WorldPos.Z;
Temp=Temp->Next;
}
}
CalcMinMax(List->Next,Min,Max);
}
void CalcSphereSize(tSkeletonNode *Node)
{
tP3D PMin,PMax;
if(Node==NULL) return;
PMin=Node->Pos;
PMax=PMin;
if(Node->MeshList!=NULL) CalcMinMax(Node->MeshList,&PMin,&PMax);
Node->SphereSize=vLengthSub(&PMin,&PMax)/2.5;
// if(Node->SphereSize==0) Node->SphereSize=2.5;
CalcSphereSize(Node->Child);
CalcSphereSize(Node->Next);
}
tObjekt *ConvertSectorToObjekt(tSector *Sector)
{
tObjekt *Temp;
tOMatrix TempMatrix;
Temp=(tObjekt *) malloc(sizeof(tObjekt));
DaObjekt=Temp;
Temp->Position=vNull;
Temp->Rotation=vNull;
// Skelettpunkte berechnen
SkelNodes=0;
TempMatrix=KartMatrix(); // Kartesisches Koordinatensystem
// ModVek=vMulK(Sector->SubSector->Pos,1);
Sector->SubSector->Pos=vSet(0,0.0001,0);
Sector->SubSector->OrgPos=vSet(0,0.0001,0);
/*
ReCalcMatrices(Sector,KartMatrix(),1);
ReCalcMeshes(Sector,KartMatrix(),vNull);
*/
// Temp->Skel=ConvertSectorToSkelNode(Sector->SubSector,NULL,ModVek,KartMatrix(),NULL);
Temp->Skel=ConvertSectorToSkelNode(Sector->SubSector,NULL,vNull,KartMatrix(),NULL);
CalcSphereSize(Temp->Skel);
Temp->SkelList=CreateSkelList(Temp->Skel,Temp);
return(Temp);
}
tObjekt *LoadObjFromBCL(unsigned char *LAddr)
{
tCommand *CommandList;
tSector *Level;
tObjekt *Temp;
// CommandList=LoadLevel(LName);
CommandList=LoadLevelFromMem(LAddr);
Level=ReCalcCommandList(CommandList);
// ReduceSector(Level,0.05);
// ReduceSector(Level,0.13,0.15);
ReCalcMatrices(Level,KartMatrix(),1);
ReCalcMeshes(Level,KartMatrix(),vNull);
Level->SubSector->Pos=vSet(0,0.0001,0);
Level->SubSector->OrgPos=vSet(0,0.0001,0);
// ReCalcMatrices(Level,KartMatrix(),1);
ReCalcMeshes(Level,KartMatrix(),vNull);
ReCalcSectorBoundBoxes(Level);
// ReCalcMeshes(Level,KartMatrix(),vMulK(Level->SubSector->Pos,-1));
ReCalcMeshes(Level,KartMatrix(),vNull);
/*
ReduceSector(Level,0.24,0.24);
ReduceSector(Level,0.24,0.24);
ReduceSector(Level,0.24,0.24);
ReduceSector(Level,0.24,0.24);
*/
Temp=ConvertSectorToObjekt(Level);
DestroySector(Level);
return(Temp);
}
void DestroySkelList(tSkelList *Temp)
{
if(Temp==NULL) return;
DestroySkelList(Temp->Next);
free(Temp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -