goat3d

annotate goatview/src/scenemodel.cc @ 90:8b156bc5205b

[maxgoat] fixed the transform export bug [goatview] added widgets for the animation controls [goatview] added a grid ground plane with automatic sizing and transitions from size to size
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 17 May 2014 06:26:24 +0300
parents 6d04caf510ab
children
rev   line source
nuclear@86 1 #include <assert.h>
nuclear@86 2 #include "scenemodel.h"
nuclear@88 3 #include "goatview.h"
nuclear@86 4
nuclear@86 5 SceneModel::SceneModel()
nuclear@86 6 {
nuclear@86 7 scn = 0;
nuclear@86 8 }
nuclear@86 9
nuclear@86 10 SceneModel::~SceneModel()
nuclear@86 11 {
nuclear@86 12 clear_scene();
nuclear@86 13 }
nuclear@86 14
nuclear@86 15 void SceneModel::set_scene(goat3d *scn)
nuclear@86 16 {
nuclear@86 17 clear_scene();
nuclear@86 18 this->scn = scn;
nuclear@86 19
nuclear@86 20 if(!scn) return;
nuclear@86 21
nuclear@86 22 // create the SceneNodeData for each node
nuclear@86 23 int num_nodes = goat3d_get_node_count(scn);
nuclear@86 24 for(int i=0; i<num_nodes; i++) {
nuclear@86 25 goat3d_node *node = goat3d_get_node(scn, i);
nuclear@86 26
nuclear@86 27 SceneNodeData data;
nuclear@86 28 data.visible = true;
nuclear@88 29 data.selected = false;
nuclear@86 30
nuclear@86 31 node_data[node] = data;
nuclear@86 32 }
nuclear@86 33 }
nuclear@86 34
nuclear@86 35 void SceneModel::clear_scene()
nuclear@86 36 {
nuclear@86 37 node_data.clear();
nuclear@86 38 scn = 0;
nuclear@86 39 }
nuclear@86 40
nuclear@86 41 SceneNodeData *SceneModel::get_node_data(goat3d_node *node) const
nuclear@86 42 {
nuclear@86 43 auto it = node_data.find(node);
nuclear@86 44 if(it == node_data.end()) {
nuclear@86 45 return 0;
nuclear@86 46 }
nuclear@86 47 return (SceneNodeData*)&it->second;
nuclear@86 48 }
nuclear@86 49
nuclear@86 50 Qt::ItemFlags SceneModel::flags(const QModelIndex &index) const
nuclear@86 51 {
nuclear@86 52 if(!index.isValid()) {
nuclear@86 53 return 0;
nuclear@86 54 }
nuclear@86 55
nuclear@86 56 Qt::ItemFlags res = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
nuclear@86 57 if(index.column() == 1) {
nuclear@86 58 res |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
nuclear@86 59 }
nuclear@86 60 return res;
nuclear@86 61 }
nuclear@86 62
nuclear@86 63 QVariant SceneModel::data(const QModelIndex &index, int role) const
nuclear@86 64 {
nuclear@86 65 if(!index.isValid()) {
nuclear@86 66 return QVariant();
nuclear@86 67 }
nuclear@86 68
nuclear@86 69 goat3d_node *node = (goat3d_node*)index.internalPointer();
nuclear@86 70 SceneNodeData *data = get_node_data(node);
nuclear@86 71
nuclear@86 72 switch(index.column()) {
nuclear@86 73 case 0:
nuclear@86 74 if(role == Qt::DisplayRole) {
nuclear@86 75 return QString(goat3d_get_node_name(node));
nuclear@86 76 }
nuclear@86 77 break;
nuclear@86 78
nuclear@86 79 case 1:
nuclear@86 80 if(role == Qt::CheckStateRole && data) {
nuclear@86 81 return data->visible ? Qt::Checked : Qt::Unchecked;
nuclear@86 82 }
nuclear@86 83 break;
nuclear@86 84
nuclear@86 85 default:
nuclear@86 86 break;
nuclear@86 87 }
nuclear@86 88
nuclear@86 89 return QVariant();
nuclear@86 90 }
nuclear@86 91
nuclear@86 92 bool SceneModel::setData(const QModelIndex &index, const QVariant &value, int role)
nuclear@86 93 {
nuclear@86 94 if(!index.isValid()) {
nuclear@86 95 return false;
nuclear@86 96 }
nuclear@86 97
nuclear@86 98 goat3d_node *node = (goat3d_node*)index.internalPointer();
nuclear@86 99 SceneNodeData *data = get_node_data(node);
nuclear@86 100 assert(data);
nuclear@86 101
nuclear@86 102 switch(index.column()) {
nuclear@86 103 case 1:
nuclear@86 104 if(role == Qt::CheckStateRole) {
nuclear@86 105 data->visible = value.toBool();
nuclear@86 106 emit dataChanged(index, index);
nuclear@86 107 return true;
nuclear@86 108 }
nuclear@86 109 break;
nuclear@86 110
nuclear@86 111 default:
nuclear@86 112 break;
nuclear@86 113 }
nuclear@86 114 return false;
nuclear@86 115 }
nuclear@86 116
nuclear@86 117 QVariant SceneModel::headerData(int section, Qt::Orientation orient, int role) const
nuclear@86 118 {
nuclear@86 119 if(orient == Qt::Horizontal && role == Qt::DisplayRole) {
nuclear@86 120 switch(section) {
nuclear@86 121 case 0:
nuclear@86 122 return QString("name");
nuclear@86 123 case 1:
nuclear@86 124 return QString("vis");
nuclear@86 125 default:
nuclear@86 126 return QString("???");
nuclear@86 127 }
nuclear@86 128 }
nuclear@86 129 return QVariant();
nuclear@86 130 }
nuclear@86 131
nuclear@86 132 int SceneModel::rowCount(const QModelIndex &parent) const
nuclear@86 133 {
nuclear@86 134 if(!scn) return 0;
nuclear@86 135
nuclear@86 136 if(!parent.isValid()) {
nuclear@86 137 // return the number of root nodes
nuclear@86 138 int num_nodes = goat3d_get_node_count(scn);
nuclear@86 139 int num_root_nodes = 0;
nuclear@86 140 for(int i=0; i<num_nodes; i++) {
nuclear@86 141 goat3d_node *node = goat3d_get_node(scn, i);
nuclear@86 142 if(!goat3d_get_node_parent(node)) {
nuclear@86 143 ++num_root_nodes;
nuclear@86 144 }
nuclear@86 145 }
nuclear@86 146 return num_root_nodes;
nuclear@86 147 }
nuclear@86 148
nuclear@86 149 goat3d_node *pnode = (goat3d_node*)parent.internalPointer();
nuclear@86 150 return goat3d_get_node_child_count(pnode);
nuclear@86 151 }
nuclear@86 152
nuclear@86 153 int SceneModel::columnCount(const QModelIndex &parent) const
nuclear@86 154 {
nuclear@86 155 return 2;
nuclear@86 156 }
nuclear@86 157
nuclear@86 158 bool SceneModel::hasChildren(const QModelIndex &parent) const
nuclear@86 159 {
nuclear@86 160 if(!parent.isValid()) {
nuclear@86 161 return true;
nuclear@86 162 }
nuclear@86 163
nuclear@86 164 goat3d_node *pnode = (goat3d_node*)parent.internalPointer();
nuclear@86 165 return goat3d_get_node_child_count(pnode) > 0;
nuclear@86 166 }
nuclear@86 167
nuclear@86 168 QModelIndex SceneModel::index(int row, int column, const QModelIndex &parent) const
nuclear@86 169 {
nuclear@86 170 if(!scn) {
nuclear@86 171 return QModelIndex();
nuclear@86 172 }
nuclear@86 173
nuclear@86 174 goat3d_node *node = 0;
nuclear@86 175
nuclear@86 176 if(!parent.isValid()) {
nuclear@86 177 int num_nodes = goat3d_get_node_count(scn);
nuclear@86 178 int idx = 0;
nuclear@86 179 for(int i=0; i<num_nodes; i++) {
nuclear@86 180 goat3d_node *n = goat3d_get_node(scn, i);
nuclear@86 181 if(!goat3d_get_node_parent(n)) {
nuclear@86 182 if(idx == row) {
nuclear@86 183 node = n;
nuclear@86 184 break;
nuclear@86 185 }
nuclear@86 186 idx++;
nuclear@86 187 }
nuclear@86 188 }
nuclear@86 189
nuclear@86 190 if(idx != row) {
nuclear@86 191 return QModelIndex(); // failed
nuclear@86 192 }
nuclear@86 193 } else {
nuclear@86 194 goat3d_node *pnode = (goat3d_node*)parent.internalPointer();
nuclear@86 195 node = goat3d_get_node_child(pnode, row);
nuclear@86 196 }
nuclear@86 197
nuclear@86 198 if(!node) {
nuclear@86 199 return QModelIndex();
nuclear@86 200 }
nuclear@86 201 return createIndex(row, column, (void*)node);
nuclear@86 202 }
nuclear@86 203
nuclear@86 204 QModelIndex SceneModel::parent(const QModelIndex &index) const
nuclear@86 205 {
nuclear@86 206 if(!index.isValid()) {
nuclear@86 207 return QModelIndex(); // root node
nuclear@86 208 }
nuclear@86 209
nuclear@86 210 goat3d_node *node = (goat3d_node*)index.internalPointer();
nuclear@86 211 goat3d_node *parent = node ? goat3d_get_node_parent(node) : 0;
nuclear@86 212
nuclear@86 213 if(!parent) {
nuclear@86 214 return QModelIndex();
nuclear@86 215 }
nuclear@86 216
nuclear@86 217 // find out which child of its parent is our parent
nuclear@86 218 int pidx = -1;
nuclear@86 219
nuclear@86 220 goat3d_node *grandparent = goat3d_get_node_parent(parent);
nuclear@86 221 if(grandparent) {
nuclear@86 222 int num_children = goat3d_get_node_child_count(grandparent);
nuclear@86 223 for(int i=0; i<num_children; i++) {
nuclear@86 224 if(goat3d_get_node_child(grandparent, i) == parent) {
nuclear@86 225 pidx = i;
nuclear@86 226 break;
nuclear@86 227 }
nuclear@86 228 }
nuclear@86 229 } else {
nuclear@86 230 int idx = 0;
nuclear@86 231 int num_nodes = goat3d_get_node_count(scn);
nuclear@86 232 for(int i=0; i<num_nodes; i++) {
nuclear@86 233 goat3d_node *n = goat3d_get_node(scn, i);
nuclear@86 234 if(!goat3d_get_node_parent(n)) {
nuclear@86 235 if(n == parent) {
nuclear@86 236 pidx = idx;
nuclear@86 237 break;
nuclear@86 238 }
nuclear@86 239 idx++;
nuclear@86 240 }
nuclear@86 241 }
nuclear@86 242 }
nuclear@86 243
nuclear@86 244 if(pidx == -1) {
nuclear@86 245 fprintf(stderr, "%s: wtf?\n", __FUNCTION__);
nuclear@86 246 return QModelIndex(); // failed
nuclear@86 247 }
nuclear@86 248
nuclear@86 249 return createIndex(pidx, 0, (void*)parent);
nuclear@86 250 }
nuclear@88 251
nuclear@88 252
nuclear@88 253 void SceneModel::selchange(const QModelIndexList &selidx)
nuclear@88 254 {
nuclear@88 255 // go over the previously selected and unselect them
nuclear@88 256 std::set<goat3d_node*>::iterator it = selected.begin();
nuclear@88 257 while(it != selected.end()) {
nuclear@88 258 goat3d_node *node = *it++;
nuclear@88 259 SceneNodeData *data = get_node_data(node);
nuclear@88 260 data->selected = false;
nuclear@88 261 }
nuclear@88 262 selected.clear();
nuclear@88 263
nuclear@88 264 for(int i=0; i<selidx.size(); i++) {
nuclear@88 265 goat3d_node *node = (goat3d_node*)selidx.at(i).internalPointer();
nuclear@88 266 SceneNodeData *data = get_node_data(node);
nuclear@88 267 data->selected = true;
nuclear@88 268 selected.insert(node);
nuclear@88 269 }
nuclear@88 270
nuclear@88 271 post_redisplay();
nuclear@88 272 }