Прочитал статью. Спасибо автору. Не могу никак понять: как сделать так, чтобы мой плагин отображался как в меню File -> Export... , так и в File -> Export Selected... ?
BOOL SceneExport::SupportsOptions(int ext, DWORD options) { return ( options == SCENE_EXPORT_SELECTED) ? TRUE : FALSE; }
это решение твоей проблемы, если ты ещё не нашёл это решение сам :)
спасибо, твоя подсказка мне пригодилась
Не поможете ещё в одном вопросе: как узнать окружение 3D MAX или путь к стартовой папке (т.е. папке, где находится 3dsmax.exe) ?
Interface *i;
i->GetDir(APP_MAXROOT_DIR);
Хелп читать не умеем ?
зы: только сейчас подумал: надеюсь ты понимаешь что указатель на Interface передается тебе параметром doexport ?
arch
Спасибо.
У меня вот в чём проблема. Я хочу запустить консольное приложение таким образом
bSuccess = CreateProcess ( "arj.exe", NULL,
NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP,
NULL, NULL, &si, ? );
надеюсь, понятно, что arj.exe - это и есть то приложение. Я что-то сильно туплю: если я располагаю это приложение в папке с файлом, в который сохраняется экспорт сцены, то всё нормально. А как мне запустить это приложение из папки с плагином сразу после экспорта сцены ? Надеюсь понятно объяснил. Спасибо
P.S. разобрался. Времени не было до Макса добраться. Сорри, что отнял время
блин, чел, такое нельзя выкладывать
это кривой код
давай проектирование я трогать не буду, всего один моментик из-за которого можно просидеть в дебаге пару дней
ты подумал, что нехорошо конвертить streampos в char[4] ибо это зависит от реализации STL? и с STLport твой плагин вешает машину в бесконечный цикл ибо первые 4 байта у этой структуры часто нули?
в самом плохом случае - f.write( (char*)&TmpPos, sizeof(TmpPos) )
и то, так делать нехорошо
хорошо писать однозначные структуры файлов без ссылок внутри ( зачем они в твоем случае - непонятно )
сама статья мало что объясняет
все, конечно, имхо и нп
ici
вот поправленный код, если кому нужно
int numF, numV, numTV, CurrHeader, zero = 0, debug = 0xAA, Del; streampos NextNode, VertexPointer, FacePointer, TmpPos; // Get TriObject from node TriObject *TObj; TObj = GetTriObjFromNode(node, Del); if (!TObj) return; numF = TObj->mesh.numFaces; numV = TObj->mesh.numVerts; numTV = TObj->mesh.numTVerts; CurrHeader = ID_NODE_HEADER; // Write node header and total count of vertexes and faces fFile.write((char *)&CurrHeader, 2); fFile.write((char *)&numV, sizeof(int)); fFile.write((char *)&numTV, sizeof(int)); fFile.write((char *)&numF, sizeof(int)); // We don't know how long node record is. // Save stream pos, and temporary fill 4 bytes by zeroes. NextNode = fFile.tellp(); fFile.write((char *)&zero, sizeof(NextNode)); // Write Material header CurrHeader = ID_MTL_HEADER; fFile.write((char *)&CurrHeader, 2); // Remember current position as place for address for mesh section VertexPointer = fFile.tellp(); fFile.write((char *)&zero, sizeof(VertexPointer)); // Export material associated with node ExportMaterial(node); // Write current pos as begin of Vertex section of our file TmpPos = fFile.tellp(); fFile.seekp(VertexPointer); fFile.write((char *)&TmpPos, sizeof(VertexPointer)); fFile.seekp(TmpPos); // Begin write geometry data // First of all dump 2 byte mesh header CurrHeader = ID_VERTEX_HEADER; fFile.write((char *)&CurrHeader, 2); // Then save place for Face data pointer FacePointer = fFile.tellp(); fFile.write((char *)&zero, sizeof(FacePointer)); // Then pass through all node's verts and put into file all data: // verex coordinates, vertex mapping UV coordinates and normal vector // but first get TM for this node ExportVerts(TObj, node->GetObjTMAfterWSM(ip->GetTime())); // Now save this pos as begin face block TmpPos = fFile.tellp(); fFile.seekp(FacePointer); fFile.write((char *)&TmpPos, sizeof(TmpPos)); fFile.seekp(TmpPos); // Now export all Face data // First write Face data header CurrHeader = ID_FACE_HEADER; fFile.write((char *)&CurrHeader, 2); // Write all facees data ExportFaces(TObj); // Now put this pos as begin of new node TmpPos = fFile.tellp(); fFile.seekp(NextNode); fFile.write((char *)&TmpPos, sizeof(TmpPos)); fFile.seekp(TmpPos); // Go to the next node if anyone exists
Эта функция сохраняет индексы текстурных координат и вершинных?
void SceneSaver::ExportFaces(TriObject *TObj)
{
int i;
// Пробегаемся по всем полигонам и записываем данные в файл
for (i = 0; i < TObj->mesh.numFaces; i++)
{
fFile.write((char *)&TObj->mesh.faces.v[0], sizeof(DWORD) * 3);
if (TObj->mesh.numTVerts != 0)
fFile.write((char *)&TObj->mesh.tvFace.t[0], sizeof(DWORD) * 3);
}
}
нет
у точки может быть несколько текстурных координат
для корректной работы нужно исходить из faces/tvfaces (их количество и индексы всегда совпадают)
зы я не говорю про мультитекстурирование - это по сути отдельная задача
Мне кажется, что нельзя забывать о том, что нормали также требуется умножать на матрицу трансформации объекта:
Matrix3 tm = node->GetObjTMAfterWSM(ip->GetTime());
Matrix3 rot = tm;
rot.NoTrans();
rot.NoScale();
vertex = tm * TObj->mesh.verts;
normal = rot * TObj->mesh.getNormal(i);
иначе ловим проблемы с нормалями...
ж))
Нормали в нормальных объектах приходится тож дергать из файла, а это плохо, аффтар L1f, работай над дамашним заданиим, пиши по делу...
(как и на что нужно умножать здесь столько написано....даже уже не улыбает)
(лично меня давно уж зае-ли модели с рассчитываемыми нормалями - оторвать руки всем кроме писателей 2d-слайдеров, спрайты жгут ;))))
ЗЫ: никаких проблем с рассчетом нормалей нет - шейдеры рулят (пока с динамикой не столкнешся)
Зызы:матрицу перемножать мыы не будем до тех пор, пока не начнем работать с костями
Зызызы: я считаю - это правильно, статика куда как легче считается
Тема в архиве.