//************************************************************************************* //************************************************************************************* long ObjectAddFace(EERIE_3DOBJ * obj, EERIE_FACE * face, EERIE_3DOBJ * srcobj) { long i; for (i = 0; i < obj->nbfaces; i++) // Check Already existing faces { if ((obj->vertexlist[obj->facelist[i].vid[0]].v.x == srcobj->vertexlist[face->vid[0]].v.x) && (obj->vertexlist[obj->facelist[i].vid[1]].v.x == srcobj->vertexlist[face->vid[1]].v.x) && (obj->vertexlist[obj->facelist[i].vid[2]].v.x == srcobj->vertexlist[face->vid[2]].v.x) && (obj->vertexlist[obj->facelist[i].vid[0]].v.y == srcobj->vertexlist[face->vid[0]].v.y) && (obj->vertexlist[obj->facelist[i].vid[1]].v.y == srcobj->vertexlist[face->vid[1]].v.y) && (obj->vertexlist[obj->facelist[i].vid[2]].v.y == srcobj->vertexlist[face->vid[2]].v.y) && (obj->vertexlist[obj->facelist[i].vid[0]].v.z == srcobj->vertexlist[face->vid[0]].v.z) && (obj->vertexlist[obj->facelist[i].vid[1]].v.z == srcobj->vertexlist[face->vid[1]].v.z) && (obj->vertexlist[obj->facelist[i].vid[2]].v.z == srcobj->vertexlist[face->vid[2]].v.z) ) return -1; } long f0, f1, f2; f0 = ObjectAddVertex(obj, &srcobj->vertexlist[face->vid[0]]); f1 = ObjectAddVertex(obj, &srcobj->vertexlist[face->vid[1]]); f2 = ObjectAddVertex(obj, &srcobj->vertexlist[face->vid[2]]); if ((f1 == -1) || (f2 == -1) || (f0 == -1)) return -1; if (obj->nbfaces == 0) { obj->facelist = (EERIE_FACE *)malloc(sizeof(EERIE_FACE)); } else { obj->facelist = (EERIE_FACE *)realloc(obj->facelist, sizeof(EERIE_FACE) * (obj->nbfaces + 1)); } memcpy(&obj->facelist[obj->nbfaces], face, sizeof(EERIE_FACE)); obj->facelist[obj->nbfaces].vid[0] = (unsigned short)f0; obj->facelist[obj->nbfaces].vid[1] = (unsigned short)f1; obj->facelist[obj->nbfaces].vid[2] = (unsigned short)f2; obj->facelist[obj->nbfaces].texid = 0; for (i = 0; i < obj->nbmaps; i++) { if (obj->texturecontainer[i] == srcobj->texturecontainer[face->texid]) { obj->facelist[obj->nbfaces].texid = (short)i; break; } } obj->nbfaces++; return (obj->nbfaces - 1); }
//************************************************************************************* //************************************************************************************* long ObjectAddAction(EERIE_3DOBJ * obj, char * name, long act, long sfx, EERIE_VERTEX * vert) { long newvert = ObjectAddVertex(obj, vert); if (newvert < 0) return -1; if (obj->nbaction == 0) { obj->actionlist = (EERIE_ACTIONLIST *)malloc(sizeof(EERIE_ACTIONLIST)); } else { for (long i = 0; i < obj->nbaction; i++) { if (!strcmp(obj->actionlist[i].name, name)) return i; } obj->actionlist = (EERIE_ACTIONLIST *)realloc(obj->actionlist, sizeof(EERIE_ACTIONLIST) * (obj->nbaction + 1)); } strcpy(obj->actionlist[obj->nbaction].name, name); obj->actionlist[obj->nbaction].act = act; obj->actionlist[obj->nbaction].sfx = sfx; obj->actionlist[obj->nbaction].idx = newvert; obj->nbaction++; return (obj->nbaction - 1); }
static long ObjectAddFace(EERIE_3DOBJ * obj, const EERIE_FACE * face, const EERIE_3DOBJ * srcobj) { // Check Already existing faces for(size_t i = 0; i < obj->facelist.size(); i++) { if(obj->vertexlist[obj->facelist[i].vid[0]].v.x == srcobj->vertexlist[face->vid[0]].v.x && obj->vertexlist[obj->facelist[i].vid[1]].v.x == srcobj->vertexlist[face->vid[1]].v.x && obj->vertexlist[obj->facelist[i].vid[2]].v.x == srcobj->vertexlist[face->vid[2]].v.x && obj->vertexlist[obj->facelist[i].vid[0]].v.y == srcobj->vertexlist[face->vid[0]].v.y && obj->vertexlist[obj->facelist[i].vid[1]].v.y == srcobj->vertexlist[face->vid[1]].v.y && obj->vertexlist[obj->facelist[i].vid[2]].v.y == srcobj->vertexlist[face->vid[2]].v.y && obj->vertexlist[obj->facelist[i].vid[0]].v.z == srcobj->vertexlist[face->vid[0]].v.z && obj->vertexlist[obj->facelist[i].vid[1]].v.z == srcobj->vertexlist[face->vid[1]].v.z && obj->vertexlist[obj->facelist[i].vid[2]].v.z == srcobj->vertexlist[face->vid[2]].v.z ) { return -1; } } size_t f0 = ObjectAddVertex(obj, &srcobj->vertexlist[face->vid[0]]); size_t f1 = ObjectAddVertex(obj, &srcobj->vertexlist[face->vid[1]]); size_t f2 = ObjectAddVertex(obj, &srcobj->vertexlist[face->vid[2]]); obj->facelist.push_back(*face); obj->facelist.back().vid[0] = (unsigned short)f0; obj->facelist.back().vid[1] = (unsigned short)f1; obj->facelist.back().vid[2] = (unsigned short)f2; obj->facelist.back().texid = 0; for(size_t i = 0; i < obj->texturecontainer.size(); i++) { if(0 <= face->texid && (size_t)face->texid < srcobj->texturecontainer.size() && obj->texturecontainer[i] == srcobj->texturecontainer[face->texid] ) { obj->facelist.back().texid = (short)i; break; } } return obj->facelist.size() - 1; }
static void ObjectAddAction(EERIE_3DOBJ * obj, const std::string & name, long act, long sfx, const EERIE_VERTEX * vert) { size_t newvert = ObjectAddVertex(obj, vert); for(std::vector<EERIE_ACTIONLIST>::iterator i = obj->actionlist.begin(); i != obj->actionlist.end(); ++i) { if(i->name == name) { return; } } obj->actionlist.push_back(EERIE_ACTIONLIST()); EERIE_ACTIONLIST & action = obj->actionlist.back(); action.name = name; action.act = act; action.sfx = sfx; action.idx = ActionPoint(newvert); }
//************************************************************************************* //************************************************************************************* EERIE_3DOBJ * CreateIntermediaryMesh(EERIE_3DOBJ * obj1, EERIE_3DOBJ * obj2, long tw) { long i; long tw1 = -1; long tw2 = -1; long iw1 = -1; long iw2 = -1; long jw1 = -1; long jw2 = -1; long sel_head1 = -1; long sel_head2 = -1; long sel_torso1 = -1; long sel_torso2 = -1; long sel_legs1 = -1; long sel_legs2 = -1; // First we retreive selection groups indexes for (i = 0; i < obj1->nbselections; i++) { if (!strcasecmp(obj1->selections[i].name, "head")) sel_head1 = i; else if (!strcasecmp(obj1->selections[i].name, "chest")) sel_torso1 = i; else if (!strcasecmp(obj1->selections[i].name, "leggings")) sel_legs1 = i; } for (i = 0; i < obj2->nbselections; i++) { if (!strcasecmp(obj2->selections[i].name, "head")) sel_head2 = i; else if (!strcasecmp(obj2->selections[i].name, "chest")) sel_torso2 = i; else if (!strcasecmp(obj2->selections[i].name, "leggings")) sel_legs2 = i; } if (sel_head1 == -1) return NULL; if (sel_head2 == -1) return NULL; if (sel_torso1 == -1) return NULL; if (sel_torso2 == -1) return NULL; if (sel_legs1 == -1) return NULL; if (sel_legs2 == -1) return NULL; if (tw == TWEAK_HEAD) { tw1 = sel_head1; tw2 = sel_head2; iw1 = sel_torso1; iw2 = sel_torso2; jw1 = sel_legs1; jw2 = sel_legs2; } if (tw == TWEAK_TORSO) { tw1 = sel_torso1; tw2 = sel_torso2; iw1 = sel_head1; iw2 = sel_head2; jw1 = sel_legs1; jw2 = sel_legs2; } if (tw == TWEAK_LEGS) { tw1 = sel_legs1; tw2 = sel_legs2; iw1 = sel_torso1; iw2 = sel_torso2; jw1 = sel_head1; jw2 = sel_head2; } if ((tw1 == -1) || (tw2 == -1)) return NULL; // Now Retreives Tweak Action Points { long idx_head1, idx_head2; long idx_torso1, idx_torso2; long idx_legs1, idx_legs2; idx_head1 = GetActionPoint(obj1, "head2chest"); if (idx_head1 < 0) return NULL; idx_head2 = GetActionPoint(obj2, "head2chest"); if (idx_head2 < 0) return NULL; idx_torso1 = GetActionPoint(obj1, "chest2leggings"); if (idx_torso1 < 0) return NULL; idx_torso2 = GetActionPoint(obj2, "chest2leggings"); if (idx_torso2 < 0) return NULL; idx_legs1 = obj1->origin; idx_legs2 = obj2->origin; } // copy vertexes EERIE_VERTEX * obj1vertexlist2 = NULL; EERIE_VERTEX * obj2vertexlist2 = NULL; obj1vertexlist2 = (EERIE_VERTEX *)malloc(sizeof(EERIE_VERTEX) * obj1->nbvertex); obj2vertexlist2 = (EERIE_VERTEX *)malloc(sizeof(EERIE_VERTEX) * obj2->nbvertex); memcpy(obj1vertexlist2, obj1->vertexlist, sizeof(EERIE_VERTEX)*obj1->nbvertex); memcpy(obj2vertexlist2, obj2->vertexlist, sizeof(EERIE_VERTEX)*obj2->nbvertex); // Work will contain the Tweaked object EERIE_3DOBJ * work = NULL; work = (EERIE_3DOBJ *)malloc(sizeof(EERIE_3DOBJ)); memset(work, 0, sizeof(EERIE_3DOBJ)); memcpy(&work->pos, &obj1->pos, sizeof(EERIE_3D)); memcpy(&work->angle, &obj1->angle, sizeof(EERIE_3D)); // ident will be the same as original object obj1 work->ident = obj1->ident; // We reset all data to create a fresh object memcpy(&work->cub, &obj1->cub, sizeof(CUB3D)); memcpy(&work->quat, &obj1->quat, sizeof(EERIE_QUAT)); // Linked objects are linked to this object. if (obj1->nblinked > obj2->nblinked) { work->linked = (EERIE_LINKED *)malloc(obj1->nblinked * sizeof(EERIE_LINKED)); memcpy(work->linked, obj1->linked, obj1->nblinked * sizeof(EERIE_LINKED)); work->nblinked = obj1->nblinked; } else if (obj2->nblinked > 0) { work->linked = (EERIE_LINKED *)malloc(obj2->nblinked * sizeof(EERIE_LINKED)); memcpy(work->linked, obj2->linked, obj2->nblinked * sizeof(EERIE_LINKED)); work->nblinked = obj2->nblinked; } else { work->linked = NULL; work->nblinked = 0; } // Is the origin of object in obj1 or obj2 ? Retreives it for work object if (IsInSelection(obj1, obj1->origin, tw1) != -1) { work->point0.x = obj2->point0.x; work->point0.y = obj2->point0.y; work->point0.z = obj2->point0.z; work->origin = ObjectAddVertex(work, &obj2vertexlist2[obj2->origin]); } else { work->point0.x = obj1->point0.x; work->point0.y = obj1->point0.y; work->point0.z = obj1->point0.z; work->origin = ObjectAddVertex(work, &obj1vertexlist2[obj1->origin]); } // Recreate Action Points included in work object.for Obj1 for (i = 0; i < obj1->nbaction; i++) { if ((IsInSelection(obj1, obj1->actionlist[i].idx, iw1) != -1) || (IsInSelection(obj1, obj1->actionlist[i].idx, jw1) != -1) || (!strcasecmp(obj1->actionlist[i].name, "head2chest")) || (!strcasecmp(obj1->actionlist[i].name, "chest2leggings")) ) { ObjectAddAction(work, obj1->actionlist[i].name, obj1->actionlist[i].act, obj1->actionlist[i].sfx, &obj1vertexlist2[obj1->actionlist[i].idx]); } } // Do the same for Obj2 for (i = 0; i < obj2->nbaction; i++) { if ((IsInSelection(obj2, obj2->actionlist[i].idx, tw2) != -1) || (!strcasecmp(obj1->actionlist[i].name, "head2chest")) || (!strcasecmp(obj1->actionlist[i].name, "chest2leggings")) ) { ObjectAddAction(work, obj2->actionlist[i].name, obj2->actionlist[i].act, obj2->actionlist[i].sfx, &obj2vertexlist2[obj2->actionlist[i].idx]); } } // Recreate Vertex using Obj1 Vertexes for (i = 0; i < obj1->nbvertex; i++) { if ((IsInSelection(obj1, i, iw1) != -1) || (IsInSelection(obj1, i, jw1) != -1)) { ObjectAddVertex(work, &obj1vertexlist2[i]); } } // The same for Obj2 for (i = 0; i < obj2->nbvertex; i++) { if (IsInSelection(obj2, i, tw2) != -1) { ObjectAddVertex(work, &obj2vertexlist2[i]); } } // Look in Faces for forgotten Vertexes... AND // Re-Create TextureContainers Infos // We look for texturecontainers included in the future tweaked object TextureContainer * tc = NULL; for (i = 0; i < obj1->nbfaces; i++) { if (((IsInSelection(obj1, obj1->facelist[i].vid[0], iw1) != -1) || (IsInSelection(obj1, obj1->facelist[i].vid[0], jw1) != -1)) && ((IsInSelection(obj1, obj1->facelist[i].vid[1], iw1) != -1) || (IsInSelection(obj1, obj1->facelist[i].vid[1], jw1) != -1)) && ((IsInSelection(obj1, obj1->facelist[i].vid[2], iw1) != -1) || (IsInSelection(obj1, obj1->facelist[i].vid[2], jw1) != -1)) ) { if (obj1->facelist[i].texid != -1) if (tc != obj1->texturecontainer[obj1->facelist[i].texid]) { tc = obj1->texturecontainer[obj1->facelist[i].texid]; ObjectAddMap(work, tc); } ObjectAddFace(work, &obj1->facelist[i], obj1); } } for (i = 0; i < obj2->nbfaces; i++) { if ((IsInSelection(obj2, obj2->facelist[i].vid[0], tw2) != -1) || (IsInSelection(obj2, obj2->facelist[i].vid[1], tw2) != -1) || (IsInSelection(obj2, obj2->facelist[i].vid[2], tw2) != -1)) { if (obj2->facelist[i].texid != -1) if (tc != obj2->texturecontainer[obj2->facelist[i].texid]) { tc = obj2->texturecontainer[obj2->facelist[i].texid]; ObjectAddMap(work, tc); } ObjectAddFace(work, &obj2->facelist[i], obj2); } } // Recreate Groups work->nbgroups = max(obj1->nbgroups, obj2->nbgroups); work->grouplist = (EERIE_GROUPLIST *)malloc(sizeof(EERIE_GROUPLIST) * work->nbgroups); memset(work->grouplist, 0, sizeof(EERIE_GROUPLIST)*work->nbgroups); for (long k = 0; k < obj1->nbgroups; k++) { strcpy(work->grouplist[k].name, obj1->grouplist[k].name); long v = GetEquivalentVertex(work, &obj1vertexlist2[obj1->grouplist[k].origin]); if (v >= 0) { work->grouplist[k].siz = obj1->grouplist[k].siz; if ((IsInSelection(obj1, obj1->grouplist[k].origin, iw1) != -1) || (IsInSelection(obj1, obj1->grouplist[k].origin, jw1) != -1)) work->grouplist[k].origin = v; } } for (int k = 0; k < obj2->nbgroups; k++) { if (k >= obj1->nbgroups) { strcpy(work->grouplist[k].name, obj2->grouplist[k].name); } long v = GetEquivalentVertex(work, &obj2vertexlist2[obj2->grouplist[k].origin]); if (v >= 0) { work->grouplist[k].siz = obj2->grouplist[k].siz; if (IsInSelection(obj2, obj2->grouplist[k].origin, tw2) != -1) work->grouplist[k].origin = v; } } // Recreate Selection Groups (only the 3 selections needed to reiterate MeshTweaking !) work->nbselections = 3; work->selections = (EERIE_SELECTIONS *)malloc(sizeof(EERIE_SELECTIONS) * work->nbselections); memset(work->selections, 0, sizeof(EERIE_SELECTIONS)*work->nbselections); strcpy(work->selections[0].name, "head"); strcpy(work->selections[1].name, "chest"); strcpy(work->selections[2].name, "leggings"); // Re-Creating sel_head if (tw == TWEAK_HEAD) { for (long l = 0; l < obj2->selections[sel_head2].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj2vertexlist2[obj2->selections[sel_head2].selected[l]].v.x; temp.v.y = obj2vertexlist2[obj2->selections[sel_head2].selected[l]].v.y; temp.v.z = obj2vertexlist2[obj2->selections[sel_head2].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, 0, t); } } } else for (long l = 0; l < obj1->selections[sel_head1].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj1vertexlist2[obj1->selections[sel_head1].selected[l]].v.x; temp.v.y = obj1vertexlist2[obj1->selections[sel_head1].selected[l]].v.y; temp.v.z = obj1vertexlist2[obj1->selections[sel_head1].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, 0, t); } } // Re-Create sel_torso if (tw == TWEAK_TORSO) { for (long l = 0; l < obj2->selections[sel_torso2].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj2vertexlist2[obj2->selections[sel_torso2].selected[l]].v.x; temp.v.y = obj2vertexlist2[obj2->selections[sel_torso2].selected[l]].v.y; temp.v.z = obj2vertexlist2[obj2->selections[sel_torso2].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, 1, t); } } } else for (long l = 0; l < obj1->selections[sel_torso1].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj1vertexlist2[obj1->selections[sel_torso1].selected[l]].v.x; temp.v.y = obj1vertexlist2[obj1->selections[sel_torso1].selected[l]].v.y; temp.v.z = obj1vertexlist2[obj1->selections[sel_torso1].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, 1, t); } } // Re-Create sel_legs if (tw == TWEAK_LEGS) { for (long l = 0; l < obj2->selections[sel_legs2].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj2vertexlist2[obj2->selections[sel_legs2].selected[l]].v.x; temp.v.y = obj2vertexlist2[obj2->selections[sel_legs2].selected[l]].v.y; temp.v.z = obj2vertexlist2[obj2->selections[sel_legs2].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, 2, t); } } } else for (long l = 0; l < obj1->selections[sel_legs1].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj1vertexlist2[obj1->selections[sel_legs1].selected[l]].v.x; temp.v.y = obj1vertexlist2[obj1->selections[sel_legs1].selected[l]].v.y; temp.v.z = obj1vertexlist2[obj1->selections[sel_legs1].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, 2, t); } } //Now recreates other selections... for (i = 0; i < obj1->nbselections; i++) { if (EERIE_OBJECT_GetSelection(work, obj1->selections[i].name) == -1) { long num = work->nbselections; work->nbselections++; work->selections = (EERIE_SELECTIONS *)realloc(work->selections, sizeof(EERIE_SELECTIONS) * work->nbselections); memset(&work->selections[num], 0, sizeof(EERIE_SELECTIONS)); strcpy(work->selections[num].name, obj1->selections[i].name); for (long l = 0; l < obj1->selections[i].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj1vertexlist2[obj1->selections[i].selected[l]].v.x; temp.v.y = obj1vertexlist2[obj1->selections[i].selected[l]].v.y; temp.v.z = obj1vertexlist2[obj1->selections[i].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, num, t); } } long ii = EERIE_OBJECT_GetSelection(obj2, obj1->selections[i].name); if (ii != -1) for (long l = 0; l < obj2->selections[ii].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj2vertexlist2[obj2->selections[ii].selected[l]].v.x; temp.v.y = obj2vertexlist2[obj2->selections[ii].selected[l]].v.y; temp.v.z = obj2vertexlist2[obj2->selections[ii].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, num, t); } } } } for (i = 0; i < obj2->nbselections; i++) { if (EERIE_OBJECT_GetSelection(work, obj2->selections[i].name) == -1) { long num = work->nbselections; work->nbselections++; work->selections = (EERIE_SELECTIONS *)realloc(work->selections, sizeof(EERIE_SELECTIONS) * work->nbselections); memset(&work->selections[num], 0, sizeof(EERIE_SELECTIONS)); strcpy(work->selections[num].name, obj2->selections[i].name); for (long l = 0; l < obj2->selections[i].nb_selected; l++) { EERIE_VERTEX temp; temp.v.x = obj2vertexlist2[obj2->selections[i].selected[l]].v.x; temp.v.y = obj2vertexlist2[obj2->selections[i].selected[l]].v.y; temp.v.z = obj2vertexlist2[obj2->selections[i].selected[l]].v.z; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, num, t); } } } } // Recreate Animation-groups vertex for (i = 0; i < obj1->nbgroups; i++) { for (long j = 0; j < obj1->grouplist[i].nb_index; j++) { AddVertexToGroup(work, i, &obj1vertexlist2[obj1->grouplist[i].indexes[j]]); } } for (i = 0; i < obj2->nbgroups; i++) { for (long j = 0; j < obj2->grouplist[i].nb_index; j++) { AddVertexToGroup(work, i, &obj2vertexlist2[obj2->grouplist[i].indexes[j]]); } } // Look for Vertices Without Group... for (i = 0; i < work->nbmaps; i++) { work->texturecontainer[i]->Restore(GDevice); } if (work->nbvertex) { work->vertexlist3 = (EERIE_VERTEX *)malloc(sizeof(EERIE_VERTEX) * work->nbvertex); memcpy(work->vertexlist3, work->vertexlist, sizeof(EERIE_VERTEX)*work->nbvertex); } if (obj1vertexlist2) free(obj1vertexlist2); if (obj2vertexlist2) free(obj2vertexlist2); return work; }
static EERIE_3DOBJ * CreateIntermediaryMesh(const EERIE_3DOBJ * obj1, const EERIE_3DOBJ * obj2, long tw) { ObjSelection tw1 = ObjSelection(); ObjSelection tw2 = ObjSelection(); ObjSelection iw1 = ObjSelection(); ObjSelection jw1 = ObjSelection(); ObjSelection sel_head1 = ObjSelection(); ObjSelection sel_head2 = ObjSelection(); ObjSelection sel_torso1 = ObjSelection(); ObjSelection sel_torso2 = ObjSelection(); ObjSelection sel_legs1 = ObjSelection(); ObjSelection sel_legs2 = ObjSelection(); // First we retreive selection groups indexes for(size_t i = 0; i < obj1->selections.size(); i++) { // TODO iterator ObjSelection sel = ObjSelection(i); if(obj1->selections[i].name == "head") { sel_head1 = sel; } else if(obj1->selections[i].name == "chest") { sel_torso1 = sel; } else if(obj1->selections[i].name == "leggings") { sel_legs1 = sel; } } for(size_t i = 0; i < obj2->selections.size(); i++) { // TODO iterator ObjSelection sel = ObjSelection(i); if(obj2->selections[i].name == "head") { sel_head2 = sel; } else if(obj2->selections[i].name == "chest") { sel_torso2 = sel; } else if(obj2->selections[i].name == "leggings") { sel_legs2 = sel; } } if(sel_head1 == ObjSelection()) return NULL; if(sel_head2 == ObjSelection()) return NULL; if(sel_torso1 == ObjSelection()) return NULL; if(sel_torso2 == ObjSelection()) return NULL; if(sel_legs1 == ObjSelection()) return NULL; if(sel_legs2 == ObjSelection()) return NULL; if(tw == TWEAK_HEAD) { tw1 = sel_head1; tw2 = sel_head2; iw1 = sel_torso1; jw1 = sel_legs1; } if(tw == TWEAK_TORSO) { tw1 = sel_torso1; tw2 = sel_torso2; iw1 = sel_head1; jw1 = sel_legs1; } if(tw == TWEAK_LEGS) { tw1 = sel_legs1; tw2 = sel_legs2; iw1 = sel_torso1; jw1 = sel_head1; } if(tw1 == ObjSelection() || tw2 == ObjSelection()) return NULL; // Now Retreives Tweak Action Points { ActionPoint idx_head1 = GetActionPoint(obj1, "head2chest"); if(idx_head1 == ActionPoint()) return NULL; ActionPoint idx_head2 = GetActionPoint(obj2, "head2chest"); if(idx_head2 == ActionPoint()) return NULL; ActionPoint idx_torso1 = GetActionPoint(obj1, "chest2leggings"); if(idx_torso1 == ActionPoint()) return NULL; ActionPoint idx_torso2 = GetActionPoint(obj2, "chest2leggings"); if(idx_torso2 == ActionPoint()) return NULL; } // copy vertices std::vector<EERIE_VERTEX> obj1vertexlist2 = obj1->vertexlist; std::vector<EERIE_VERTEX> obj2vertexlist2 = obj2->vertexlist; // Work will contain the Tweaked object EERIE_3DOBJ * work = new EERIE_3DOBJ; work->pos = obj1->pos; work->angle = obj1->angle; // We reset all data to create a fresh object work->cub = obj1->cub; work->quat = obj1->quat; // Linked objects are linked to this object. if(obj1->linked.size() > obj2->linked.size()) { work->linked = obj1->linked; } else { work->linked = obj2->linked; } // Is the origin of object in obj1 or obj2 ? Retreives it for work object if(IsInSelection(obj1, obj1->origin, tw1)) { work->point0 = obj2->point0; work->origin = ObjectAddVertex(work, &obj2vertexlist2[obj2->origin]); } else { work->point0 = obj1->point0; work->origin = ObjectAddVertex(work, &obj1vertexlist2[obj1->origin]); } // Recreate Action Points included in work object.for Obj1 for(size_t i = 0; i < obj1->actionlist.size(); i++) { const EERIE_ACTIONLIST & action = obj1->actionlist[i]; if( IsInSelection(obj1, action.idx.handleData(), iw1) || IsInSelection(obj1, action.idx.handleData(), jw1) || action.name == "head2chest" || action.name == "chest2leggings" ) { ObjectAddAction(work, action.name, action.act, action.sfx, &obj1vertexlist2[action.idx.handleData()]); } } // Do the same for Obj2 for(size_t i = 0; i < obj2->actionlist.size(); i++) { const EERIE_ACTIONLIST & action = obj2->actionlist[i]; if( IsInSelection(obj2, action.idx.handleData(), tw2) || action.name == "head2chest" || action.name == "chest2leggings" ) { ObjectAddAction(work, action.name, action.act, action.sfx, &obj2vertexlist2[action.idx.handleData()]); } } // Recreate Vertex using Obj1 Vertexes for(size_t i = 0; i < obj1->vertexlist.size(); i++) { if(IsInSelection(obj1, i, iw1) || IsInSelection(obj1, i, jw1)) { ObjectAddVertex(work, &obj1vertexlist2[i]); } } // The same for Obj2 for(size_t i = 0; i < obj2->vertexlist.size(); i++) { if(IsInSelection(obj2, i, tw2)) { ObjectAddVertex(work, &obj2vertexlist2[i]); } } // Look in Faces for forgotten Vertexes... AND // Re-Create TextureContainers Infos // We look for texturecontainers included in the future tweaked object TextureContainer * tc = NULL; for(size_t i = 0; i < obj1->facelist.size(); i++) { const EERIE_FACE & face = obj1->facelist[i]; if( (IsInSelection(obj1, face.vid[0], iw1) || IsInSelection(obj1, face.vid[0], jw1)) && (IsInSelection(obj1, face.vid[1], iw1) || IsInSelection(obj1, face.vid[1], jw1)) && (IsInSelection(obj1, face.vid[2], iw1) || IsInSelection(obj1, face.vid[2], jw1)) ) { if(face.texid != -1) { if(tc != obj1->texturecontainer[face.texid]) { tc = obj1->texturecontainer[face.texid]; ObjectAddMap(work, tc); } } ObjectAddFace(work, &face, obj1); } } for(size_t i = 0; i < obj2->facelist.size(); i++) { const EERIE_FACE & face = obj2->facelist[i]; if( IsInSelection(obj2, face.vid[0], tw2) || IsInSelection(obj2, face.vid[1], tw2) || IsInSelection(obj2, face.vid[2], tw2) ) { if(face.texid != -1) { if(tc != obj2->texturecontainer[face.texid]) { tc = obj2->texturecontainer[face.texid]; ObjectAddMap(work, tc); } } ObjectAddFace(work, &face, obj2); } } // Recreate Groups work->grouplist.resize(std::max(obj1->grouplist.size(), obj2->grouplist.size())); for(size_t k = 0; k < obj1->grouplist.size(); k++) { const VertexGroup & grp = obj1->grouplist[k]; work->grouplist[k].name = grp.name; long v = GetEquivalentVertex(work, &obj1vertexlist2[grp.origin]); if(v >= 0) { work->grouplist[k].siz = grp.siz; if(IsInSelection(obj1, grp.origin, iw1) || IsInSelection(obj1, grp.origin, jw1)) work->grouplist[k].origin = v; } } for(size_t k = 0; k < obj2->grouplist.size(); k++) { if(k >= obj1->grouplist.size()) { work->grouplist[k].name = obj2->grouplist[k].name; } long v = GetEquivalentVertex(work, &obj2vertexlist2[obj2->grouplist[k].origin]); if(v >= 0) { work->grouplist[k].siz = obj2->grouplist[k].siz; if(IsInSelection(obj2, obj2->grouplist[k].origin, tw2)) work->grouplist[k].origin = v; } } // Recreate Selection Groups (only the 3 selections needed to reiterate MeshTweaking !) work->selections.resize(3); work->selections[0].name = "head"; work->selections[1].name = "chest"; work->selections[2].name = "leggings"; // Re-Creating sel_head if(tw == TWEAK_HEAD) { const EERIE_SELECTIONS & sel = obj2->selections[sel_head2.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj2vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, 0, t); } } } else { const EERIE_SELECTIONS & sel = obj1->selections[sel_head1.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj1vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, 0, t); } } } // Re-Create sel_torso if(tw == TWEAK_TORSO) { const EERIE_SELECTIONS & sel = obj2->selections[sel_torso2.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj2vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, 1, t); } } } else { const EERIE_SELECTIONS & sel = obj1->selections[sel_torso1.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj1vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, 1, t); } } } // Re-Create sel_legs if(tw == TWEAK_LEGS) { const EERIE_SELECTIONS & sel = obj2->selections[sel_legs2.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj2vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, 2, t); } } } else { const EERIE_SELECTIONS & sel = obj1->selections[sel_legs1.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj1vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, 2, t); } } } //Now recreates other selections... for(size_t i = 0; i < obj1->selections.size(); i++) { if(EERIE_OBJECT_GetSelection(work, obj1->selections[i].name) == ObjSelection()) { size_t num = work->selections.size(); work->selections.resize(num + 1); work->selections[num].name = obj1->selections[i].name; for(size_t l = 0; l < obj1->selections[i].selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj1vertexlist2[obj1->selections[i].selected[l]].v; long t = GetEquivalentVertex(work, &temp); if (t != -1) { ObjectAddSelection(work, num, t); } } ObjSelection ii = EERIE_OBJECT_GetSelection(obj2, obj1->selections[i].name); if(ii != ObjSelection()) { const EERIE_SELECTIONS & sel = obj2->selections[ii.handleData()]; for(size_t l = 0; l < sel.selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj2vertexlist2[sel.selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, num, t); } } } } } for(size_t i = 0; i < obj2->selections.size(); i++) { if(EERIE_OBJECT_GetSelection(work, obj2->selections[i].name) == ObjSelection()) { size_t num = work->selections.size(); work->selections.resize(num + 1); work->selections[num].name = obj2->selections[i].name; for(size_t l = 0; l < obj2->selections[i].selected.size(); l++) { EERIE_VERTEX temp; temp.v = obj2vertexlist2[obj2->selections[i].selected[l]].v; long t = GetEquivalentVertex(work, &temp); if(t != -1) { ObjectAddSelection(work, num, t); } } } } // Recreate Animation-groups vertex for(size_t i = 0; i < obj1->grouplist.size(); i++) { for(size_t j = 0; j < obj1->grouplist[i].indexes.size(); j++) { AddVertexToGroup(work, i, &obj1vertexlist2[obj1->grouplist[i].indexes[j]]); } } for(size_t i = 0; i < obj2->grouplist.size(); i++) { for(size_t j = 0; j < obj2->grouplist[i].indexes.size(); j++) { AddVertexToGroup(work, i, &obj2vertexlist2[obj2->grouplist[i].indexes[j]]); } } work->vertexWorldPositions.resize(work->vertexlist.size()); work->vertexClipPositions.resize(work->vertexlist.size()); work->vertexColors.resize(work->vertexlist.size()); return work; }