первый
This commit is contained in:
579
lib/object3d.cpp
Normal file
579
lib/object3d.cpp
Normal file
@ -0,0 +1,579 @@
|
||||
//#pragma hdrstop
|
||||
|
||||
#include <GL/glew.h> //Должен стоять до "wx/gl...h"
|
||||
#include <GL/glu.h>
|
||||
|
||||
#include <wx/glcanvas.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "object3d.h"
|
||||
#include "texture.h"
|
||||
#include "mathTools.h"
|
||||
//#include "tools/debug.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
TTriMat::TTriMat()
|
||||
{
|
||||
textureid=0;
|
||||
ColorAmbientRGB.r=0.2f; // 0.2 по умолчанию в OpenGL
|
||||
ColorAmbientRGB.g=0.2f;
|
||||
ColorAmbientRGB.b=0.2f;
|
||||
ColorAmbientRGB.a=1.0f;
|
||||
ColorDiffuseRGB.r=0.8f; // 0.8 по умолчанию в OpenGL
|
||||
ColorDiffuseRGB.g=0.8f;
|
||||
ColorDiffuseRGB.b=0.8f;
|
||||
ColorDiffuseRGB.a=1.0f;
|
||||
ColorSpecularRGB.r=0.0f; // 0.0 по умолчанию в OpenGL
|
||||
ColorSpecularRGB.g=0.0f;
|
||||
ColorSpecularRGB.b=0.0f;
|
||||
ColorSpecularRGB.a=1.0f;
|
||||
USCALE=1.0f;
|
||||
VSCALE=1.0f;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void TTriMat::Release()
|
||||
{
|
||||
//прозрачность
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_LIGHTING);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&ColorAmbientRGB);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&ColorDiffuseRGB);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&ColorSpecularRGB);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); //яркость источника цвета от 0 до 128
|
||||
|
||||
//если текстурированна
|
||||
if(textureid!=0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, textureid);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
//чтобы цвет не воздействовал на текстуру если она есть
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glColor4f(1,1,1,ColorDiffuseRGB.a);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
} else glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TTriangles::TTriangles()
|
||||
{
|
||||
del=false;
|
||||
bSmooth=false;
|
||||
CountVertex=0;
|
||||
CountFaces=0;
|
||||
//countMapPoint=0;
|
||||
Vertices=NULL;
|
||||
SmoothNormals=NULL;
|
||||
faces=NULL;
|
||||
TexVertices=NULL;
|
||||
SmoothG=NULL;
|
||||
bInit=false;
|
||||
//разбивка по материалам
|
||||
countMF=0;
|
||||
MatFaces=NULL;
|
||||
//материал (после разбивки)
|
||||
TriMat=NULL;
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
TTriangles::~TTriangles()
|
||||
{
|
||||
if (Vertices!=NULL) delete[] Vertices;
|
||||
Vertices=NULL;
|
||||
if (SmoothNormals!=NULL) delete[] SmoothNormals;
|
||||
SmoothNormals=NULL;
|
||||
if (faces!=NULL) delete[] faces;
|
||||
faces=NULL;
|
||||
if (TexVertices!=NULL) delete[] TexVertices;
|
||||
TexVertices=NULL;
|
||||
if (SmoothG!=NULL) delete[] SmoothG;
|
||||
SmoothG=NULL;
|
||||
if (bInit)
|
||||
{
|
||||
glDeleteBuffersARB(1,&vbov);
|
||||
glDeleteBuffersARB(1,&vbot);
|
||||
glDeleteBuffersARB(1,&vbon);
|
||||
glDeleteBuffersARB(1,&vbof);
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<countMF;i++)
|
||||
{
|
||||
delete[] MatFaces[i].name;
|
||||
delete[] MatFaces[i].faces;
|
||||
}
|
||||
if(MatFaces!=NULL) delete[] MatFaces;
|
||||
MatFaces=NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//TODO предусмотреть загрузку в видео память как 1го объекта так и группы (если группой то здесь сохраняется указатель и смещение к нужному объекту)
|
||||
void TTriangles::render()
|
||||
{
|
||||
if(TexVertices==NULL) TexVertices = new RfPointXY[CountVertex];
|
||||
//if(Material!=NULL) Material.Release();
|
||||
|
||||
if(!bSmooth) glShadeModel(GL_FLAT); else glShadeModel(GL_SMOOTH);
|
||||
|
||||
//передаём указатели на массивы и рендерим
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
/*RdPointXYZ *d=new RdPointXYZ[CountVertex];
|
||||
for(unsigned int i=0;i<CountVertex;i++)
|
||||
{
|
||||
d[i].x=Vertices[i].x;
|
||||
d[i].y=Vertices[i].y;
|
||||
d[i].z=Vertices[i].z;
|
||||
}
|
||||
glVertexPointer(3,GL_DOUBLE,0,&d[0]);*/
|
||||
|
||||
glVertexPointer(3,GL_FLOAT,0,&Vertices[0]);
|
||||
glNormalPointer(GL_FLOAT, 0, &SmoothNormals[0]);
|
||||
glTexCoordPointer(2,GL_FLOAT, 0, &TexVertices[0]);
|
||||
glDrawElements(GL_TRIANGLES, CountFaces*3, GL_UNSIGNED_SHORT, &faces[0]);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
|
||||
//delete[] d;
|
||||
/**/
|
||||
/*if (!bInit)
|
||||
{
|
||||
//огромные переделки:
|
||||
//однотипные обьекты должны храниться в одном vbov значит рендеринг должен быть преобразован в другой вид а именно
|
||||
//с начала идет цикл по всем созданным VBO он биндиться потом цикл по моделям(смещениям) в этом VBO здесь применяеться механизм отсечения потом
|
||||
//потом применяеться подходящяя текстура потом собственно glDrawElements
|
||||
|
||||
glGenBuffersARB(1,&vbov);
|
||||
glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbov );
|
||||
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*sizeof(RfPointXYZ), &fPointXYZ[0], GL_STATIC_DRAW_ARB);
|
||||
|
||||
glGenBuffersARB(1,&vbot);
|
||||
glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbot );
|
||||
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*sizeof(RfPointXY), &fMapPointXY[0], GL_STATIC_DRAW_ARB );
|
||||
|
||||
glGenBuffersARB(1,&vbon);
|
||||
glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbon );
|
||||
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*sizeof(RfPointXYZ), &fNormalXYZ[0], GL_STATIC_DRAW_ARB );
|
||||
|
||||
glGenBuffersARB(1,&vbof);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbof);
|
||||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, p_object->faces*sizeof(RsFacesABC), &face[0], GL_STATIC_DRAW_ARB);
|
||||
|
||||
bInit=true;
|
||||
}
|
||||
// vbov,vbon,vbot,vbof :TGLuint; //вершины,нормали,текстура,рёбра
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbov);
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbot);
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbon);
|
||||
glNormalPointer( GL_FLOAT, 0, (char *) NULL );
|
||||
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbof);
|
||||
glDrawElements(GL_TRIANGLES, p_object->faces*3 ,GL_UNSIGNED_SHORT, NULL);
|
||||
|
||||
//биндим нулевой буфер
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
|
||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
/**/
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TTriangles::CalcMinMaxPoint()
|
||||
{
|
||||
if(CountVertex>0)
|
||||
{
|
||||
MaxPointXYZ.x=Vertices[0].x;
|
||||
MaxPointXYZ.y=Vertices[0].y;
|
||||
MaxPointXYZ.z=Vertices[0].z;
|
||||
MinPointXYZ.x=Vertices[0].x;
|
||||
MinPointXYZ.y=Vertices[0].y;
|
||||
MinPointXYZ.z=Vertices[0].z;
|
||||
}
|
||||
for(unsigned int i=1;i<CountVertex;i++)
|
||||
{
|
||||
if(MaxPointXYZ.x<Vertices[i].x) MaxPointXYZ.x=Vertices[i].x;
|
||||
if(MaxPointXYZ.y<Vertices[i].y) MaxPointXYZ.y=Vertices[i].y;
|
||||
if(MaxPointXYZ.z<Vertices[i].z) MaxPointXYZ.z=Vertices[i].z;
|
||||
|
||||
if(MinPointXYZ.x>Vertices[i].x) MinPointXYZ.x=Vertices[i].x;
|
||||
if(MinPointXYZ.y>Vertices[i].y) MinPointXYZ.y=Vertices[i].y;
|
||||
if(MinPointXYZ.z>Vertices[i].z) MinPointXYZ.z=Vertices[i].z;
|
||||
}
|
||||
PointXYZCenter.x=(MinPointXYZ.x+MaxPointXYZ.x)/2.0f;
|
||||
PointXYZCenter.y=(MinPointXYZ.y+MaxPointXYZ.y)/2.0f;
|
||||
PointXYZCenter.z=(MinPointXYZ.z+MaxPointXYZ.z)/2.0f;
|
||||
|
||||
|
||||
/* //DOTO есть такие параметры как сдвиг вращения масштаб я здесь учитываю только масштаб и сдвиг
|
||||
MaxPointXYZ.x=(MaxPointXYZ.x*ScaleXYZ.x)+ShiftXYZ.x;
|
||||
MaxPointXYZ.y=(MaxPointXYZ.y*ScaleXYZ.y)+ShiftXYZ.y;
|
||||
MaxPointXYZ.z=(MaxPointXYZ.z*ScaleXYZ.z)+ShiftXYZ.z;
|
||||
MinPointXYZ.x=(MinPointXYZ.x*ScaleXYZ.x)+ShiftXYZ.x;
|
||||
MinPointXYZ.y=(MinPointXYZ.y*ScaleXYZ.y)+ShiftXYZ.y;
|
||||
MinPointXYZ.z=(MinPointXYZ.z*ScaleXYZ.z)+ShiftXYZ.z;
|
||||
|
||||
//так как выделяем обьект по попаданию точки в нутырь куба для плоских обьектов немного расширем пространиство
|
||||
MaxPointXYZ.x=MaxPointXYZ.x+0.001;
|
||||
MaxPointXYZ.y=MaxPointXYZ.y+0.001;
|
||||
MaxPointXYZ.z=MaxPointXYZ.z+0.001;
|
||||
MinPointXYZ.x=MinPointXYZ.x-0.001;
|
||||
MinPointXYZ.y=MinPointXYZ.y-0.001;
|
||||
MinPointXYZ.z=MinPointXYZ.z-0.001;*/
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//просчитать сглаживающие нормали к поверхности
|
||||
void TTriangles::CalcSmoothNormals()
|
||||
{
|
||||
unsigned int j;
|
||||
if(SmoothNormals==NULL) SmoothNormals=new RfPointXYZ[CountVertex]; //память под нормали к точке
|
||||
//если отключенно сглаживание то учитываеться только последний вектор к грани
|
||||
if(!bSmooth)
|
||||
{
|
||||
for(j=0;j<CountVertex;j++)
|
||||
{
|
||||
SmoothNormals[j].x=0;
|
||||
SmoothNormals[j].y=0;
|
||||
SmoothNormals[j].z=0;
|
||||
}
|
||||
for(j=0;j<CountFaces;j++)
|
||||
{
|
||||
CalcNormals(Vertices[faces[j].a].x,Vertices[faces[j].a].y,Vertices[faces[j].a].z,Vertices[faces[j].b].x,Vertices[faces[j].b].y,Vertices[faces[j].b].z,Vertices[faces[j].c].x,Vertices[faces[j].c].y,Vertices[faces[j].c].z,SmoothNormals[faces[j].c].x,SmoothNormals[faces[j].c].y,SmoothNormals[faces[j].c].z);
|
||||
}
|
||||
}else
|
||||
{
|
||||
for(j=0;j<CountVertex;j++)
|
||||
{
|
||||
SmoothNormals[j].x=0;
|
||||
SmoothNormals[j].y=0;
|
||||
SmoothNormals[j].z=0;
|
||||
}
|
||||
unsigned int *mas=new unsigned int[CountVertex];
|
||||
for(j=0;j<CountVertex;j++) mas[j]=0; //для усреднения
|
||||
//подсчитываем нормали для каждой точки
|
||||
RfPointXYZ point;
|
||||
for(j=0;j<CountFaces;j++)
|
||||
{
|
||||
CalcNormals(Vertices[faces[j].a].x,Vertices[faces[j].a].y,Vertices[faces[j].a].z,Vertices[faces[j].b].x,Vertices[faces[j].b].y,Vertices[faces[j].b].z,Vertices[faces[j].c].x,Vertices[faces[j].c].y,Vertices[faces[j].c].z,point.x,point.y,point.z);
|
||||
SmoothNormals[faces[j].a].x=SmoothNormals[faces[j].a].x+point.x;
|
||||
SmoothNormals[faces[j].a].y=SmoothNormals[faces[j].a].y+point.y;
|
||||
SmoothNormals[faces[j].a].z=SmoothNormals[faces[j].a].z+point.z;
|
||||
mas[faces[j].a]++;
|
||||
SmoothNormals[faces[j].b].x=SmoothNormals[faces[j].b].x+point.x;
|
||||
SmoothNormals[faces[j].b].y=SmoothNormals[faces[j].b].y+point.y;
|
||||
SmoothNormals[faces[j].b].z=SmoothNormals[faces[j].b].z+point.z;
|
||||
mas[faces[j].b]++;
|
||||
SmoothNormals[faces[j].c].x=SmoothNormals[faces[j].c].x+point.x;
|
||||
SmoothNormals[faces[j].c].y=SmoothNormals[faces[j].c].y+point.y;
|
||||
SmoothNormals[faces[j].c].z=SmoothNormals[faces[j].c].z+point.z;
|
||||
mas[faces[j].c]++;
|
||||
}
|
||||
//нормализуем нормали
|
||||
for(j=0;j<CountVertex;j++)
|
||||
{
|
||||
SmoothNormals[j].x=SmoothNormals[j].x/mas[j];
|
||||
SmoothNormals[j].y=SmoothNormals[j].y/mas[j];
|
||||
SmoothNormals[j].z=SmoothNormals[j].z/mas[j];
|
||||
normalized(SmoothNormals[j]); //приведу к еденичной длине
|
||||
}
|
||||
delete[] mas;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TTriangles::cutOnSmoothGroup()
|
||||
{
|
||||
/*if(SmoothG==NULL)
|
||||
{*/
|
||||
//груп сглаживания нет то каждая грань имеет единоличные точки
|
||||
RfPointXYZ *vbuf=new RfPointXYZ[CountFaces*3];
|
||||
RfPointXY *tbuf=new RfPointXY[CountFaces*3];
|
||||
unsigned short count=0;
|
||||
for(unsigned int i=0;i<CountFaces;i++)
|
||||
{
|
||||
vbuf[count]=Vertices[faces[i].a];
|
||||
if(TexVertices!=NULL) tbuf[count]=TexVertices[faces[i].a];
|
||||
faces[i].a=count; //сохраняем новый номер точки
|
||||
count++;
|
||||
vbuf[count]=Vertices[faces[i].b];
|
||||
if(TexVertices!=NULL) tbuf[count]=TexVertices[faces[i].b];
|
||||
faces[i].b=count; //сохраняем новый номер точки
|
||||
count++;
|
||||
vbuf[count]=Vertices[faces[i].c];
|
||||
if(TexVertices!=NULL) tbuf[count]=TexVertices[faces[i].c];
|
||||
faces[i].c=count; //сохраняем новый номер точки
|
||||
count++;
|
||||
}
|
||||
delete[] Vertices;
|
||||
Vertices=vbuf;
|
||||
CountVertex=CountFaces*3;
|
||||
if(TexVertices!=NULL) delete[] TexVertices;
|
||||
TexVertices=tbuf;
|
||||
/*}else
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
CalcSmoothNormals(); //просчитываем сглаживающие нормали к точкам
|
||||
delete[] SmoothG;
|
||||
SmoothG=NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//добавить материал
|
||||
//название материала,колво элементов, список фейсов с этим материалом
|
||||
void TTriangles::AddMaterial(char *name,unsigned short count,unsigned short *faces)
|
||||
{
|
||||
RMatFaces *buf=new RMatFaces[countMF+1];
|
||||
for(unsigned int i=0;i<countMF;i++) buf[i]=MatFaces[i];
|
||||
buf[countMF].name=name;
|
||||
buf[countMF].count=count;
|
||||
buf[countMF].faces=faces;
|
||||
if(MatFaces!=NULL) delete[] MatFaces;
|
||||
MatFaces=buf;
|
||||
countMF++;
|
||||
}
|
||||
//******************************************************************************
|
||||
TTrianglesList::TTrianglesList()
|
||||
{
|
||||
count=0;
|
||||
List=NULL;
|
||||
countMat=0; //количество материалов
|
||||
ListMat=NULL; //массив материалов
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
TTrianglesList::~TTrianglesList()
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++) delete List[i];
|
||||
if(List!=NULL) delete[] List;
|
||||
count=4294967295; //на всяк.
|
||||
|
||||
for(unsigned int i=0;i<countMat;i++) delete ListMat[i];
|
||||
if(ListMat!=NULL) delete[] ListMat;
|
||||
countMat=4294967295; //на всяк.
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
TTriangles* TTrianglesList::Add()
|
||||
{
|
||||
TTriangles **buf = new TTriangles*[count+1];
|
||||
for(unsigned int i=0;i<count;i++) buf[i]=List[i];
|
||||
buf[count]=new TTriangles();
|
||||
if(List!=NULL) delete[] List;
|
||||
List=buf;
|
||||
return List[count++];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//удалить обьект из массива
|
||||
void TTrianglesList::DelTri(TTriangles* tri)
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
if(List[i]==tri)
|
||||
{
|
||||
TTriangles **buf = new TTriangles*[count-1];
|
||||
unsigned int pos=0;
|
||||
for(unsigned int j=0;j<count;j++)
|
||||
{
|
||||
if(i!=j){buf[pos]=List[j]; pos++;}
|
||||
}
|
||||
delete[] List;
|
||||
delete tri;
|
||||
List=buf;
|
||||
count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//добавить новый метериал
|
||||
TTriMat* TTrianglesList::AddMat()
|
||||
{
|
||||
TTriMat **buf = new TTriMat*[countMat+1];
|
||||
for(unsigned int i=0;i<countMat;i++) buf[i]=ListMat[i];
|
||||
buf[countMat]=new TTriMat();
|
||||
if(ListMat!=NULL) delete[] ListMat;
|
||||
ListMat=buf;
|
||||
return ListMat[countMat++];
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TTrianglesList::render()
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
if(tri->TriMat!=NULL) tri->TriMat->Release();
|
||||
tri->render();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TTrianglesList::CalcMinMaxPoint()
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
tri->CalcMinMaxPoint();
|
||||
if(i==0) MinPointXYZ=tri->MinPointXYZ; else
|
||||
{
|
||||
if(MinPointXYZ.x>tri->MinPointXYZ.x) MinPointXYZ.x=tri->MinPointXYZ.x;
|
||||
if(MinPointXYZ.y>tri->MinPointXYZ.y) MinPointXYZ.y=tri->MinPointXYZ.y;
|
||||
if(MinPointXYZ.z>tri->MinPointXYZ.z) MinPointXYZ.z=tri->MinPointXYZ.z;
|
||||
}
|
||||
if(i==0) MaxPointXYZ=tri->MaxPointXYZ; else
|
||||
{
|
||||
if(MaxPointXYZ.x<tri->MaxPointXYZ.x) MaxPointXYZ.x=tri->MaxPointXYZ.x;
|
||||
if(MaxPointXYZ.y<tri->MaxPointXYZ.y) MaxPointXYZ.y=tri->MaxPointXYZ.y;
|
||||
if(MaxPointXYZ.z<tri->MaxPointXYZ.z) MaxPointXYZ.z=tri->MaxPointXYZ.z;
|
||||
}
|
||||
}
|
||||
CenterPointXYZ.x=(MaxPointXYZ.x+MinPointXYZ.x)/2.0f;
|
||||
CenterPointXYZ.y=(MaxPointXYZ.y+MinPointXYZ.y)/2.0f;
|
||||
CenterPointXYZ.z=(MaxPointXYZ.z+MinPointXYZ.z)/2.0f;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TTrianglesList::CalcSmoothNormals()
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
tri->CalcSmoothNormals();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void TTrianglesList::cutOnSmoothGroup()
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
tri->cutOnSmoothGroup();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
TTriMat *TTrianglesList::FindMatOnName(char *name)
|
||||
{
|
||||
for(unsigned int i=0;i<countMat;i++)
|
||||
{
|
||||
if(wxString::FromAscii(ListMat[i]->name).Lower()==wxString::FromAscii(name).Lower()) return ListMat[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//разбить обьект по списку материалов (сколько материалов столшько и объектов будет)
|
||||
//применять после разбения по группам сглаживания и просчёта нормалей а то на границе между разными материалами не будет сглаживания
|
||||
void TTrianglesList::cutOnMaterials()
|
||||
{
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
if(tri->countMF==1)
|
||||
{
|
||||
tri->TriMat=FindMatOnName(tri->MatFaces[0].name);
|
||||
}else
|
||||
if(tri->countMF>1) //если несколько материалов то размножаем объекты
|
||||
{
|
||||
//в списке фейсов для этого материала раздные точки
|
||||
//составляем список уникальных точек затем копируем их
|
||||
//память выделяем под самый плохой вариант
|
||||
unsigned short *buf=new unsigned short[tri->CountVertex*2]; //уникальные номера точек
|
||||
for(unsigned int j=0;j<tri->countMF;j++)
|
||||
{
|
||||
//создаём новый объект и копируем туда точки в соответствии с материалом
|
||||
unsigned int cnt=0;
|
||||
for(unsigned int k=0;k<tri->MatFaces[j].count;k++)
|
||||
{
|
||||
if(tri->MatFaces[j].faces[k]>=tri->CountFaces)
|
||||
return;
|
||||
|
||||
bool b=false;
|
||||
for(unsigned int q=0;q<cnt;q++)
|
||||
if(buf[q]==tri->faces[tri->MatFaces[j].faces[k]].a)
|
||||
{
|
||||
b=true;
|
||||
break;
|
||||
}
|
||||
if(!b){buf[cnt]=tri->faces[tri->MatFaces[j].faces[k]].a; cnt++;}
|
||||
b=false;
|
||||
for(unsigned int q=0;q<cnt;q++)
|
||||
if(buf[q]==tri->faces[tri->MatFaces[j].faces[k]].b)
|
||||
{
|
||||
b=true;
|
||||
break;
|
||||
}
|
||||
if(!b){buf[cnt]=tri->faces[tri->MatFaces[j].faces[k]].b; cnt++;}
|
||||
b=false;
|
||||
for(unsigned int q=0;q<cnt;q++)
|
||||
if(buf[q]==tri->faces[tri->MatFaces[j].faces[k]].c)
|
||||
{
|
||||
b=true;
|
||||
break;
|
||||
}
|
||||
if(!b){buf[cnt]=tri->faces[tri->MatFaces[j].faces[k]].c; cnt++;}
|
||||
}
|
||||
//выбрали список точек нужных для нового обьекта теперь копируем
|
||||
TTriangles* newTri=Add();
|
||||
newTri->TriMat=FindMatOnName(tri->MatFaces[j].name);
|
||||
newTri->CountVertex=cnt;
|
||||
newTri->Vertices=new RfPointXYZ[newTri->CountVertex];
|
||||
newTri->TexVertices=new RfPointXY[newTri->CountVertex];
|
||||
newTri->SmoothNormals=new RfPointXYZ[newTri->CountVertex];
|
||||
newTri->CountFaces=tri->MatFaces[j].count;
|
||||
newTri->faces=new RsFacesABC[newTri->CountFaces];
|
||||
for(unsigned int k=0;k<cnt;k++) //копируем точки
|
||||
{
|
||||
newTri->Vertices[k]=tri->Vertices[buf[k]];
|
||||
newTri->TexVertices[k]=tri->TexVertices[buf[k]];
|
||||
newTri->SmoothNormals[k]=tri->SmoothNormals[buf[k]];
|
||||
}
|
||||
for(unsigned int k=0;k<tri->MatFaces[j].count;k++)
|
||||
{
|
||||
newTri->faces[k]=tri->faces[tri->MatFaces[j].faces[k]];
|
||||
//ищем номер точки
|
||||
bool b=true;
|
||||
for(unsigned int q=0;q<cnt;q++){ if(newTri->faces[k].a==buf[q]) {newTri->faces[k].a=q; b=false; break;} }
|
||||
if(b||newTri->faces[k].a>=cnt)
|
||||
return;
|
||||
b=true;
|
||||
for(unsigned int q=0;q<cnt;q++){ if(newTri->faces[k].b==buf[q]) {newTri->faces[k].b=q; b=false; break;} }
|
||||
if(b||newTri->faces[k].b>=cnt)
|
||||
return;
|
||||
b=true;
|
||||
for(unsigned int q=0;q<cnt;q++){ if(newTri->faces[k].c==buf[q]) {newTri->faces[k].c=q; b=false; break;} }
|
||||
if(b||newTri->faces[k].c>=cnt)
|
||||
return;
|
||||
}
|
||||
}
|
||||
tri->del=true;
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int i=0;
|
||||
while(i<count)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
//tri->CountVertex;
|
||||
if(tri->del)
|
||||
DelTri(tri);
|
||||
else i++;
|
||||
}
|
||||
|
||||
//домножаем текущие координаты материала на USCALE и VSCALE текущего материала
|
||||
|
||||
for(unsigned int i=0;i<count;i++)
|
||||
{
|
||||
TTriangles *tri=List[i];
|
||||
if(tri->TriMat!=NULL)
|
||||
for(unsigned int j=0;j<tri->CountVertex;j++)
|
||||
{
|
||||
tri->TexVertices[j].x*=tri->TriMat->USCALE;
|
||||
tri->TexVertices[j].y*=tri->TriMat->VSCALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user