/* copy.c * Giram - A GPLed Modelling Program. * Copyright (C) 1999-2002 DindinX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "giram.h" #include "object.h" #include "primitives/bicubic_patch.h" #include "primitives/box.h" #include "primitives/cone.h" #include "csg.h" #include "primitives/cylinder.h" #include "primitives/disc.h" #include "primitives/heightfield.h" #include "primitives/mesh.h" #include "primitives/plane.h" #include "primitives/quadric.h" #include "primitives/sor.h" #include "primitives/sphere.h" #include "primitives/superellipsoid.h" #include "primitives/torus.h" #include "primitives/triangle.h" #include "camera.h" #include "copy.h" #include "transformation.h" #include "color_map.h" /***************************************************************************** * copy_transformations ******************************************************************************/ static GSList *copy_transformations(GSList *org_transforms) { GSList *tmp_list, *new_transforms = NULL; guint i, j; for (tmp_list = org_transforms ; tmp_list ; tmp_list=tmp_list->next) { TransformationStruct *org_trans = tmp_list->data, *new_trans; new_trans = g_new(TransformationStruct, 1); new_trans->type = org_trans->type; new_trans->name = g_strdup(org_trans->name); for (i=0 ; i<4 ; i++) for (j=0 ; j<4 ; j++) { new_trans->transform.Direct[i][j] = org_trans->transform.Direct[i][j]; new_trans->transform.Inverse[i][j] = org_trans->transform.Inverse[i][j]; } V3Dcopy(new_trans->vect, org_trans->vect); new_trans->active = org_trans->active; new_trans->object = NULL; new_transforms = g_slist_append(new_transforms, new_trans); } return new_transforms; } /***************************************************************************** * CopyObject ******************************************************************************/ ObjectStruct *CopyObject(ObjectStruct *OrgObject) { ObjectStruct *LocalObject; if (OrgObject) { switch (OrgObject->Type) { case BICUBIC_PATCH_OBJECT: LocalObject = (ObjectStruct *)g_new(BicubicPatchStruct, 1); { BicubicPatchStruct *bbicubic_patch = (BicubicPatchStruct *)LocalObject; BicubicPatchStruct *org_bicubic_patch = (BicubicPatchStruct *)OrgObject; gint i; bbicubic_patch->u_steps = org_bicubic_patch->u_steps; bbicubic_patch->v_steps = org_bicubic_patch->v_steps; for (i=0 ; i<16 ; i++) { V3Dcopy(bbicubic_patch->control_points[i], org_bicubic_patch->control_points[i]); } } break; case BOX_OBJECT: LocalObject = (ObjectStruct *)g_new(BoxStruct, 1); { BoxStruct *BBox = (BoxStruct *)LocalObject; BoxStruct *OrgBox = (BoxStruct *)OrgObject; V3Dcopy(BBox->MinCorner, OrgBox->MinCorner); V3Dcopy(BBox->MaxCorner, OrgBox->MaxCorner); } break; case CONE_OBJECT: LocalObject = (ObjectStruct *)g_new(ConeStruct, 1); { ConeStruct *CCone = (ConeStruct *)LocalObject; ConeStruct *OrgCone = (ConeStruct *)OrgObject; CCone->Open = OrgCone->Open; CCone->Radius1 = OrgCone->Radius1; CCone->Radius2 = OrgCone->Radius2; } break; case CSG_OBJECT: LocalObject = (ObjectStruct *)g_new(CSGStruct, 1); { CSGStruct *CCSG = (CSGStruct *)LocalObject; CSGStruct *OrgCSG = (CSGStruct *)OrgObject; GSList *tmp_list; CCSG->Type = OrgCSG->Type; CCSG->all_objects = NULL; for (tmp_list = OrgCSG->all_objects; tmp_list ; tmp_list = g_slist_next(tmp_list)) { ObjectStruct *tmp_object = tmp_list->data; CCSG->all_objects = g_slist_append(CCSG->all_objects, CopyObject(tmp_object)); } } break; case CYLINDER_OBJECT: LocalObject = (ObjectStruct *)g_new(CylinderStruct, 1); { CylinderStruct *CCylinder = (CylinderStruct *)LocalObject; CylinderStruct *OrgCylinder = (CylinderStruct *)OrgObject; CCylinder->Open = OrgCylinder->Open; } break; case DISC_OBJECT: LocalObject = (ObjectStruct *)g_new(DiscStruct, 1); { DiscStruct *DDisc = (DiscStruct *)LocalObject; DiscStruct *OrgDisc = (DiscStruct *)OrgObject; DDisc->Radius = OrgDisc->Radius; DDisc->HoleRadius = DDisc->HoleRadius; } break; case HEIGHT_FIELD_OBJECT: LocalObject = (ObjectStruct *)g_new(HeightFieldStruct, 1); { HeightFieldStruct *HHeightfield = (HeightFieldStruct *)LocalObject; HeightFieldStruct *OrgHeightField = (HeightFieldStruct *)OrgObject; HHeightfield->type = OrgHeightField->type; HHeightfield->filename = g_strdup(OrgHeightField->filename); HHeightfield->waterlevel = OrgHeightField->waterlevel; HHeightfield->smooth = OrgHeightField->smooth; } break; case MESH_OBJECT: LocalObject = (ObjectStruct *)g_new(MeshStruct, 1); { MeshStruct *MMesh = (MeshStruct *)LocalObject; MeshStruct *OrgMesh = (MeshStruct *)OrgObject; TriangleListStruct *TmpTri, *NewTri; MMesh->FirstTriangle = NULL; for (TmpTri = OrgMesh->FirstTriangle ; TmpTri ; TmpTri=TmpTri->Next) { NewTri = g_new(TriangleListStruct, 1); NewTri->Next = MMesh->FirstTriangle; MMesh->FirstTriangle = NewTri; V3Dcopy(NewTri->P1, TmpTri->P1); V3Dcopy(NewTri->N1, TmpTri->N1); V3Dcopy(NewTri->P2, TmpTri->P2); V3Dcopy(NewTri->N2, TmpTri->N2); V3Dcopy(NewTri->P3, TmpTri->P3); V3Dcopy(NewTri->N3, TmpTri->N3); } } break; case PLANE_OBJECT: LocalObject = (ObjectStruct *)g_new(PlaneStruct, 1); { PlaneStruct *PPlane = (PlaneStruct *)LocalObject; PlaneStruct *OrgPlane = (PlaneStruct *)OrgObject; V3Dcopy(PPlane->Normal, OrgPlane->Normal); PPlane->Distance = OrgPlane->Distance; PPlane->NbSquare = OrgPlane->NbSquare; PPlane->SquareSize = OrgPlane->SquareSize; } break; case QUADRIC_OBJECT: LocalObject = (ObjectStruct *)g_new(QuadricStruct, 1); { QuadricStruct *QQuadric = (QuadricStruct *)LocalObject; QuadricStruct *OrgQuadric = (QuadricStruct *)OrgObject; QQuadric->A = OrgQuadric->A; QQuadric->B = OrgQuadric->B; QQuadric->C = OrgQuadric->C; QQuadric->D = OrgQuadric->D; QQuadric->E = OrgQuadric->E; QQuadric->F = OrgQuadric->F; QQuadric->G = OrgQuadric->G; QQuadric->H = OrgQuadric->H; QQuadric->I = OrgQuadric->I; QQuadric->J = OrgQuadric->J; } break; case SOR_OBJECT: LocalObject = (ObjectStruct *)g_new(SorStruct, 1); { SorStruct *SSor = (SorStruct *)LocalObject; SorStruct *OrgSor = (SorStruct *)OrgObject; guint i; SSor->NumberOfPoints = OrgSor->NumberOfPoints; SSor->Point = g_new(Vector, SSor->NumberOfPoints); for (i=0 ; iNumberOfPoints ; i++) { SSor->Point[i][0] = OrgSor->Point[i][0]; SSor->Point[i][1] = OrgSor->Point[i][1]; } } break; case SPHERE_OBJECT: LocalObject = (ObjectStruct *)g_new(SphereStruct, 1); { SphereStruct *SSphere = (SphereStruct *)LocalObject; SphereStruct *OrgSphere = (SphereStruct *)OrgObject; V3Dcopy(SSphere->Center, OrgSphere->Center); SSphere->Radius = OrgSphere->Radius; } break; case SUPERELLIPSOID_OBJECT: LocalObject = (ObjectStruct *)g_new(SuperEllipsoidStruct, 1); { SuperEllipsoidStruct *SSuperEllipsoid = (SuperEllipsoidStruct *)LocalObject; SuperEllipsoidStruct *OrgSuperEllipsoid = (SuperEllipsoidStruct *)OrgObject; SSuperEllipsoid->E = OrgSuperEllipsoid->E; SSuperEllipsoid->N = OrgSuperEllipsoid->N; } break; case TORUS_OBJECT: LocalObject = (ObjectStruct *)g_new(TorusStruct, 1); { TorusStruct *TTorus = (TorusStruct *)LocalObject; TorusStruct *OrgTorus = (TorusStruct *)OrgObject; TTorus->Major = OrgTorus->Major; TTorus->Minor = OrgTorus->Minor; } break; case TRIANGLE_OBJECT: LocalObject = (ObjectStruct *)g_new(TriangleStruct, 1); { TriangleStruct *TTriangle = (TriangleStruct *)LocalObject; TriangleStruct *OrgTriangle = (TriangleStruct *)OrgObject; V3Dcopy(TTriangle->P1, OrgTriangle->P1); V3Dcopy(TTriangle->P2, OrgTriangle->P2); V3Dcopy(TTriangle->P3, OrgTriangle->P3); V3Dcopy(TTriangle->N1, OrgTriangle->N1); V3Dcopy(TTriangle->N2, OrgTriangle->N2); V3Dcopy(TTriangle->N3, OrgTriangle->N3); } break; default: LocalObject = NULL; printf("Severe bug in CopyObject\n"); exit(1); } LocalObject->Type = OrgObject->Type; LocalObject->FirstTriangle = NULL; LocalObject->Trans = CopyTransform(OrgObject->Trans); LocalObject->Texture = CopyTexture(OrgObject->Texture); LocalObject->Inverse = OrgObject->Inverse; LocalObject->NoShadow = OrgObject->NoShadow; LocalObject->Hollow = OrgObject->Hollow; LocalObject->selected = OrgObject->selected; LocalObject->visible = OrgObject->visible; LocalObject->name = NULL; LocalObject->parent = OrgObject->parent; LocalObject->all_transforms = copy_transformations(OrgObject->all_transforms); { GSList *tmp_list; for (tmp_list = LocalObject->all_transforms ; tmp_list ; tmp_list=tmp_list->next) { TransformationStruct *trans = tmp_list->data; trans->object = LocalObject; } } LocalObject->frame = OrgObject->frame; LocalObject->klass = OrgObject->klass; giram_object_build_triangle_mesh(LocalObject); return LocalObject; } else return NULL; } /***************************************************************************** * CopyTexture ******************************************************************************/ TextureStruct *CopyTexture(TextureStruct *OrgTexture) { TextureStruct *LocalTexture; if (OrgTexture) { LocalTexture = g_new(TextureStruct, 1); LocalTexture->Pigment = CopyPigment(OrgTexture->Pigment); LocalTexture->finish = CopyFinish(OrgTexture->finish); LocalTexture->Trans = CopyTransform(OrgTexture->Trans); return LocalTexture; } else return NULL; } /***************************************************************************** * CopyFinish ******************************************************************************/ FinishStruct *CopyFinish(FinishStruct *org_finish) { FinishStruct *local_finish; if (org_finish) { local_finish = g_new(FinishStruct, 1); V3Dcopy(local_finish->ambient, org_finish->ambient); local_finish->diffuse = org_finish->diffuse; V3Dcopy(local_finish->reflection, org_finish->reflection); local_finish->brilliance = org_finish->brilliance; local_finish->crand = org_finish->crand; local_finish->phong = org_finish->phong; local_finish->phong_size = org_finish->phong_size; local_finish->specular = org_finish->specular; local_finish->roughness = org_finish->roughness; return local_finish; } else return NULL; } /***************************************************************************** * CopyPigment ******************************************************************************/ PigmentStruct *CopyPigment(PigmentStruct *OrgPigment) { PigmentStruct *LocalPigment; if (OrgPigment) { LocalPigment = g_new(PigmentStruct, 1); LocalPigment->Type = OrgPigment->Type; V5Dcopy(LocalPigment->Color, OrgPigment->Color); V5Dcopy(LocalPigment->Color2, OrgPigment->Color2); V5Dcopy(LocalPigment->Color3, OrgPigment->Color3); LocalPigment->Trans = CopyTransform(OrgPigment->Trans); LocalPigment->color_map = color_map_copy(OrgPigment->color_map); return LocalPigment; } else return NULL; } /***************************************************************************** * CopyCamera ******************************************************************************/ CameraStruct *CopyCamera(CameraStruct *OrgCamera) { CameraStruct *LocalCamera; if (OrgCamera) { LocalCamera = g_new(CameraStruct, 1); LocalCamera->Type = OrgCamera->Type; V3Dcopy(LocalCamera->Location, OrgCamera->Location); V3Dcopy(LocalCamera->LookAt, OrgCamera->LookAt); V3Dcopy(LocalCamera->Right, OrgCamera->Right); V3Dcopy(LocalCamera->Up, OrgCamera->Up); V3Dcopy(LocalCamera->Direction, OrgCamera->Direction); V3Dcopy(LocalCamera->Sky, OrgCamera->Sky); LocalCamera->Angle = OrgCamera->Angle; LocalCamera->BlurSamples = OrgCamera->BlurSamples; LocalCamera->Aperture = OrgCamera->Aperture; V3Dcopy(LocalCamera->FocalPoint, OrgCamera->FocalPoint); LocalCamera->Confidence = OrgCamera->Confidence; LocalCamera->Variance = OrgCamera->Variance; return LocalCamera; } else return NULL; } /***************************************************************************** * CopyLightSource ******************************************************************************/ LightSourceStruct *CopyLightSource(LightSourceStruct *OrgLightSource) { LightSourceStruct *LocalLightSource; if (OrgLightSource) { LocalLightSource = g_new(LightSourceStruct, 1); V3Dcopy(LocalLightSource->Location, OrgLightSource->Location); V5Dcopy(LocalLightSource->Color, OrgLightSource->Color); LocalLightSource->Type = OrgLightSource->Type; V3Dcopy(LocalLightSource->PointAt, OrgLightSource->PointAt); LocalLightSource->Radius = OrgLightSource->Radius; LocalLightSource->FallOff = OrgLightSource->FallOff; LocalLightSource->Tightness = OrgLightSource->Tightness; LocalLightSource->AreaLight = OrgLightSource->AreaLight; V3Dcopy(LocalLightSource->Area1, OrgLightSource->Area1); V3Dcopy(LocalLightSource->Area2, OrgLightSource->Area2); LocalLightSource->AreaSize1 = OrgLightSource->AreaSize1; LocalLightSource->AreaSize2 = OrgLightSource->AreaSize2; LocalLightSource->Adaptive = OrgLightSource->Adaptive; LocalLightSource->Jitter = OrgLightSource->Jitter; //LocalLightSource->LooksLike = CopyObject(OrgLightSource->LooksLike); LocalLightSource->FadeDistance = OrgLightSource->FadeDistance; LocalLightSource->FadePower = OrgLightSource->FadePower; LocalLightSource->AtmosphericAttenuation = OrgLightSource->AtmosphericAttenuation; LocalLightSource->Atmosphere = LocalLightSource->Atmosphere; return LocalLightSource; } else return NULL; } /***************************************************************************** * CopyTransform ******************************************************************************/ TransformStruct *CopyTransform(TransformStruct *OrgTransform) { TransformStruct *LocalTransform; int i,j; if (OrgTransform) { LocalTransform = g_new(TransformStruct, 1); for (i=0 ; i<4 ; i++) for (j=0 ; j<4 ; j++) { LocalTransform->Direct[i][j] = OrgTransform->Direct[i][j]; LocalTransform->Inverse[i][j] = OrgTransform->Inverse[i][j]; } return LocalTransform; } else return NULL; }