亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? heightfield.h

?? 一個紋理地形渲染器
?? H
字號:
// Heightfield class

#pragma once

#include <vector>

#include "Mathematics/Float.h"
#include "Mathematics/Vector.h"

using namespace Mathematics;


/// A heightfield with bilinear interpolation support for height and normal queries at arbitrary (x,y).
/// Internally the heightfield stores a 2D array of floating point height samples in world space.
/// The key functionality that this class implements are queries about height and normal at a point
/// (x,y), either in integer coordinates (discrete terrain samples), or in world coordinates (bilinearly interpolated).
/// Please note that the heightfield makes the strict assumption that it is in the x,y plane with +z being up,
/// and that the width,height of the heightfield correspond to vectors along the x,y axes.

class Heightfield
{
public:

    /// Initialize heightfield from raw sample data.
    /// This method constructs the 2D floating point samples array from normalized floating point
    /// heightfield samples, a vector for the center of the terrain in (x,y) world space, 
    /// and scale factors along the xy plane and the vertical z axis.
	/// NOTE: the normalized data has 0.5 subtracted from its height, then it is scaled by scale_z
	/// to give the actual heights in world coordinates stored internally.
	/// NOTE: if the width and height are not power of two plus one, the nearest higher
	/// value which satisfies this constraint is used for the actual width and height
	/// of the heightfield sample array.

    void initialize(const float data[], int width, int height, const Vector &center, float scale_xy, float scale_z)
    {
		// initialize primary data

		assert(width>1);
		assert(height>1);
		assert(width==height);

		m_width = nearestPowerOfTwoPlusOneAbove(width);
        m_height = nearestPowerOfTwoPlusOneAbove(height);
		m_scale = scale_xy;

		// initialize secondary data

		m_scale_inverse = 1.0f / m_scale;
		m_scale_half = 0.5f * m_scale;
		m_scale_squared = m_scale * m_scale;

        const float half_dx = m_scale * width * 0.5f;
        const float half_dy = m_scale * height * 0.5f;
		const float half_dz = scale_z * 0.5f;

        m_origin = Vector( center.x - half_dx, center.x - half_dy, center.z - half_dz);

		m_minimum = m_origin;
		vectorAtIndex(width-1, height-1, m_maximum);

		// load heightfield samples

		const int size = m_width * m_height;
		m_samples.resize(size);

		load(data, width, height, &m_samples[0], m_width, m_height, true, 0.5f, scale_z);

		// calculate minimum and maximum z extents

		m_minimum.z = FLT_MAX;
		m_maximum.z = -FLT_MAX;

		const int samples = m_width*m_height;
		for (int i=0; i<samples; i++)
		{
			if (m_minimum.z>m_samples[i])
				m_minimum.z = m_samples[i];

			if (m_maximum.z<m_samples[i])
				m_maximum.z = m_samples[i];
		}
    }

    /// Get the height in world coordinates at integer sample coordinates (x,y).

	float heightAtIndex(int x, int y) const
	{
        assert(x>=0);
        assert(y>=0);
        assert(x<m_width);
        assert(y<m_height);

		return m_samples[x+y*m_height];
	}

    float heightAtOffset(unsigned int offset) const
    {
        assert(offset>=0);
        assert(offset<m_samples.size());
        return m_samples[offset];
    }

    int offsetAtIndex(int x, int y) const
    {
        return x+y*m_height;
    }

    /// Get the height in world coordinates at integer sample coordinates (x,y) clamped to bounds.
    /// Note that this method is temporary and will be removed once we implement a guard band border
    /// in the heightfield sample array.

    float heightAtIndex_SAFE(int x, int y) const
	{
		if (x<0) x = 0;                 
		else if (x>=m_width) x = m_width - 1;
    	
		if (y<0) y = 0;
		else if (y>=m_height) y = m_height - 1;

        assert(x>=0);
        assert(y>=0);
        assert(x<m_width);
        assert(y<m_height);

		return m_samples[x+y*m_height];
	}

    /// Get the bilinearly interpolated height at world coordinates (x,y).
    /// Please be careful that you pass (x,y) coordinates that are inside the heightfield, this method does not clamp or clip!

	float height(float x, float y) const
	{
		// the height returned here is in world units

		// (x1,y1) (x2,y1)
		// (x1,y2) (x2,y2)

		int x1 = Float::integer((x - m_origin.x) * m_scale_inverse);
		int y1 = Float::integer((y - m_origin.y) * m_scale_inverse);
		int x2 = x1 + 1;
		int y2 = y1 + 1;

		// a b
		// c d

		const float a = heightAtIndex_SAFE(x1,y1);
		const float b = heightAtIndex_SAFE(x2,y1);
		const float c = heightAtIndex_SAFE(x1,y2);
		const float d = heightAtIndex_SAFE(x2,y2);

		// calculate normalized distance from point sample at center of grid cell

		float cx,cy;
		vectorAtIndex(x1,y1,cx,cy);

		const float dx = (x - cx) * m_scale_inverse;
		const float dy = (y - cy) * m_scale_inverse;

		const float idx = 1 - dx;
		const float idy = 1 - dy;

		// calculate bilinear sample weightings

		const float weight_a = idx * idy;
		const float weight_b = dx * idy;
		const float weight_c = idx * dy;
		const float weight_d = dx * dy;

		// calculate bilinear height sample

		return weight_a*a + weight_b*b + weight_c*c + weight_d*d;
	}

    /// Get the bilinear interpolated normal vector at world coordinates (x,y)
    /// Note that the normal returned here will not be unit length, normalize it yourself if you need a unit vector!

	void normal(float x, float y, Vector &normal) const
	{
		// (x1,y1) (x2,y1)
		// (x1,y2) (x2,y2)

		int x1 = Float::integer((x - m_origin.x) * m_scale_inverse);
		int y1 = Float::integer((y - m_origin.y) * m_scale_inverse);
		int x2 = x1 + 1;
		int y2 = y1 + 1;

		// calculate normalized distance from point sample at center of grid cell

		float cx,cy;
		vectorAtIndex(x1,y1,cx,cy);

		const float dx = (x - cx) * m_scale_inverse;
		const float dy = (y - cy) * m_scale_inverse;

		const float idx = 1 - dx;
		const float idy = 1 - dy;

		// calculate bilinear sample weightings

		// a b
		// d c

		const float weight_a = idx * idy;
		const float weight_b = dx * idy;
		const float weight_c = dx * dy;
		const float weight_d = idx * dy;

		// sample grid heights

		//   i j
		// k l m n
		// o p q r
		//   s t

		const float i = heightAtIndex_SAFE(x1,   y1-1);
		const float j = heightAtIndex_SAFE(x2,   y1-1);
		const float k = heightAtIndex_SAFE(x1-1, y1);
		const float l = heightAtIndex_SAFE(x1,   y1);
		const float m = heightAtIndex_SAFE(x2,   y1);
		const float n = heightAtIndex_SAFE(x2+1, y1);
		const float o = heightAtIndex_SAFE(x1-1, y2);
		const float p = heightAtIndex_SAFE(x1,   y2);
		const float q = heightAtIndex_SAFE(x2,   y2);
		const float r = heightAtIndex_SAFE(x2+1, y2);
		const float s = heightAtIndex_SAFE(x1,   y2+1);
		const float t = heightAtIndex_SAFE(x2,   y2+1);

		// calculate interpolated normal

		normal.x = m_scale_half * ((k - m) * weight_a + (l - n) * weight_b + (p - r) * weight_c + (o - q) * weight_d);
		normal.y = m_scale_half * ((i - p) * weight_a + (j - q) * weight_b + (m - t) * weight_c + (l - s) * weight_d);
		normal.z = m_scale_squared * (weight_a + weight_b + weight_c + weight_d);
	}

    /// Get the normal vector integer sample coordinates (x,y).
    /// Note that the normal returned here will not be unit length, normalize it yourself if you need a unit vector!

	void normalAtIndex(int x, int y, Vector &normal) const
	{
		// a b
		// c 

		const float a = heightAtIndex_SAFE(x,y);          // temporary: pending guard band
		const float b = heightAtIndex_SAFE(x+1,y);
		const float c = heightAtIndex_SAFE(x,y+1);

		const Vector ab(m_scale, 0, b-a);
		const Vector ac(0, m_scale, c-a);
		
		normal = ab.cross(ac);
	}

    /// Get integer terrain sample index coordinates at world coordinates vector (point.x, point.y)

	void indexAtVector(const Vector &point, int &ix, int &iy) const
	{
		const float dx = (point.x - m_origin.x) * m_scale_inverse;
		const float dy = (point.y - m_origin.y) * m_scale_inverse;
		ix = Float::integer(dx);
		iy = Float::integer(dy);
	}

    /// Get integer terrain sample index coordinates at world coordinates vector (x,y)

	void indexAtVector(float x, float y, int &ix, int &iy) const
	{
		const float dx = (x - m_origin.x) * m_scale_inverse;
		const float dy = (y - m_origin.y) * m_scale_inverse;
		ix = Float::integer(dx);
		iy = Float::integer(dy);
	}

    /// Get world point vector (x,y) at integer terrain sample index (ix,iy)

	void vectorAtIndex(int ix, int iy, float &x, float &y) const
	{
		x = m_origin.x + ix * m_scale;
		y = m_origin.y + iy * m_scale;
	}

    /// Get world point vector (point.x,point.y) at integer terrain sample index (ix,iy).
    /// Note that this method sets point.z=0, it does NOT return the terrain height in the point vector!
    /// If you need this functionality please use the heightAtIndex method.

	void vectorAtIndex(int ix, int iy, Vector &point) const
	{
		point.x = m_origin.x + ix * m_scale;
		point.y = m_origin.y + iy * m_scale;
		point.z = 0;
	}

    /// Get world point vector (point.x,point.y) at integer terrain sample index (ix,iy).
    /// Note that this method sets the returned vector's z coordinate to 0.0f. 
    /// It does NOT return the terrain height in the vector! If you need to query
    /// terrain height at index please use the heightAtIndex method.

	Vector vectorAtIndex(int ix, int iy) const
	{
        return Vector(m_origin.x + ix * m_scale, m_origin.y + iy * m_scale, 0);
	}

    /// Get the origin of the heightfield

    Vector origin() const
    {
        return m_origin;
    }

	/// Get the minimum coordinate of the heightfield axis aligned bounding volume.
	/// note: minimum z coordinate not yet implemented.

	Vector minimum() const
	{
		return m_minimum;
	}

	/// Get the maximum coordinate of the heightfield axis aligned bounding volume.
	/// note: minimum z coordinate not yet implemented.

	Vector maximum() const
	{
		return m_maximum;
	}

    /// Get the width of the heightfield in samples.

	int width() const
	{
		return m_width;
	}

    /// Get the height of the heightfield in samples.

	int height() const
	{
		return m_height;
	}

    /// Get the scale of the heightfield

    float scale() const
    {
        return m_scale;
    }

	/// Check if vector is inside heightfield bounds
	/// note: checks if inside full 3d bounding box (m_minimum, m_maximum)

	bool inside(const Vector &vector) const
	{
		return ( vector.x>=m_minimum.x && vector.x<=m_maximum.x &&
				    vector.y>=m_minimum.y && vector.y<=m_maximum.y && 
				    vector.z>=m_minimum.z && vector.z<=m_maximum.z );
	}		

private:

	/// Calculate nearest power of two plus one value above the given integer (3,5,9,17,33,65,129,257,513,1025,2049 max)

	unsigned int nearestPowerOfTwoPlusOneAbove(unsigned int number)
	{
		int i = 0;
		unsigned int pow = 2;
		while (i<32)
		{
			if (number<=pow+1)
				return pow+1;
			pow<<=1;
			i++;
		}
		return 0;
	}

	/// Load source heightfield data into local heightfield data.
	/// This method automatically handles clipping to source data, so we can expand from non 2^n-1 size images.

	void load( const float source_data[], int source_width, int source_height, 
			    float destination_data[], int destination_width, int destination_height, 
				bool normalized = false, float offset = 0, float scale = 1 )
	{
		for (int y=0; y<destination_height; y++)
		{
			for (int x=0; x<destination_width; x++)
			{
				int sx = x;
				if (sx>=source_width)
					sx = source_width - 1;

				int sy = y;
				if (sy>=source_height)
					sy = source_height - 1;

				const int source_offset = sx + sy*source_width;
				const int destination_offset = x + y*destination_width;

				#ifdef _DEBUG
				if (normalized)
				{
					assert(source_data[source_offset]>=0);
					assert(source_data[source_offset]<=1);
				}
				#endif

				destination_data[destination_offset] = (source_data[source_offset] - offset) * scale;
			}
		}
	}

	// primary data

	Vector m_origin;			    ///< origin point the xy world coordinates of the height sample (0,0)
	Vector m_minimum;			    ///< minimum point of axis aligned bounding box
	Vector m_maximum;			    ///< maximum point of axis aligned bounding box
	float m_scale;			        ///< cell scale in xy
	int m_width;				    ///< width in samples
	int m_height;				    ///< height in samples
    std::vector<float> m_samples;	///< samples array (heights stored in world coordinates)

	// secondary data

	float m_scale_inverse;	        ///< inverse of xy cell scale
	float m_scale_half;				///< half of xy cell scale
	float m_scale_squared;			///< xy cell scale squared
};

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
美女视频一区在线观看| 欧美一区二区久久久| 欧美精品一二三| 亚洲国产精品精华液ab| 婷婷综合五月天| 91视视频在线观看入口直接观看www| 91精品婷婷国产综合久久 | 99精品桃花视频在线观看| 欧美精品久久久久久久久老牛影院 | 91麻豆6部合集magnet| 精品国产一区二区三区忘忧草| 亚洲另类色综合网站| 国产aⅴ综合色| 欧美tickling网站挠脚心| 亚洲动漫第一页| 色综合天天综合色综合av | 日韩欧美一区在线| 亚洲一区二区三区视频在线播放| 成人午夜精品在线| 久久久亚洲精华液精华液精华液| 老司机免费视频一区二区三区| 欧美日韩日日夜夜| 洋洋成人永久网站入口| 在线免费观看视频一区| 中文字幕一区二区三中文字幕| 成人久久久精品乱码一区二区三区 | 久久成人麻豆午夜电影| 91精品国产欧美日韩| 偷拍日韩校园综合在线| 欧美日韩一区国产| 亚洲777理论| 91精品国产综合久久精品性色| 香蕉成人啪国产精品视频综合网| 欧洲视频一区二区| 亚洲图片一区二区| 欧美日韩第一区日日骚| 天天做天天摸天天爽国产一区 | 日本中文一区二区三区| 日韩欧美中文字幕一区| 韩国中文字幕2020精品| 国产日韩欧美高清| 99精品桃花视频在线观看| 亚洲欧美激情一区二区| 欧美中文字幕久久| 日本欧美一区二区| 久久丝袜美腿综合| 成人动漫一区二区在线| 亚洲精选在线视频| 欧美日本国产视频| 精品一区二区三区在线视频| 久久久久国产一区二区三区四区| youjizz国产精品| 一区二区三区在线视频观看 | 91黄色免费网站| 五月天国产精品| 精品少妇一区二区三区免费观看| 国产河南妇女毛片精品久久久| 国产精品卡一卡二| 欧美日本在线观看| 国产精品一区久久久久| 亚洲少妇30p| 91精品国产色综合久久不卡电影 | 成人18视频在线播放| 亚洲国产乱码最新视频| 久久综合久久99| 91在线视频观看| 九九**精品视频免费播放| 国产精品久久久久久久久免费樱桃| 99视频在线观看一区三区| 亚洲成a天堂v人片| 中文字幕国产一区二区| 欧美高清性hdvideosex| 夫妻av一区二区| 婷婷开心久久网| 欧美国产一区二区| 欧美片在线播放| 粉嫩av一区二区三区粉嫩| 日韩av网站免费在线| 国产精品亲子乱子伦xxxx裸| 制服丝袜激情欧洲亚洲| 91女人视频在线观看| 国内久久精品视频| 亚洲成人7777| 日韩伦理电影网| 2021国产精品久久精品| 欧美视频日韩视频在线观看| 成人一区二区在线观看| 久久99蜜桃精品| 天天色天天操综合| 一区二区久久久久| 日韩一区日韩二区| 国产欧美精品一区aⅴ影院| 日韩美一区二区三区| 欧美老女人在线| 日本高清不卡aⅴ免费网站| 成人一区二区三区| 国产主播一区二区| 美女高潮久久久| 日日摸夜夜添夜夜添亚洲女人| 亚洲日本护士毛茸茸| 国产精品私人影院| 国产色爱av资源综合区| 精品国产1区二区| 精品久久久久久久久久久院品网| 欧美精品亚洲一区二区在线播放| 欧美色图12p| 欧美色图片你懂的| 欧美日韩免费视频| 欧美午夜电影在线播放| 欧洲精品中文字幕| 91国在线观看| 欧美色视频在线观看| 欧美三级电影在线看| 精品视频全国免费看| 欧美人体做爰大胆视频| 91精品国产品国语在线不卡| 欧美一区三区四区| 精品福利在线导航| 国产亚洲一区二区三区四区| 日本一区二区综合亚洲| 最新国产成人在线观看| 国产精品美女久久久久高潮| 一区在线中文字幕| 亚洲精品高清视频在线观看| 亚洲国产精品久久人人爱| 日韩一区欧美二区| 精品一区二区三区日韩| 麻豆freexxxx性91精品| 国产精品中文字幕欧美| 懂色av中文字幕一区二区三区| 99精品视频一区| 欧美日本一道本| 日韩欧美精品在线视频| 国产欧美日韩卡一| 伊人开心综合网| 三级在线观看一区二区| 国产剧情在线观看一区二区| 97se亚洲国产综合自在线观| 欧美日韩的一区二区| 久久久久国产一区二区三区四区 | 久久成人免费网| 成人app在线观看| 欧美日韩国产美女| 久久久精品国产免大香伊| 亚洲六月丁香色婷婷综合久久| 亚洲电影一区二区| 国产一区二区三区不卡在线观看| av网站免费线看精品| 欧美视频第二页| 国产欧美一区二区在线| 亚洲成av人在线观看| 国产麻豆精品视频| 欧美日韩一区不卡| 国产日韩欧美高清在线| 午夜激情久久久| 成人av在线资源网站| 日韩一级成人av| 亚洲日本护士毛茸茸| 国模套图日韩精品一区二区| 色噜噜夜夜夜综合网| 久久久久久久久久久黄色| 亚洲成人精品在线观看| 成人h版在线观看| 日韩亚洲欧美高清| 一区二区三区欧美在线观看| 国产美女一区二区三区| 欧美精品粉嫩高潮一区二区| 亚洲丝袜美腿综合| 国产精品一区二区91| 欧美一级一区二区| 一个色综合网站| www.综合网.com| 久久久久久久久久美女| 日本成人在线看| 欧美日韩在线电影| 亚洲精品伦理在线| 大桥未久av一区二区三区中文| 精品少妇一区二区三区视频免付费| 一区二区三区精品| 成人成人成人在线视频| 久久九九国产精品| 韩国欧美国产一区| 欧美成人午夜电影| 美女网站一区二区| 欧美精品aⅴ在线视频| 亚洲一二三级电影| 在线观看www91| 亚洲精品水蜜桃| 91免费视频观看| 亚洲丝袜另类动漫二区| 成人av免费在线观看| 国产精品久久看| 99久精品国产| 亚洲欧美欧美一区二区三区| 99精品国产视频| 亚洲精品国产精品乱码不99| 色婷婷av一区二区三区之一色屋| 自拍偷在线精品自拍偷无码专区 | 亚洲黄色片在线观看| 日本电影欧美片|