/****************************************************************************** Plush Version 1.2 obj.c Object control Copyright (c) 1996-2000, Justin Frankel ******************************************************************************/ #include "plush.h" void pl_Obj::Scale(pl_Float s) { int i = Vertices.GetSize(); pl_Vertex *v = Vertices.Get(); while (i--) { v->x *= s; v->y *= s; v->z *= s; v++; } for (i = 0; i < Children.GetSize(); i ++) if (Children.Get(i)) Children.Get(i)->Scale(s); } void pl_Obj::Stretch(pl_Float x, pl_Float y, pl_Float z) { int i = Vertices.GetSize(); pl_Vertex *v = Vertices.Get(); while (i--) { v->x *= x; v->y *= y; v->z *= z; v++; } for (i = 0; i < Children.GetSize(); i ++) if (Children.Get(i)) Children.Get(i)->Stretch(x,y,z); } void pl_Obj::Translate(pl_Float x, pl_Float y, pl_Float z) { int i = Vertices.GetSize(); pl_Vertex *v = Vertices.Get(); while (i--) { v->x += x; v->y += y; v->z += z; v++; } for (i = 0; i < Children.GetSize(); i ++) if (Children.Get(i)) Children.Get(i)->Translate(x,y,z); } void pl_Obj::FlipNormals() { int i = Vertices.GetSize(); pl_Vertex *v = Vertices.Get(); pl_Face *f = Faces.Get(); while (i--) { v->nx = - v->nx; v->ny = - v->ny; v->nz = - v->nz; v++; } i = Faces.GetSize(); while (i--) { f->nx = - f->nx; f->ny = - f->ny; f->nz = - f->nz; f++; } for (i = 0; i < Children.GetSize(); i ++) if (Children.Get(i)) Children.Get(i)->FlipNormals(); } pl_Obj *pl_Obj::Clone() { int i; pl_Obj *out; if (!(out = new pl_Obj(Vertices.GetSize(),Faces.GetSize()))) return 0; for (i = 0; i < Children.GetSize(); i ++) out->Children.Add(Children.Get(i) ? Children.Get(i)->Clone() : NULL); out->Xa = Xa; out->Ya = Ya; out->Za = Za; out->Xp = Xp; out->Yp = Yp; out->Zp = Zp; out->GenMatrix = GenMatrix; memcpy(out->Matrix,Matrix,sizeof(Matrix)); memcpy(out->Vertices.Get(), Vertices.Get(), sizeof(pl_Vertex) * Vertices.GetSize()); memcpy(out->Faces.Get(),Faces.Get(),sizeof(pl_Face) * Faces.GetSize()); return out; } void pl_Obj::SetMaterial(pl_Mat *m, pl_Bool th) { pl_sInt32 i = Faces.GetSize(); pl_Face *f = Faces.Get(); while (i--) (f++)->Material = m; if (th) for (i = 0; i < Children.GetSize(); i++) if (Children.Get(i)) Children.Get(i)->SetMaterial(m,true); } void pl_Obj::CalculateNormals() { int i; pl_Vertex *v = Vertices.Get(); pl_Face *f = Faces.Get(); double x1, x2, y1, y2, z1, z2; i = Vertices.GetSize(); while (i--) { v->nx = 0.0; v->ny = 0.0; v->nz = 0.0; v++; } i = Faces.GetSize(); while (i--) { pl_Vertex *vp=Vertices.Get(); pl_Vertex *fVertices[3] = { vp+f->VertexIndices[0], vp+f->VertexIndices[1], vp+f->VertexIndices[2], }; x1 = fVertices[0]->x-fVertices[1]->x; x2 = fVertices[0]->x-fVertices[2]->x; y1 = fVertices[0]->y-fVertices[1]->y; y2 = fVertices[0]->y-fVertices[2]->y; z1 = fVertices[0]->z-fVertices[1]->z; z2 = fVertices[0]->z-fVertices[2]->z; f->nx = (pl_Float) (y1*z2 - z1*y2); f->ny = (pl_Float) (z1*x2 - x1*z2); f->nz = (pl_Float) (x1*y2 - y1*x2); plNormalizeVector(&f->nx, &f->ny, &f->nz); fVertices[0]->nx += f->nx; fVertices[0]->ny += f->ny; fVertices[0]->nz += f->nz; fVertices[1]->nx += f->nx; fVertices[1]->ny += f->ny; fVertices[1]->nz += f->nz; fVertices[2]->nx += f->nx; fVertices[2]->ny += f->ny; fVertices[2]->nz += f->nz; f++; } v = Vertices.Get(); i = Vertices.GetSize(); do { plNormalizeVector(&v->nx, &v->ny, &v->nz); v++; } while (--i); for (i = 0; i < Children.GetSize(); i ++) if (Children.Get(i)) Children.Get(i)->CalculateNormals(); }