| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | #include "Exception.h" |
|---|
| 15 | #include "HeightFieldLayer.h" |
|---|
| 16 | #include "Layer.h" |
|---|
| 17 | |
|---|
| 18 | #include <osgDB/ReadFile> |
|---|
| 19 | #include <osg/io_utils> |
|---|
| 20 | |
|---|
| 21 | using namespace ive; |
|---|
| 22 | |
|---|
| 23 | void HeightFieldLayer::write(DataOutputStream* out) |
|---|
| 24 | { |
|---|
| 25 | |
|---|
| 26 | out->writeInt(IVEHEIGHTFIELDLAYER); |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | osgTerrain::Layer* layer = dynamic_cast<osgTerrain::Layer*>(this); |
|---|
| 30 | if (layer) |
|---|
| 31 | ((ive::Layer*)(layer))->write(out); |
|---|
| 32 | else |
|---|
| 33 | out_THROW_EXCEPTION("HeightFieldLayer::write(): Could not cast this osgLayer::HeightFieldLayer to an osgTerrain::Layer."); |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | if (getFileName().empty() && getHeightField()) |
|---|
| 37 | { |
|---|
| 38 | osg::HeightField* hf = getHeightField(); |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | out->writeBool(true); |
|---|
| 42 | if (out->getVersion()>=VERSION_0035) |
|---|
| 43 | { |
|---|
| 44 | |
|---|
| 45 | out->writeUInt(hf->getNumColumns()); |
|---|
| 46 | out->writeUInt(hf->getNumRows()); |
|---|
| 47 | out->writeVec3(hf->getOrigin()); |
|---|
| 48 | out->writeFloat(hf->getXInterval()); |
|---|
| 49 | out->writeFloat(hf->getYInterval()); |
|---|
| 50 | out->writeQuat(hf->getRotation()); |
|---|
| 51 | out->writeFloat(hf->getSkirtHeight()); |
|---|
| 52 | out->writeUInt(hf->getBorderWidth()); |
|---|
| 53 | |
|---|
| 54 | float maxError = 0.0f; |
|---|
| 55 | |
|---|
| 56 | if (getLocator()) |
|---|
| 57 | { |
|---|
| 58 | osg::Vec3d world_origin, world_corner; |
|---|
| 59 | |
|---|
| 60 | getLocator()->convertLocalToModel(osg::Vec3d(0.0,0.0,0.0), world_origin); |
|---|
| 61 | getLocator()->convertLocalToModel(osg::Vec3d(1.0,1.0,0.0), world_corner); |
|---|
| 62 | |
|---|
| 63 | double distance = (world_origin-world_corner).length(); |
|---|
| 64 | |
|---|
| 65 | maxError = distance * out->getTerrainMaximumErrorToSizeRatio(); |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | out->writePackedFloatArray(hf->getFloatArray(), maxError); |
|---|
| 69 | } |
|---|
| 70 | else |
|---|
| 71 | { |
|---|
| 72 | out->writeShape(getHeightField()); |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | } |
|---|
| 76 | else |
|---|
| 77 | { |
|---|
| 78 | |
|---|
| 79 | out->writeBool(false); |
|---|
| 80 | out->writeString(getFileName()); |
|---|
| 81 | } |
|---|
| 82 | |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | void HeightFieldLayer::read(DataInputStream* in) |
|---|
| 86 | { |
|---|
| 87 | |
|---|
| 88 | int id = in->peekInt(); |
|---|
| 89 | if (id != IVEHEIGHTFIELDLAYER) |
|---|
| 90 | in_THROW_EXCEPTION("HeightFieldLayer::read(): Expected HeightFieldLayer identification."); |
|---|
| 91 | |
|---|
| 92 | |
|---|
| 93 | id = in->readInt(); |
|---|
| 94 | |
|---|
| 95 | |
|---|
| 96 | osgTerrain::Layer* layer = dynamic_cast<osgTerrain::Layer*>(this); |
|---|
| 97 | if (layer) |
|---|
| 98 | ((ive::Layer*)(layer))->read(in); |
|---|
| 99 | else |
|---|
| 100 | in_THROW_EXCEPTION("HeightFieldLayer::read(): Could not cast this osgLayer::Layer to an osg::Group."); |
|---|
| 101 | |
|---|
| 102 | |
|---|
| 103 | bool useInlineHeightField = in->readBool(); |
|---|
| 104 | |
|---|
| 105 | if (useInlineHeightField) |
|---|
| 106 | { |
|---|
| 107 | |
|---|
| 108 | if (in->getVersion()>=VERSION_0035) |
|---|
| 109 | { |
|---|
| 110 | osg::HeightField* hf = new osg::HeightField; |
|---|
| 111 | |
|---|
| 112 | |
|---|
| 113 | |
|---|
| 114 | unsigned int col = in->readUInt(); |
|---|
| 115 | unsigned int row = in->readUInt(); |
|---|
| 116 | hf->allocate(col,row); |
|---|
| 117 | |
|---|
| 118 | hf->setOrigin(in->readVec3()); |
|---|
| 119 | hf->setXInterval(in->readFloat()); |
|---|
| 120 | hf->setYInterval(in->readFloat()); |
|---|
| 121 | hf->setRotation(in->readQuat()); |
|---|
| 122 | |
|---|
| 123 | hf->setSkirtHeight(in->readFloat()); |
|---|
| 124 | hf->setBorderWidth(in->readUInt()); |
|---|
| 125 | |
|---|
| 126 | if (in->getVersion()>=VERSION_0035) |
|---|
| 127 | { |
|---|
| 128 | in->readPackedFloatArray(hf->getFloatArray()); |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | setHeightField(hf); |
|---|
| 132 | |
|---|
| 133 | } |
|---|
| 134 | else |
|---|
| 135 | { |
|---|
| 136 | osg::Shape* shape = in->readShape(); |
|---|
| 137 | setHeightField(dynamic_cast<osg::HeightField*>(shape)); |
|---|
| 138 | } |
|---|
| 139 | |
|---|
| 140 | } |
|---|
| 141 | else |
|---|
| 142 | { |
|---|
| 143 | std::string filename = in->readString(); |
|---|
| 144 | setFileName(filename); |
|---|
| 145 | |
|---|
| 146 | setHeightField(osgDB::readHeightFieldFile(filename,in->getOptions())); |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | } |
|---|