1/*
2 * Copyright (c) 2009-2012 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32package com.jme3.terrain;
33
34import com.jme3.material.Material;
35import com.jme3.math.Vector2f;
36import com.jme3.math.Vector3f;
37import com.jme3.terrain.geomipmap.lodcalc.LodCalculator;
38import java.util.List;
39
40/**
41 * Terrain can be one or many meshes comprising of a, probably large, piece of land.
42 * Terrain is Y-up in the grid axis, meaning gravity acts in the -Y direction.
43 * Level of Detail (LOD) is supported and expected as terrains can get very large. LOD can
44 * also be disabled if you so desire, however some terrain implementations can choose to ignore
45 * useLOD(boolean).
46 * Terrain implementations should extend Node, or at least Spatial.
47 *
48 * @author bowens
49 */
50public interface Terrain {
51
52    /**
53     * Get the real-world height of the terrain at the specified X-Z coorindate.
54     * @param xz the X-Z world coordinate
55     * @return the height at the given point
56     */
57    public float getHeight(Vector2f xz);
58
59    /**
60     * Get the normal vector for the surface of the terrain at the specified
61     * X-Z coordinate. This normal vector can be a close approximation. It does not
62     * take into account any normal maps on the material.
63     * @param xz the X-Z world coordinate
64     * @return the normal vector at the given point
65     */
66    public Vector3f getNormal(Vector2f xz);
67
68    /**
69     * Get the heightmap height at the specified X-Z coordinate. This does not
70     * count scaling and snaps the XZ coordinate to the nearest (rounded) heightmap grid point.
71     * @param xz world coordinate
72     * @return the height, unscaled and uninterpolated
73     */
74    public float getHeightmapHeight(Vector2f xz);
75
76    /**
77     * Set the height at the specified X-Z coordinate.
78     * To set the height of the terrain and see it, you will have
79     * to unlock the terrain meshes by calling terrain.setLocked(false) before
80     * you call setHeight().
81     * @param xzCoordinate coordinate to set the height
82     * @param height that will be set at the coordinate
83     */
84    public void setHeight(Vector2f xzCoordinate, float height);
85
86    /**
87     * Set the height at many points. The two lists must be the same size.
88     * Each xz coordinate entry matches to a height entry, 1 for 1. So the
89     * first coordinate matches to the first height value, the last to the
90     * last etc.
91     * @param xz a list of coordinates where the hight will be set
92     * @param height the heights that match the xz coordinates
93     */
94    public void setHeight(List<Vector2f> xz, List<Float> height);
95
96    /**
97     * Raise/lower the height in one call (instead of getHeight then setHeight).
98     * @param xzCoordinate world coordinate to adjust the terrain height
99     * @param delta +- value to adjust the height by
100     */
101    public void adjustHeight(Vector2f xzCoordinate, float delta);
102
103    /**
104     * Raise/lower the height at many points. The two lists must be the same size.
105     * Each xz coordinate entry matches to a height entry, 1 for 1. So the
106     * first coordinate matches to the first height value, the last to the
107     * last etc.
108     * @param xz a list of coordinates where the hight will be adjusted
109     * @param height +- value to adjust the height by, that matches the xz coordinates
110     */
111    public void adjustHeight(List<Vector2f> xz, List<Float> height);
112
113    /**
114     * Get the heightmap of the entire terrain.
115     * This can return null if that terrain object does not store the height data.
116     * Infinite or "paged" terrains will not be able to support this, so use with caution.
117     */
118    public float[] getHeightMap();
119
120    /**
121     * This is calculated by the specific LOD algorithm.
122     * A value of one means that the terrain is showing full detail.
123     * The higher the value, the more the terrain has been generalized
124     * and the less detailed it will be.
125     */
126    public int getMaxLod();
127
128    /**
129     * Called by an LodControl.
130     * Calculates the level of detail of the terrain and adjusts its geometry.
131     * This is where the Terrain's LOD algorithm will change the detail of
132     * the terrain based on how far away this position is from the particular
133     * terrain patch.
134     * @param location the Camera's location. A list of one camera location is normal
135     *  if you just have one camera in your scene.
136     */
137    public void update(List<Vector3f> location, LodCalculator lodCalculator);
138
139    /**
140     * Lock or unlock the meshes of this terrain.
141     * Locked meshes are un-editable but have better performance.
142     * This should call the underlying getMesh().setStatic()/setDynamic() methods.
143     * @param locked or unlocked
144     */
145    public void setLocked(boolean locked);
146
147    /**
148     * Pre-calculate entropy values.
149     * Some terrain systems support entropy calculations to determine LOD
150     * changes. Often these entropy calculations are expensive and can be
151     * cached ahead of time. Use this method to do that.
152     */
153    public void generateEntropy(ProgressMonitor monitor);
154
155    /**
156     * Returns the material that this terrain uses.
157     * If it uses many materials, just return the one you think is best.
158     * For TerrainQuads this is sufficient. For TerrainGrid you want to call
159     * getMaterial(Vector3f) instead.
160     */
161    public Material getMaterial();
162
163    /**
164     * Returns the material that this terrain uses.
165     * Terrain can have different materials in different locations.
166     * In general, the TerrainQuad will only have one material. But
167     * TerrainGrid will have a different material per tile.
168     *
169     * It could be possible to pass in null for the location, some Terrain
170     * implementations might just have the one material and not care where
171     * you are looking. So implementations must handle null being supplied.
172     *
173     * @param worldLocation the location, in world coordinates, of where
174     * we are interested in the underlying texture.
175     */
176    public Material getMaterial(Vector3f worldLocation);
177
178    /**
179     * Used for painting to get the number of vertices along the edge of the
180     * terrain.
181     * This is an un-scaled size, and should represent the vertex count (ie. the
182     * texture coord count) along an edge of a square terrain.
183     *
184     * In the standard TerrainQuad default implementation, this will return
185     * the "totalSize" of the terrain (512 or so).
186     */
187    public int getTerrainSize();
188
189    /**
190     * Get the scale of the texture coordinates. Normally if the texture is
191     * laid on the terrain and not scaled so that the texture does not repeat,
192     * then each texture coordinate (on a vertex) will be 1/(terrain size).
193     * That is: the coverage between each consecutive texture coordinate will
194     * be a percentage of the total terrain size.
195     * So if the terrain is 512 vertexes wide, then each texture coord will cover
196     * 1/512 (or 0.00195) percent of the texture.
197     * This is used for converting between tri-planar texture scales and regular
198     * texture scales.
199     *
200     * not needed
201     */
202    //public float getTextureCoordinateScale();
203
204    /**
205     *
206     *
207     */
208    public int getNumMajorSubdivisions();
209}
210