Encapsulate mjCMesh data, apply Google C++ naming convention to class members (See https://google.github.io/styleguide/cppguide.html#Variable_Names), and fix a couple of typos.
PiperOrigin-RevId: 553129088 Change-Id: Ic515154220af472f4fc90ca9ade92d86b205cc94
This commit is contained in:
+522
-397
File diff suppressed because it is too large
Load Diff
+35
-35
@@ -828,7 +828,7 @@ void mjCModel::SetDefaultNames(void) {
|
|||||||
// meshes
|
// meshes
|
||||||
for (int i=0; i<meshes.size(); i++) {
|
for (int i=0; i<meshes.size(); i++) {
|
||||||
if (meshes[i]->name.empty()) {
|
if (meshes[i]->name.empty()) {
|
||||||
stripped = mjuu_strippath(meshes[i]->file);
|
stripped = mjuu_strippath(meshes[i]->file());
|
||||||
meshes[i]->name = mjuu_stripext(stripped);
|
meshes[i]->name = mjuu_stripext(stripped);
|
||||||
|
|
||||||
// name cannot be empty
|
// name cannot be empty
|
||||||
@@ -934,12 +934,12 @@ void mjCModel::SetSizes(void) {
|
|||||||
|
|
||||||
// nmeshvert, nmeshface, nmeshtexcoord, nmeshgraph
|
// nmeshvert, nmeshface, nmeshtexcoord, nmeshgraph
|
||||||
for (int i=0; i<nmesh; i++) {
|
for (int i=0; i<nmesh; i++) {
|
||||||
nmeshvert += meshes[i]->nvert;
|
nmeshvert += meshes[i]->nvert();
|
||||||
nmeshnormal += meshes[i]->nnormal;
|
nmeshnormal += meshes[i]->nnormal();
|
||||||
nmeshface += meshes[i]->nface;
|
nmeshface += meshes[i]->nface();
|
||||||
nmeshtexcoord += (meshes[i]->texcoord ? meshes[i]->ntexcoord : 0);
|
nmeshtexcoord += (meshes[i]->HasTexcoord() ? meshes[i]->ntexcoord() : 0);
|
||||||
nmeshgraph += meshes[i]->szgraph;
|
nmeshgraph += meshes[i]->szgraph();
|
||||||
nbvh += meshes[i]->tree.nbvh;
|
nbvh += meshes[i]->tree().nbvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nskinvert, nskintexvert, nskinface, nskinbone, nskinbonevert
|
// nskinvert, nskintexvert, nskinface, nskinbone, nskinbonevert
|
||||||
@@ -1712,43 +1712,43 @@ void mjCModel::CopyObjects(mjModel* m) {
|
|||||||
|
|
||||||
// set fields
|
// set fields
|
||||||
m->mesh_vertadr[i] = vert_adr;
|
m->mesh_vertadr[i] = vert_adr;
|
||||||
m->mesh_vertnum[i] = pme->nvert;
|
m->mesh_vertnum[i] = pme->nvert();
|
||||||
m->mesh_normaladr[i] = normal_adr;
|
m->mesh_normaladr[i] = normal_adr;
|
||||||
m->mesh_normalnum[i] = pme->nnormal;
|
m->mesh_normalnum[i] = pme->nnormal();
|
||||||
m->mesh_texcoordadr[i] = (pme->texcoord ? texcoord_adr : -1);
|
m->mesh_texcoordadr[i] = (pme->HasTexcoord() ? texcoord_adr : -1);
|
||||||
m->mesh_texcoordnum[i] = pme->ntexcoord;
|
m->mesh_texcoordnum[i] = pme->ntexcoord();
|
||||||
m->mesh_faceadr[i] = face_adr;
|
m->mesh_faceadr[i] = face_adr;
|
||||||
m->mesh_facenum[i] = pme->nface;
|
m->mesh_facenum[i] = pme->nface();
|
||||||
m->mesh_graphadr[i] = (pme->szgraph ? graph_adr : -1);
|
m->mesh_graphadr[i] = (pme->szgraph() ? graph_adr : -1);
|
||||||
m->mesh_bvhadr[i] = bvh_adr;
|
m->mesh_bvhadr[i] = bvh_adr;
|
||||||
m->mesh_bvhnum[i] = pme->tree.nbvh;
|
m->mesh_bvhnum[i] = pme->tree().nbvh;
|
||||||
|
|
||||||
// copy vertices, normals, faces, texcoords, aux data
|
// copy vertices, normals, faces, texcoords, aux data
|
||||||
memcpy(m->mesh_vert + 3*vert_adr, pme->vert, 3*pme->nvert*sizeof(float));
|
pme->CopyVert(m->mesh_vert + 3*vert_adr);
|
||||||
memcpy(m->mesh_normal + 3*normal_adr, pme->normal, 3*pme->nnormal*sizeof(float));
|
pme->CopyNormal(m->mesh_normal + 3*normal_adr);
|
||||||
memcpy(m->mesh_face + 3*face_adr, pme->face, 3*pme->nface*sizeof(float));
|
pme->CopyFace(m->mesh_face + 3*face_adr);
|
||||||
memcpy(m->mesh_facenormal + 3*face_adr, pme->facenormal, 3*pme->nface*sizeof(int));
|
pme->CopyFaceNormal(m->mesh_facenormal + 3*face_adr);
|
||||||
if (pme->texcoord) {
|
if (pme->HasTexcoord()) {
|
||||||
memcpy(m->mesh_texcoord + 2*texcoord_adr, pme->texcoord, 2*pme->ntexcoord*sizeof(float));
|
pme->CopyTexcoord(m->mesh_texcoord + 2*texcoord_adr);
|
||||||
memcpy(m->mesh_facetexcoord + 3*face_adr, pme->facetexcoord, 3*pme->nface*sizeof(int));
|
pme->CopyFaceTexcoord(m->mesh_facetexcoord + 3*face_adr);
|
||||||
} else {
|
} else {
|
||||||
memset(m->mesh_facetexcoord + 3*face_adr, 0, 3*pme->nface*sizeof(int));
|
memset(m->mesh_facetexcoord + 3*face_adr, 0, 3*pme->nface()*sizeof(int));
|
||||||
}
|
}
|
||||||
if (pme->szgraph) {
|
if (pme->szgraph()) {
|
||||||
memcpy(m->mesh_graph + graph_adr, pme->graph, pme->szgraph*sizeof(int));
|
pme->CopyGraph(m->mesh_graph + graph_adr);
|
||||||
}
|
}
|
||||||
memcpy(m->bvh_aabb + 6*bvh_adr, pme->tree.bvh.data(), 6*pme->tree.nbvh*sizeof(mjtNum));
|
memcpy(m->bvh_aabb + 6*bvh_adr, pme->tree().bvh.data(), 6*pme->tree().nbvh*sizeof(mjtNum));
|
||||||
memcpy(m->bvh_child + 2*bvh_adr, pme->tree.child.data(), 2*pme->tree.nbvh*sizeof(int));
|
memcpy(m->bvh_child + 2*bvh_adr, pme->tree().child.data(), 2*pme->tree().nbvh*sizeof(int));
|
||||||
memcpy(m->bvh_depth + bvh_adr, pme->tree.level.data(), pme->tree.nbvh*sizeof(int));
|
memcpy(m->bvh_depth + bvh_adr, pme->tree().level.data(), pme->tree().nbvh*sizeof(int));
|
||||||
memcpy(m->bvh_geomid + bvh_adr, pme->tree.nodeid.data(), pme->tree.nbvh*sizeof(int));
|
memcpy(m->bvh_geomid + bvh_adr, pme->tree().nodeid.data(), pme->tree().nbvh*sizeof(int));
|
||||||
|
|
||||||
// advance counters
|
// advance counters
|
||||||
vert_adr += pme->nvert;
|
vert_adr += pme->nvert();
|
||||||
normal_adr += pme->nnormal;
|
normal_adr += pme->nnormal();
|
||||||
texcoord_adr += (pme->texcoord ? pme->ntexcoord : 0);
|
texcoord_adr += (pme->HasTexcoord() ? pme->ntexcoord() : 0);
|
||||||
face_adr += pme->nface;
|
face_adr += pme->nface();
|
||||||
graph_adr += pme->szgraph;
|
graph_adr += pme->szgraph();
|
||||||
bvh_adr += pme->tree.nbvh;
|
bvh_adr += pme->tree().nbvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skins
|
// skins
|
||||||
@@ -2535,7 +2535,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, int vfs_provider) {
|
|||||||
for (int i=0; i<geoms.size(); i++) {
|
for (int i=0; i<geoms.size(); i++) {
|
||||||
if (geoms[i]->meshid>=0 && geoms[i]->type==mjGEOM_MESH &&
|
if (geoms[i]->meshid>=0 && geoms[i]->type==mjGEOM_MESH &&
|
||||||
(geoms[i]->contype || geoms[i]->conaffinity)) {
|
(geoms[i]->contype || geoms[i]->conaffinity)) {
|
||||||
meshes[geoms[i]->meshid]->needhull = true;
|
meshes[geoms[i]->meshid]->set_needhull(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1302,7 +1302,8 @@ double mjCGeom::GetVolume(void) {
|
|||||||
if (model->exactmeshinertia || typeinertia==mjSHELL_MESH) {
|
if (model->exactmeshinertia || typeinertia==mjSHELL_MESH) {
|
||||||
return pmesh->GetVolumeRef(typeinertia);
|
return pmesh->GetVolumeRef(typeinertia);
|
||||||
} else {
|
} else {
|
||||||
return pmesh->boxsz_volume[0]*pmesh->boxsz_volume[1]*pmesh->boxsz_volume[2]*8;
|
const double* boxsz_volume = pmesh->boxsz_volume();
|
||||||
|
return boxsz_volume[0]*boxsz_volume[1]*boxsz_volume[2]*8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1419,7 +1420,7 @@ void mjCGeom::SetInertia(void) {
|
|||||||
|
|
||||||
// compute radius of bounding sphere
|
// compute radius of bounding sphere
|
||||||
double mjCGeom::GetRBound(void) {
|
double mjCGeom::GetRBound(void) {
|
||||||
double* aabb;
|
const double* aabb;
|
||||||
double haabb[3] = {0};
|
double haabb[3] = {0};
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -1439,7 +1440,7 @@ double mjCGeom::GetRBound(void) {
|
|||||||
return sqrt(size[0]*size[0]+size[1]*size[1]+size[2]*size[2]);
|
return sqrt(size[0]*size[0]+size[1]*size[1]+size[2]*size[2]);
|
||||||
|
|
||||||
case mjGEOM_MESH:
|
case mjGEOM_MESH:
|
||||||
aabb = model->meshes[meshid]->aabb;
|
aabb = model->meshes[meshid]->aabb();
|
||||||
haabb[0] = mjMAX(fabs(aabb[0]), fabs(aabb[3]));
|
haabb[0] = mjMAX(fabs(aabb[0]), fabs(aabb[3]));
|
||||||
haabb[1] = mjMAX(fabs(aabb[1]), fabs(aabb[4]));
|
haabb[1] = mjMAX(fabs(aabb[1]), fabs(aabb[4]));
|
||||||
haabb[2] = mjMAX(fabs(aabb[2]), fabs(aabb[5]));
|
haabb[2] = mjMAX(fabs(aabb[2]), fabs(aabb[5]));
|
||||||
@@ -1585,7 +1586,7 @@ void mjCGeom::ComputeAABB() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case mjGEOM_MESH:
|
case mjGEOM_MESH:
|
||||||
mjuu_copyvec(aabb, model->meshes[meshid]->aabb, 6);
|
mjuu_copyvec(aabb, model->meshes[meshid]->aabb(), 6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mjGEOM_PLANE:
|
case mjGEOM_PLANE:
|
||||||
@@ -1752,7 +1753,7 @@ void mjCGeom::Compile(void) {
|
|||||||
size[1] = model->hfields[hfieldid]->size[1];
|
size[1] = model->hfields[hfieldid]->size[1];
|
||||||
size[2] = 0.5*(model->hfields[hfieldid]->size[2]+model->hfields[hfieldid]->size[3]);
|
size[2] = 0.5*(model->hfields[hfieldid]->size[2]+model->hfields[hfieldid]->size[3]);
|
||||||
} else if (type==mjGEOM_MESH) {
|
} else if (type==mjGEOM_MESH) {
|
||||||
double* aabb = model->meshes[meshid]->aabb;
|
const double* aabb = model->meshes[meshid]->aabb();
|
||||||
size[0] = mjMAX(fabs(aabb[0]), fabs(aabb[3]));
|
size[0] = mjMAX(fabs(aabb[0]), fabs(aabb[3]));
|
||||||
size[1] = mjMAX(fabs(aabb[1]), fabs(aabb[4]));
|
size[1] = mjMAX(fabs(aabb[1]), fabs(aabb[4]));
|
||||||
size[2] = mjMAX(fabs(aabb[2]), fabs(aabb[5]));
|
size[2] = mjMAX(fabs(aabb[2]), fabs(aabb[5]));
|
||||||
|
|||||||
+109
-56
@@ -15,7 +15,9 @@
|
|||||||
#ifndef MUJOCO_SRC_USER_USER_OBJECTS_H_
|
#ifndef MUJOCO_SRC_USER_USER_OBJECTS_H_
|
||||||
#define MUJOCO_SRC_USER_USER_OBJECTS_H_
|
#define MUJOCO_SRC_USER_USER_OBJECTS_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -518,42 +520,93 @@ class mjCLight : public mjCBase {
|
|||||||
// Describes a mesh
|
// Describes a mesh
|
||||||
|
|
||||||
class mjCMesh: public mjCBase {
|
class mjCMesh: public mjCBase {
|
||||||
friend class mjCDef;
|
|
||||||
friend class mjCGeom;
|
|
||||||
friend class mjCBody;
|
|
||||||
friend class mjCSkin;
|
|
||||||
friend class mjCModel;
|
|
||||||
friend class mjXWriter;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
mjCMesh(mjCModel* = 0, mjCDef* = 0);
|
||||||
|
~mjCMesh();
|
||||||
|
|
||||||
|
// public getters
|
||||||
|
const std::string& content_type() const { return content_type_; }
|
||||||
|
const std::string& file() const { return file_; }
|
||||||
|
const double* refpos() const { return refpos_; }
|
||||||
|
const double* refquat() const { return refquat_; }
|
||||||
|
const double* scale() const { return scale_; }
|
||||||
|
bool smoothnormal() const { return smoothnormal_; }
|
||||||
|
|
||||||
|
// public getters for user data
|
||||||
|
const std::vector<float>& uservert() const { return uservert_; }
|
||||||
|
const std::vector<float>& usernormal() const { return usernormal_; }
|
||||||
|
const std::vector<float>& usertexcoord() const { return usertexcoord_; }
|
||||||
|
const std::vector<int>& userface() const { return userface_; }
|
||||||
|
|
||||||
|
// mesh properites computed by Compile
|
||||||
|
const double* boxsz_volume() const { return boxsz_volume_; }
|
||||||
|
const double* aabb() const { return aabb_; }
|
||||||
|
|
||||||
|
// number of vertices, normals, texture coordinates, and faces
|
||||||
|
int nvert() const { return nvert_; }
|
||||||
|
int nnormal() const { return nnormal_; }
|
||||||
|
int ntexcoord() const { return ntexcoord_; }
|
||||||
|
int nface() const { return nface_; }
|
||||||
|
|
||||||
|
// return size of graph data in ints
|
||||||
|
int szgraph() const { return szgraph_; }
|
||||||
|
|
||||||
|
// bounding volume hierarchy tree
|
||||||
|
const mjCBoundingVolumeHierarchy& tree() { return tree_; }
|
||||||
|
|
||||||
|
// general setters
|
||||||
|
void set_file(const std::string& file);
|
||||||
|
void set_scale(std::array<double, 3> scale);
|
||||||
|
void set_smoothnormal(bool smoothnormal);
|
||||||
|
void set_needhull(bool needhull);
|
||||||
|
|
||||||
|
// setters used in reading XML attributes (no-op if empty optional)
|
||||||
|
void set_content_type(std::optional<std::string>&& content_type);
|
||||||
|
void set_file(std::optional<std::string>&& file);
|
||||||
|
void set_refpos(std::optional<std::array<double, 3>> refpos);
|
||||||
|
void set_refquat(std::optional<std::array<double, 4>> refquat);
|
||||||
|
void set_scale(std::optional<std::array<double, 3>> scale);
|
||||||
|
|
||||||
|
void set_uservert(std::optional<std::vector<float>>&& uservert);
|
||||||
|
void set_usernormal(std::optional<std::vector<float>>&& usernormal);
|
||||||
|
void set_usertexcoord(std::optional<std::vector<float>>&& usertexcoord);
|
||||||
|
void set_userface(std::optional<std::vector<int>>&& userface);
|
||||||
|
|
||||||
|
void Compile(int vfs_provider); // compiler
|
||||||
double* GetPosPtr(mjtMeshType type); // get position
|
double* GetPosPtr(mjtMeshType type); // get position
|
||||||
double* GetQuatPtr(mjtMeshType type); // get orientation
|
double* GetQuatPtr(mjtMeshType type); // get orientation
|
||||||
double* GetInertiaBoxPtr(mjtMeshType type); // get inertia box
|
double* GetInertiaBoxPtr(mjtMeshType type); // get inertia box
|
||||||
double& GetVolumeRef(mjtMeshType type); // get volume
|
double& GetVolumeRef(mjtMeshType type); // get volume
|
||||||
void FitGeom(mjCGeom* geom, double* meshpos); // approximate mesh with simple geom
|
void FitGeom(mjCGeom* geom, double* meshpos); // approximate mesh with simple geom
|
||||||
|
bool HasTexcoord() const; // texcoord not null
|
||||||
|
|
||||||
|
void CopyVert(float* arr) const; // copy vert data into array
|
||||||
|
void CopyNormal(float* arr) const; // copy normal data into array
|
||||||
|
void CopyFace(int* arr) const; // copy face data into array
|
||||||
|
void CopyFaceNormal(int* arr) const; // copy face normal data into array
|
||||||
|
void CopyFaceTexcoord(int* arr) const; // copy face texcoord data into array
|
||||||
|
void CopyTexcoord(float* arr) const; // copy texcoord data into array
|
||||||
|
void CopyGraph(int* arr) const; // copy graph data into array
|
||||||
|
|
||||||
// returns a bounding volume given a face
|
// returns a bounding volume given a face
|
||||||
mjCBoundingVolume GetBoundingVolume(int faceid);
|
mjCBoundingVolume GetBoundingVolume(int faceid);
|
||||||
|
|
||||||
std::string content_type; // content type of file
|
|
||||||
std::string file; // mesh file
|
|
||||||
double refpos[3]; // reference position (translate)
|
|
||||||
double refquat[4]; // reference orientation (rotate)
|
|
||||||
double scale[3]; // rescale mesh
|
|
||||||
bool smoothnormal; // do not exclude large-angle faces from normals
|
|
||||||
|
|
||||||
std::vector<float> uservert; // user vertex data
|
|
||||||
std::vector<float> usernormal; // user normal data
|
|
||||||
std::vector<float> usertexcoord; // user texcoord data
|
|
||||||
std::vector<int> userface; // user vertex indices
|
|
||||||
std::vector<int> userfacenormal; // user normal indices
|
|
||||||
std::vector<int> userfacetexcoord; // user texcoord indices
|
|
||||||
std::vector< std::pair<int, int> > useredge; // user half-edge data
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mjCMesh(mjCModel* = 0, mjCDef* = 0); // constructor
|
std::string content_type_; // content type of file
|
||||||
~mjCMesh(); // destructor
|
std::string file_; // mesh file
|
||||||
void Compile(int vfs_provider); // compiler
|
double refpos_[3]; // reference position (translate)
|
||||||
|
double refquat_[4]; // reference orientation (rotate)
|
||||||
|
double scale_[3]; // rescale mesh
|
||||||
|
bool smoothnormal_; // do not exclude large-angle faces from normals
|
||||||
|
|
||||||
|
std::vector<float> uservert_; // user vertex data
|
||||||
|
std::vector<float> usernormal_; // user normal data
|
||||||
|
std::vector<float> usertexcoord_; // user texcoord data
|
||||||
|
std::vector<int> userface_; // user vertex indices
|
||||||
|
std::vector<int> userfacenormal_; // user normal indices
|
||||||
|
std::vector<int> userfacetexcoord_; // user texcoord indices
|
||||||
|
std::vector< std::pair<int, int> > useredge_; // user half-edge data
|
||||||
|
|
||||||
void LoadOBJ(mjResource* resource); // load mesh in wavefront OBJ format
|
void LoadOBJ(mjResource* resource); // load mesh in wavefront OBJ format
|
||||||
void LoadSTL(mjResource* resource); // load mesh in STL BIN format
|
void LoadSTL(mjResource* resource); // load mesh in STL BIN format
|
||||||
void LoadMSH(mjResource* resource); // load mesh in MSH BIN format
|
void LoadMSH(mjResource* resource); // load mesh in MSH BIN format
|
||||||
@@ -572,43 +625,43 @@ class mjCMesh: public mjCBase {
|
|||||||
bool exactmeshinertia);
|
bool exactmeshinertia);
|
||||||
|
|
||||||
// mesh properties that indicate a well-formed mesh
|
// mesh properties that indicate a well-formed mesh
|
||||||
std::pair<int, int> invalidorientation; // indices of invalid edge; -1 if none
|
std::pair<int, int> invalidorientation_; // indices of invalid edge; -1 if none
|
||||||
bool validarea; // false if the area is too small
|
bool validarea_; // false if the area is too small
|
||||||
int validvolume; // 0: volume is too small, -1: volume is negative
|
int validvolume_; // 0: volume is too small, -1: volume is negative
|
||||||
bool valideigenvalue; // false if inertia eigenvalue is too small
|
bool valideigenvalue_; // false if inertia eigenvalue is too small
|
||||||
bool validinequality; // false if inertia inequality is not satisfied
|
bool validinequality_; // false if inertia inequality is not satisfied
|
||||||
bool processed; // false if the mesh has not been processed yet
|
bool processed_; // false if the mesh has not been processed yet
|
||||||
|
|
||||||
// mesh properties computed by Compile
|
// mesh properties computed by Compile
|
||||||
double pos_volume[3]; // CoM position
|
double pos_volume_[3]; // CoM position
|
||||||
double pos_surface[3]; // CoM position
|
double pos_surface_[3]; // CoM position
|
||||||
double quat_volume[4]; // inertia orientation
|
double quat_volume_[4]; // inertia orientation
|
||||||
double quat_surface[4]; // inertia orientation
|
double quat_surface_[4]; // inertia orientation
|
||||||
double boxsz_volume[3]; // half-sizes of equivalent inertia box (volume)
|
double boxsz_volume_[3]; // half-sizes of equivalent inertia box (volume)
|
||||||
double boxsz_surface[3]; // half-sizes of equivalent inertia box (surface)
|
double boxsz_surface_[3]; // half-sizes of equivalent inertia box (surface)
|
||||||
double aabb[6]; // axis-aligned bounding box
|
double aabb_[6]; // axis-aligned bounding box
|
||||||
double volume; // volume of the mesh
|
double volume_; // volume of the mesh
|
||||||
double surface; // surface of the mesh
|
double surface_; // surface of the mesh
|
||||||
|
|
||||||
// mesh data to be copied into mjModel
|
// mesh data to be copied into mjModel
|
||||||
int nvert; // number of vertices
|
int nvert_; // number of vertices
|
||||||
int nnormal; // number of normals
|
int nnormal_; // number of normals
|
||||||
int ntexcoord; // number of texcoords
|
int ntexcoord_; // number of texcoords
|
||||||
int nface; // number of faces
|
int nface_; // number of faces
|
||||||
int szgraph; // size of graph data in ints
|
int szgraph_; // size of graph data in ints
|
||||||
float* vert; // vertex data (3*nvert), relative to (pos, quat)
|
float* vert_; // vertex data (3*nvert), relative to (pos, quat)
|
||||||
float* normal; // vertex normal data (3*nnormal)
|
float* normal_; // vertex normal data (3*nnormal)
|
||||||
double* center; // face circumcenter data (3*nface)
|
double* center_; // face circumcenter data (3*nface)
|
||||||
float* texcoord; // vertex texcoord data (2*ntexcoord or NULL)
|
float* texcoord_; // vertex texcoord data (2*ntexcoord or NULL)
|
||||||
int* face; // face vertex indices (3*nface)
|
int* face_; // face vertex indices (3*nface)
|
||||||
int* facenormal; // face normal indices (3*nface)
|
int* facenormal_; // face normal indices (3*nface)
|
||||||
int* facetexcoord; // face texcoord indices (3*nface)
|
int* facetexcoord_; // face texcoord indices (3*nface)
|
||||||
int* graph; // convex graph data
|
int* graph_; // convex graph data
|
||||||
|
|
||||||
bool needhull; // needs convex hull for collisions
|
bool needhull_; // needs convex hull for collisions
|
||||||
|
|
||||||
mjCBoundingVolumeHierarchy tree; // bounding volume hierarchy
|
mjCBoundingVolumeHierarchy tree_; // bounding volume hierarchy
|
||||||
std::vector<double> face_aabb; // bounding boxes of all faces
|
std::vector<double> face_aabb_; // bounding boxes of all faces
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1155,7 +1155,6 @@ void mjXReader::Size(XMLElement* section, mjCModel* mod) {
|
|||||||
|
|
||||||
ReadAttrInt(section, "nuser_sensor", &mod->nuser_sensor);
|
ReadAttrInt(section, "nuser_sensor", &mod->nuser_sensor);
|
||||||
if (mod->nuser_sensor < -1) throw mjXError(section, "nuser_sensor must be >= -1");
|
if (mod->nuser_sensor < -1) throw mjXError(section, "nuser_sensor must be >= -1");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1187,26 +1186,27 @@ void mjXReader::OneMesh(XMLElement* elem, mjCMesh* pmesh) {
|
|||||||
// read attributes
|
// read attributes
|
||||||
ReadAttrTxt(elem, "name", pmesh->name);
|
ReadAttrTxt(elem, "name", pmesh->name);
|
||||||
ReadAttrTxt(elem, "class", pmesh->classname);
|
ReadAttrTxt(elem, "class", pmesh->classname);
|
||||||
ReadAttrTxt(elem, "content_type", pmesh->content_type);
|
pmesh->set_content_type(ReadAttrStr(elem, "content_type"));
|
||||||
ReadAttrTxt(elem, "file", pmesh->file);
|
pmesh->set_file(ReadAttrStr(elem, "file"));
|
||||||
ReadAttr(elem, "refpos", 3, pmesh->refpos, text);
|
pmesh->set_refpos(ReadAttrArr<double, 3>(elem, "refpos"));
|
||||||
ReadAttr(elem, "refquat", 4, pmesh->refquat, text);
|
pmesh->set_refquat(ReadAttrArr<double, 4>(elem, "refquat"));
|
||||||
ReadAttr(elem, "scale", 3, pmesh->scale, text);
|
pmesh->set_scale(ReadAttrArr<double, 3>(elem, "scale"));
|
||||||
|
|
||||||
if (MapValue(elem, "smoothnormal", &n, bool_map, 2)) {
|
if (MapValue(elem, "smoothnormal", &n, bool_map, 2)) {
|
||||||
pmesh->smoothnormal = (n==1);
|
pmesh->set_smoothnormal((n==1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// read user vertex data
|
// read user vertex data
|
||||||
if (ReadAttrTxt(elem, "vertex", text)) String2Vector(text, pmesh->uservert);
|
pmesh->set_uservert(ReadAttrVec<float>(elem, "vertex"));
|
||||||
|
|
||||||
// read user normal data
|
// read user normal data
|
||||||
if (ReadAttrTxt(elem, "normal", text)) String2Vector(text, pmesh->usernormal);
|
pmesh->set_usernormal(ReadAttrVec<float>(elem, "normal"));
|
||||||
|
|
||||||
// read user texcoord data
|
// read user texcoord data
|
||||||
if (ReadAttrTxt(elem, "texcoord", text)) String2Vector(text, pmesh->usertexcoord);
|
pmesh->set_usertexcoord(ReadAttrVec<float>(elem, "texcoord"));
|
||||||
|
|
||||||
// read user face data
|
// read user face data
|
||||||
if (ReadAttrTxt(elem, "face", text)) String2Vector(text, pmesh->userface);
|
pmesh->set_userface(ReadAttrVec<int>(elem, "face"));
|
||||||
|
|
||||||
GetXMLPos(elem, pmesh);
|
GetXMLPos(elem, pmesh);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,39 +90,39 @@ void mjXWriter::OneMesh(XMLElement* elem, mjCMesh* pmesh, mjCDef* def) {
|
|||||||
if (!writingdefaults) {
|
if (!writingdefaults) {
|
||||||
WriteAttrTxt(elem, "name", pmesh->name);
|
WriteAttrTxt(elem, "name", pmesh->name);
|
||||||
WriteAttrTxt(elem, "class", pmesh->classname);
|
WriteAttrTxt(elem, "class", pmesh->classname);
|
||||||
WriteAttrTxt(elem, "content_type", pmesh->content_type);
|
WriteAttrTxt(elem, "content_type", pmesh->content_type());
|
||||||
WriteAttrTxt(elem, "file", pmesh->file);
|
WriteAttrTxt(elem, "file", pmesh->file());
|
||||||
|
|
||||||
// write vertex data
|
// write vertex data
|
||||||
if (!pmesh->uservert.empty()) {
|
if (!pmesh->uservert().empty()) {
|
||||||
Vector2String(text, pmesh->uservert);
|
Vector2String(text, pmesh->uservert());
|
||||||
WriteAttrTxt(elem, "vertex", text);
|
WriteAttrTxt(elem, "vertex", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write normal data
|
// write normal data
|
||||||
if (!pmesh->usernormal.empty()) {
|
if (!pmesh->usernormal().empty()) {
|
||||||
Vector2String(text, pmesh->usernormal);
|
Vector2String(text, pmesh->usernormal());
|
||||||
WriteAttrTxt(elem, "normal", text);
|
WriteAttrTxt(elem, "normal", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write texcoord data
|
// write texcoord data
|
||||||
if (!pmesh->usertexcoord.empty()) {
|
if (!pmesh->usertexcoord().empty()) {
|
||||||
Vector2String(text, pmesh->usertexcoord);
|
Vector2String(text, pmesh->usertexcoord());
|
||||||
WriteAttrTxt(elem, "texcoord", text);
|
WriteAttrTxt(elem, "texcoord", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write face data
|
// write face data
|
||||||
if (!pmesh->userface.empty()) {
|
if (!pmesh->userface().empty()) {
|
||||||
Vector2String(text, pmesh->userface);
|
Vector2String(text, pmesh->userface());
|
||||||
WriteAttrTxt(elem, "face", text);
|
WriteAttrTxt(elem, "face", text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaults and regular
|
// defaults and regular
|
||||||
WriteAttr(elem, "refpos", 3, pmesh->refpos, def->mesh.refpos);
|
WriteAttr(elem, "refpos", 3, pmesh->refpos(), def->mesh.refpos());
|
||||||
WriteAttr(elem, "refquat", 4, pmesh->refquat, def->mesh.refquat);
|
WriteAttr(elem, "refquat", 4, pmesh->refquat(), def->mesh.refquat());
|
||||||
WriteAttr(elem, "scale", 3, pmesh->scale, def->mesh.scale);
|
WriteAttr(elem, "scale", 3, pmesh->scale(), def->mesh.scale());
|
||||||
WriteAttrKey(elem, "smoothnormal", bool_map, 2, pmesh->smoothnormal, def->mesh.smoothnormal);
|
WriteAttrKey(elem, "smoothnormal", bool_map, 2, pmesh->smoothnormal(), def->mesh.smoothnormal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-8
@@ -542,10 +542,11 @@ mjCGeom* mjXURDF::Geom(XMLElement* geom_elem, mjCBody* pbody, bool collision) {
|
|||||||
// mesh
|
// mesh
|
||||||
else if ((temp = FindSubElem(elem, "mesh"))) {
|
else if ((temp = FindSubElem(elem, "mesh"))) {
|
||||||
// set geom type and read mesh attributes
|
// set geom type and read mesh attributes
|
||||||
double meshscale[3] = {1, 1, 1};
|
|
||||||
pgeom->type = mjGEOM_MESH;
|
pgeom->type = mjGEOM_MESH;
|
||||||
ReadAttrTxt(temp, "filename", meshfile, true);
|
meshfile = ReadAttrStr(temp, "filename", true).value();
|
||||||
ReadAttr(temp, "scale", 3, meshscale, text);
|
std::array<double, 3> default_meshscale = {1, 1, 1};
|
||||||
|
std::array<double, 3> meshscale = ReadAttrArr<double, 3>(temp, "scale")
|
||||||
|
.value_or(default_meshscale);
|
||||||
|
|
||||||
// strip file name if necessary
|
// strip file name if necessary
|
||||||
if (model->strippath) {
|
if (model->strippath) {
|
||||||
@@ -565,18 +566,18 @@ mjCGeom* mjXURDF::Geom(XMLElement* geom_elem, mjCBody* pbody, bool collision) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exists with different scale: append name with '1', create
|
// exists with different scale: append name with '1', create
|
||||||
else if (pmesh->scale[0]!=meshscale[0] ||
|
else if (pmesh->scale()[0]!=meshscale[0] ||
|
||||||
pmesh->scale[1]!=meshscale[1] ||
|
pmesh->scale()[1]!=meshscale[1] ||
|
||||||
pmesh->scale[2]!=meshscale[2]) {
|
pmesh->scale()[2]!=meshscale[2]) {
|
||||||
pmesh = model->AddMesh();
|
pmesh = model->AddMesh();
|
||||||
meshname = meshname + "1";
|
meshname = meshname + "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
// set fields
|
// set fields
|
||||||
pmesh->file = meshfile;
|
pmesh->set_file(meshfile);
|
||||||
pmesh->name = meshname;
|
pmesh->name = meshname;
|
||||||
pgeom->mesh = meshname;
|
pgeom->mesh = meshname;
|
||||||
mjuu_copyvec(pmesh->scale, meshscale, 3);
|
pmesh->set_scale(meshscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|||||||
+5
-5
@@ -895,7 +895,7 @@ static int Round(double x) {
|
|||||||
|
|
||||||
// write attribute
|
// write attribute
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void mjXUtil::WriteAttr(XMLElement* elem, string name, int n, T* data, const T* def) {
|
void mjXUtil::WriteAttr(XMLElement* elem, string name, int n, const T* data, const T* def) {
|
||||||
// make sure all are defined
|
// make sure all are defined
|
||||||
if constexpr (std::is_floating_point_v<T>) {
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
for (int i=0; i<n; i++) {
|
for (int i=0; i<n; i++) {
|
||||||
@@ -935,16 +935,16 @@ void mjXUtil::WriteAttr(XMLElement* elem, string name, int n, T* data, const T*
|
|||||||
|
|
||||||
|
|
||||||
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
||||||
double* data, const double* def);
|
const double* data, const double* def);
|
||||||
|
|
||||||
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
||||||
float* data, const float* def);
|
const float* data, const float* def);
|
||||||
|
|
||||||
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
||||||
int* data, const int* def);
|
const int* data, const int* def);
|
||||||
|
|
||||||
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
template void mjXUtil::WriteAttr(XMLElement* elem, string name, int n,
|
||||||
mjtByte* data, const mjtByte* def);
|
const mjtByte* data, const mjtByte* def);
|
||||||
|
|
||||||
|
|
||||||
// write vector<double> attribute, default = zero array
|
// write vector<double> attribute, default = zero array
|
||||||
|
|||||||
+1
-1
@@ -179,7 +179,7 @@ class mjXUtil {
|
|||||||
|
|
||||||
// write attribute- any type
|
// write attribute- any type
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void WriteAttr(tinyxml2::XMLElement* elem, std::string name, int n, T* data,
|
static void WriteAttr(tinyxml2::XMLElement* elem, std::string name, int n, const T* data,
|
||||||
const T* def = 0);
|
const T* def = 0);
|
||||||
|
|
||||||
// write vector<double> attribute, with and without default
|
// write vector<double> attribute, with and without default
|
||||||
|
|||||||
Reference in New Issue
Block a user