Files
Hoops_Exchange/exchange/exchangesource/CreatePRCCubes/CreateTessellatedCubes.cpp
2025-12-15 22:06:49 +08:00

189 lines
8.4 KiB
C++

/***********************************************************************************************************************
*
* Copyright (c) 2010 - 2022 by Tech Soft 3D, Inc.
* The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
* employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the
* scope and manner of such use.
*
***********************************************************************************************************************/
/**
* Sample CreatePRCCubes
* file CreateTessellatedCubes.cpp
* This file is containing the data and function used to create PRC Tessellation.
*
* fillCubeTessBaseData is filling the structure A3DTessBaseData
* A3DTessBaseData is the structure containing the coordinates of the tessellation.
*
* fillCubeTessData is filling the structure A3DTess3DData
* A3DTess3DData is the structure describing the coordinates from A3DTessBaseData
* It contains indexes of vertex coordinates, wire frames coordinates, normals and textures coordinates.
*
*
***********************************************************************************************************************/
#include "CreateTessellatedCubes.h"
//######################################################################################################################
// Cube Tessellation structures completion
// filling A3DTessBaseData: containing the coordinates of the tessellation.
void fillCubeTessBaseData(A3DTessBaseData& sTessBaseData, A3DDouble cubeWidth, A3DDouble cubeHeight, A3DDouble cubeLength)
{
A3D_INITIALIZE_DATA(A3DTessBaseData, sTessBaseData);
sTessBaseData.m_bIsCalculated = false;
// Point coordinates
sTessBaseData.m_uiCoordSize = 24;
sTessBaseData.m_pdCoords = (A3DDouble*) malloc((size_t) sTessBaseData.m_uiCoordSize * sizeof(A3DDouble));
A3DUns32 ui;
for (ui = 0; ui < sTessBaseData.m_uiCoordSize / 3; ++ui)
{
sTessBaseData.m_pdCoords[3 * ui] = stCubePoints[3 * ui] * cubeWidth;
sTessBaseData.m_pdCoords[3 * ui + 1] = stCubePoints[3 * ui + 1] * cubeHeight;
sTessBaseData.m_pdCoords[3 * ui + 2] = stCubePoints[3 * ui + 2] * cubeLength;
}
}
void freeTessBaseData(A3DTessBaseData& sTessBaseData)
{
free(sTessBaseData.m_pdCoords);
}
//######################################################################################################################
// Cube Tessellation structures completion
// filling A3DTess3DData:describing the coordinates from A3DTessBaseData
// indexes of vertex coordinates, wire frames coordinates, normals and textures coordinates.
void fillCubeTessData(A3DTess3DData& sTess3DData, A3DUns32* puiStyleIndex)
{
A3D_INITIALIZE_DATA(A3DTess3DData, sTess3DData);
A3DUns32 ui;
// Normal coordinates
sTess3DData.m_uiNormalSize = 18;
sTess3DData.m_pdNormals = (A3DDouble*) malloc((size_t) sTess3DData.m_uiNormalSize * sizeof(A3DDouble));
for (ui = 0; ui < sTess3DData.m_uiNormalSize; ++ui)
sTess3DData.m_pdNormals[ui] = stCubeNormals[ui];
if (puiStyleIndex != NULL)
{
// UV coordinates
sTess3DData.m_uiTextureCoordSize = 8;
sTess3DData.m_pdTextureCoords =
(A3DDouble*) malloc(sTess3DData.m_uiTextureCoordSize * A3DUns32(sizeof(A3DDouble)));
for (ui = 0; ui < sTess3DData.m_uiTextureCoordSize; ++ui)
{
sTess3DData.m_pdTextureCoords[ui] = stCubeUV[ui];
}
}
// Faces
sTess3DData.m_bHasFaces = true; // Geometrical face notion?
sTess3DData.m_uiFaceTessSize = 6;
sTess3DData.m_psFaceTessData =
(A3DTessFaceData*) malloc((size_t) sTess3DData.m_uiFaceTessSize * sizeof(A3DTessFaceData));
for (ui = 0; ui < sTess3DData.m_uiFaceTessSize; ++ui)
A3D_INITIALIZE_DATA(A3DTessFaceData, (sTess3DData.m_psFaceTessData[ui]));
// All the point, normal and texture indexes are stored in the A3DTess3D.
// The faces describes how to interpret these indices.
if (puiStyleIndex != NULL)
{
sTess3DData.m_uiTriangulatedIndexSize = 18 * 6;
sTess3DData.m_puiTriangulatedIndexes = (A3DUns32*) malloc(sTess3DData.m_uiTriangulatedIndexSize * A3DUns32(sizeof(A3DUns32)));
for (ui = 0; ui < sTess3DData.m_uiTriangulatedIndexSize; ++ui)
{
sTess3DData.m_puiTriangulatedIndexes[ui] = stTexturedCubeFacesNormalPTrianglesUV[ui];
}
}
else
{
sTess3DData.m_uiTriangulatedIndexSize = 12 * 6;
sTess3DData.m_puiTriangulatedIndexes = (A3DUns32*) malloc((size_t) sTess3DData.m_uiTriangulatedIndexSize * sizeof(A3DUns32));
for (ui = 0; ui < sTess3DData.m_uiTriangulatedIndexSize; ++ui)
{
sTess3DData.m_puiTriangulatedIndexes[ui] = stCubeFacesNormalPTrianglesUV[ui];
}
}
// Like above the edge point indices of the faces are stored in the A3DTess3D
sTess3DData.m_uiWireIndexSize = 8 * 6;
sTess3DData.m_puiWireIndexes = (A3DUns32*) malloc((size_t) sTess3DData.m_uiWireIndexSize * sizeof(A3DUns32));
for (ui = 0; ui < sTess3DData.m_uiWireIndexSize; ++ui)
sTess3DData.m_puiWireIndexes[ui] = stCubeFacesWireframe[ui];
A3DUns32 uj;
for (ui = 0; ui < sTess3DData.m_uiFaceTessSize; ++ui)
{
A3DTessFaceData& sFace = sTess3DData.m_psFaceTessData[ui];
// Type(s) of the entities of the face. This face contains only triangles with texture (with uv for each vertex).
if (puiStyleIndex != NULL)
{
sFace.m_usUsedEntitiesFlags = kA3DTessFaceDataTriangleTextured;
// indicates the texture of this face
if (*puiStyleIndex != A3D_DEFAULT_STYLE_INDEX)
{
sFace.m_uiStyleIndexesSize = 1;
sFace.m_puiStyleIndexes = (A3DUns32*) malloc(sFace.m_uiStyleIndexesSize * A3DUns32(sizeof(A3DUns32)));
sFace.m_puiStyleIndexes[0] = *puiStyleIndex;
}
// number of uv indices for each vertex of the face
// (a multi-textured face or a multi-referenced part should involve more than one uv index)
sFace.m_uiTextureCoordIndexesSize = 1;
// the description of the triangles of the face begins at this position
// in the m_puiTriangulatedIndexes array filled above.
sFace.m_uiStartTriangulated = ui * 18;
}
else
{
sFace.m_usUsedEntitiesFlags = kA3DTessFaceDataTriangle;
sFace.m_uiTextureCoordIndexesSize = 0;
sFace.m_uiStartTriangulated = ui * 12;
}
sFace.m_uiSizesTriangulatedSize = 1; // size of the next array
sFace.m_puiSizesTriangulated = (A3DUns32*) malloc(sFace.m_uiSizesTriangulatedSize * A3DUns32(sizeof(A3DUns32)));
sFace.m_puiSizesTriangulated[0] = 2; // number of triangles for this face
// wireframe of the face
sFace.m_uiSizesWiresSize = 4; // size of the next array corresponds to the number of edges
sFace.m_puiSizesWires = (A3DUns32*) malloc((size_t) sFace.m_uiSizesWiresSize * sizeof(A3DUns32));
for (uj = 0; uj < sFace.m_uiSizesWiresSize; ++uj)
sFace.m_puiSizesWires[uj] = 2; // two points for each edge
// to indicate that the loop is closed,
// the number of vertices of the last edge has the flag kA3DTessFaceDataWireIsClosing
sFace.m_puiSizesWires[sFace.m_uiSizesWiresSize - 1] |= kA3DTessFaceDataWireIsClosing;
// the description of the wireframe of the face begins at this position
// in the m_puiWireIndexes array filled above.
sFace.m_uiStartWire = ui * 8;
}
}
void freeTess3DData(A3DTess3DData& sTess3DData)
{
free(sTess3DData.m_pdNormals);
free(sTess3DData.m_pdTextureCoords);
free(sTess3DData.m_puiTriangulatedIndexes);
free(sTess3DData.m_puiWireIndexes);
A3DUns32 ui = sTess3DData.m_uiFaceTessSize;
for (ui = 0; ui < sTess3DData.m_uiFaceTessSize; ++ui)
{
if (sTess3DData.m_psFaceTessData[ui].m_puiStyleIndexes != NULL) // Texture is optionnal
free(sTess3DData.m_psFaceTessData[ui].m_puiStyleIndexes);
free(sTess3DData.m_psFaceTessData[ui].m_puiSizesTriangulated);
free(sTess3DData.m_psFaceTessData[ui].m_puiSizesWires);
}
free(sTess3DData.m_psFaceTessData);
}